mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Cache redesign part 1, and add support for alternative links
This commit is contained in:
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
@@ -65,6 +65,13 @@ jobs:
|
||||
- name: Run specs (unit tests)
|
||||
run: yarn run test:headless
|
||||
|
||||
# NOTE: Angular CLI only supports code coverage for specs. See https://github.com/angular/angular-cli/issues/6286
|
||||
# Upload coverage reports to Codecov (for Node v12 only)
|
||||
# https://github.com/codecov/codecov-action
|
||||
- name: Upload coverage to Codecov.io
|
||||
uses: codecov/codecov-action@v1
|
||||
if: matrix.node-version == '12.x'
|
||||
|
||||
# Using docker-compose start backend using CI configuration
|
||||
# and load assetstore from a cached copy
|
||||
- name: Start DSpace REST Backend via Docker (for e2e tests)
|
||||
@@ -78,10 +85,3 @@ jobs:
|
||||
|
||||
- name: Shutdown Docker containers
|
||||
run: docker-compose -f ./docker/docker-compose-ci.yml down
|
||||
|
||||
# NOTE: Angular CLI only supports code coverage for specs. See https://github.com/angular/angular-cli/issues/6286
|
||||
# Upload coverage reports to Codecov (for Node v12 only)
|
||||
# https://github.com/codecov/codecov-action
|
||||
- name: Upload coverage to Codecov.io
|
||||
uses: codecov/codecov-action@v1
|
||||
if: matrix.node-version == '12.x'
|
||||
|
@@ -94,6 +94,12 @@
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"sourceMap": {
|
||||
"scripts": false,
|
||||
"styles": false,
|
||||
"hidden": false,
|
||||
"vendor": false
|
||||
},
|
||||
"assets": [
|
||||
"src/assets"
|
||||
],
|
||||
|
@@ -8,7 +8,7 @@ import { BrowserModule, By } from '@angular/platform-browser';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { FindListOptions } from '../../../core/data/request.models';
|
||||
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
|
||||
@@ -44,7 +44,7 @@ describe('EPeopleRegistryComponent', () => {
|
||||
activeEPerson: null,
|
||||
allEpeople: mockEPeople,
|
||||
getEPeople(): Observable<RemoteData<PaginatedList<EPerson>>> {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: this.allEpeople.length, totalElements: this.allEpeople.length, totalPages: 1, currentPage: 1 }), this.allEpeople));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: this.allEpeople.length, totalElements: this.allEpeople.length, totalPages: 1, currentPage: 1 }), this.allEpeople));
|
||||
},
|
||||
getActiveEPerson(): Observable<EPerson> {
|
||||
return observableOf(this.activeEPerson);
|
||||
@@ -54,18 +54,18 @@ describe('EPeopleRegistryComponent', () => {
|
||||
const result = this.allEpeople.find((ePerson: EPerson) => {
|
||||
return ePerson.email === query
|
||||
});
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: [result].length, totalElements: [result].length, totalPages: 1, currentPage: 1 }), [result]));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: [result].length, totalElements: [result].length, totalPages: 1, currentPage: 1 }), [result]));
|
||||
}
|
||||
if (scope === 'metadata') {
|
||||
if (query === '') {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: this.allEpeople.length, totalElements: this.allEpeople.length, totalPages: 1, currentPage: 1 }), this.allEpeople));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: this.allEpeople.length, totalElements: this.allEpeople.length, totalPages: 1, currentPage: 1 }), this.allEpeople));
|
||||
}
|
||||
const result = this.allEpeople.find((ePerson: EPerson) => {
|
||||
return (ePerson.name.includes(query) || ePerson.email.includes(query))
|
||||
});
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: [result].length, totalElements: [result].length, totalPages: 1, currentPage: 1 }), [result]));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: [result].length, totalElements: [result].length, totalPages: 1, currentPage: 1 }), [result]));
|
||||
}
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: this.allEpeople.length, totalElements: this.allEpeople.length, totalPages: 1, currentPage: 1 }), this.allEpeople));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: this.allEpeople.length, totalElements: this.allEpeople.length, totalPages: 1, currentPage: 1 }), this.allEpeople));
|
||||
},
|
||||
deleteEPerson(ePerson: EPerson): Observable<boolean> {
|
||||
this.allEpeople = this.allEpeople.filter((ePerson2: EPerson) => {
|
||||
|
@@ -5,7 +5,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
|
||||
import { Subscription } from 'rxjs/internal/Subscription';
|
||||
import { map, switchMap, take } from 'rxjs/operators';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
|
||||
import { EPerson } from '../../../core/eperson/models/eperson.model';
|
||||
@@ -15,13 +15,16 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio
|
||||
import { EpersonDtoModel } from '../../../core/eperson/models/eperson-dto.model';
|
||||
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||
import { getAllSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||
import { ErrorResponse, RestResponse } from '../../../core/cache/response.models';
|
||||
import {
|
||||
getAllSucceededRemoteDataPayload,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../core/shared/operators';
|
||||
import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
import { filter } from 'rxjs/internal/operators/filter';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-epeople-registry',
|
||||
@@ -159,7 +162,7 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
||||
})
|
||||
);
|
||||
})).pipe(map((dtos: EpersonDtoModel[]) => {
|
||||
return new PaginatedList(epeople.pageInfo, dtos);
|
||||
return buildPaginatedList(epeople.pageInfo, dtos);
|
||||
}))
|
||||
})).subscribe((value) => {
|
||||
this.ePeopleDto$.next(value);
|
||||
@@ -215,13 +218,12 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
||||
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
||||
if (confirm) {
|
||||
if (hasValue(ePerson.id)) {
|
||||
this.epersonService.deleteEPerson(ePerson).pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||
if (restResponse.isSuccessful) {
|
||||
this.epersonService.deleteEPerson(ePerson).pipe(getFirstCompletedRemoteData()).subscribe((restResponse: RemoteData<NoContent>) => {
|
||||
if (restResponse.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: ePerson.name }));
|
||||
this.reset();
|
||||
} else {
|
||||
const errorResponse = restResponse as ErrorResponse;
|
||||
this.notificationsService.error('Error occured when trying to delete EPerson with id: ' + ePerson.id + ' with code: ' + errorResponse.statusCode + ' and message: ' + errorResponse.errorMessage);
|
||||
this.notificationsService.error('Error occured when trying to delete EPerson with id: ' + ePerson.id + ' with code: ' + restResponse.statusCode + ' and message: ' + restResponse.errorMessage);
|
||||
}
|
||||
})
|
||||
}}
|
||||
|
@@ -1,14 +1,13 @@
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { BrowserModule, By } from '@angular/platform-browser';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RestResponse } from '../../../../core/cache/response.models';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { FindListOptions } from '../../../../core/data/request.models';
|
||||
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
|
||||
@@ -46,7 +45,7 @@ describe('EPersonFormComponent', () => {
|
||||
activeEPerson: null,
|
||||
allEpeople: mockEPeople,
|
||||
getEPeople(): Observable<RemoteData<PaginatedList<EPerson>>> {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(null, this.allEpeople));
|
||||
},
|
||||
getActiveEPerson(): Observable<EPerson> {
|
||||
return observableOf(this.activeEPerson);
|
||||
@@ -56,18 +55,18 @@ describe('EPersonFormComponent', () => {
|
||||
const result = this.allEpeople.find((ePerson: EPerson) => {
|
||||
return ePerson.email === query
|
||||
});
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [result]));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [result]));
|
||||
}
|
||||
if (scope === 'metadata') {
|
||||
if (query === '') {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(null, this.allEpeople));
|
||||
}
|
||||
const result = this.allEpeople.find((ePerson: EPerson) => {
|
||||
return (ePerson.name.includes(query) || ePerson.email.includes(query))
|
||||
});
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [result]));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [result]));
|
||||
}
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(null, this.allEpeople));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(null, this.allEpeople));
|
||||
},
|
||||
deleteEPerson(ePerson: EPerson): Observable<boolean> {
|
||||
this.allEpeople = this.allEpeople.filter((ePerson2: EPerson) => {
|
||||
@@ -75,8 +74,9 @@ describe('EPersonFormComponent', () => {
|
||||
});
|
||||
return observableOf(true);
|
||||
},
|
||||
create(ePerson: EPerson) {
|
||||
this.allEpeople = [...this.allEpeople, ePerson]
|
||||
create(ePerson: EPerson): Observable<RemoteData<EPerson>> {
|
||||
this.allEpeople = [...this.allEpeople, ePerson];
|
||||
return createSuccessfulRemoteDataObject$(ePerson);
|
||||
},
|
||||
editEPerson(ePerson: EPerson) {
|
||||
this.activeEPerson = ePerson;
|
||||
@@ -87,18 +87,13 @@ describe('EPersonFormComponent', () => {
|
||||
clearEPersonRequests(): void {
|
||||
// empty
|
||||
},
|
||||
tryToCreate(ePerson: EPerson): Observable<RestResponse> {
|
||||
this.allEpeople = [...this.allEpeople, ePerson]
|
||||
return observableOf(new RestResponse(true, 200, 'Success'));
|
||||
},
|
||||
updateEPerson(ePerson: EPerson): Observable<RestResponse> {
|
||||
updateEPerson(ePerson: EPerson): Observable<RemoteData<EPerson>> {
|
||||
this.allEpeople.forEach((ePersonInList: EPerson, i: number) => {
|
||||
if (ePersonInList.id === ePerson.id) {
|
||||
this.allEpeople[i] = ePerson;
|
||||
}
|
||||
});
|
||||
return observableOf(new RestResponse(true, 200, 'Success'));
|
||||
|
||||
return createSuccessfulRemoteDataObject$(ePerson);
|
||||
}
|
||||
};
|
||||
builderService = getMockFormBuilderService();
|
||||
@@ -299,7 +294,7 @@ describe('EPersonFormComponent', () => {
|
||||
|
||||
it ('should call the epersonFormComponent delete when clicked on the button' , () => {
|
||||
spyOn(component, 'delete').and.stub();
|
||||
spyOn(component.epersonService, 'deleteEPerson').and.returnValue(observableOf(new RestResponse(true, 204, 'No Content')));
|
||||
spyOn(component.epersonService, 'deleteEPerson').and.returnValue(createSuccessfulRemoteDataObject$('No Content', 204));
|
||||
const deleteButton = fixture.debugElement.query(By.css('.delete-button'));
|
||||
deleteButton.triggerEventHandler('click', null);
|
||||
expect(component.delete).toHaveBeenCalled();
|
||||
@@ -307,7 +302,7 @@ describe('EPersonFormComponent', () => {
|
||||
|
||||
it ('should call the epersonService delete when clicked on the button' , () => {
|
||||
// ePersonDataServiceStub.activeEPerson = eperson;
|
||||
spyOn(component.epersonService, 'deleteEPerson').and.returnValue(observableOf(new RestResponse(true, 204, 'No Content')));
|
||||
spyOn(component.epersonService, 'deleteEPerson').and.returnValue(createSuccessfulRemoteDataObject$('No Content', 204));
|
||||
const deleteButton = fixture.debugElement.query(By.css('.delete-button'));
|
||||
expect(deleteButton.nativeElement.disabled).toBe(false);
|
||||
deleteButton.triggerEventHandler('click', null);
|
||||
|
@@ -10,14 +10,17 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { Subscription, combineLatest, of } from 'rxjs';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { switchMap, take } from 'rxjs/operators';
|
||||
import { RestResponse } from '../../../../core/cache/response.models';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
|
||||
import { GroupDataService } from '../../../../core/eperson/group-data.service';
|
||||
import { EPerson } from '../../../../core/eperson/models/eperson.model';
|
||||
import { Group } from '../../../../core/eperson/models/group.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
|
||||
import {
|
||||
getRemoteDataPayload,
|
||||
getFirstSucceededRemoteData,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../../core/shared/operators';
|
||||
import { hasValue } from '../../../../shared/empty.util';
|
||||
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
|
||||
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
|
||||
@@ -28,6 +31,7 @@ import { FeatureID } from '../../../../core/data/feature-authorization/feature-i
|
||||
import { ConfirmationModalComponent } from '../../../../shared/confirmation-modal/confirmation-modal.component';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { RequestService } from '../../../../core/data/request.service';
|
||||
import { NoContent } from '../../../../core/shared/NoContent.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-eperson-form',
|
||||
@@ -314,9 +318,11 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
||||
createNewEPerson(values) {
|
||||
const ePersonToCreate = Object.assign(new EPerson(), values);
|
||||
|
||||
const response = this.epersonService.tryToCreate(ePersonToCreate);
|
||||
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||
if (restResponse.isSuccessful) {
|
||||
const response = this.epersonService.create(ePersonToCreate);
|
||||
response.pipe(
|
||||
getFirstCompletedRemoteData()
|
||||
).subscribe((rd: RemoteData<EPerson>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.created.success', { name: ePersonToCreate.name }));
|
||||
this.submitForm.emit(ePersonToCreate);
|
||||
} else {
|
||||
@@ -354,8 +360,8 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
const response = this.epersonService.updateEPerson(editedEperson);
|
||||
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||
if (restResponse.isSuccessful) {
|
||||
response.pipe(take(1)).subscribe((rd: RemoteData<EPerson>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.edited.success', { name: editedEperson.name }));
|
||||
this.submitForm.emit(editedEperson);
|
||||
} else {
|
||||
@@ -380,7 +386,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
||||
this.subs.push(this.epersonService.searchByScope('email', ePerson.email, {
|
||||
currentPage: 1,
|
||||
elementsPerPage: 0
|
||||
}).pipe(getSucceededRemoteData(), getRemoteDataPayload())
|
||||
}).pipe(getFirstSucceededRemoteData(), getRemoteDataPayload())
|
||||
.subscribe((list: PaginatedList<EPerson>) => {
|
||||
if (list.totalElements > 0) {
|
||||
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.' + notificationSection + '.failure.emailInUse', {
|
||||
@@ -434,12 +440,12 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
||||
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
||||
if (confirm) {
|
||||
if (hasValue(eperson.id)) {
|
||||
this.epersonService.deleteEPerson(eperson).pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||
if (restResponse.isSuccessful) {
|
||||
this.epersonService.deleteEPerson(eperson).pipe(take(1)).subscribe((restResponse: RemoteData<NoContent>) => {
|
||||
if (restResponse.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: eperson.name }));
|
||||
this.reset();
|
||||
} else {
|
||||
this.notificationsService.error('Error occured when trying to delete EPerson with id: ' + eperson.id + ' with code: ' + restResponse.statusCode + ' and message: ' + restResponse.statusText);
|
||||
this.notificationsService.error('Error occured when trying to delete EPerson with id: ' + eperson.id + ' with code: ' + restResponse.statusCode + ' and message: ' + restResponse.errorMessage);
|
||||
}
|
||||
this.cancelForm.emit();
|
||||
})
|
||||
|
@@ -12,11 +12,10 @@ import { of as observableOf } from 'rxjs';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
|
||||
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
|
||||
import { RestResponse } from '../../../../core/cache/response.models';
|
||||
import { DSOChangeAnalyzer } from '../../../../core/data/dso-change-analyzer.service';
|
||||
import { DSpaceObjectDataService } from '../../../../core/data/dspace-object-data.service';
|
||||
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
|
||||
import { GroupDataService } from '../../../../core/eperson/group-data.service';
|
||||
@@ -35,6 +34,7 @@ import { getMockTranslateService } from '../../../../shared/mocks/translate.serv
|
||||
import { TranslateLoaderMock } from '../../../../shared/testing/translate-loader.mock';
|
||||
import { RouterMock } from '../../../../shared/mocks/router.mock';
|
||||
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service.stub';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
|
||||
describe('GroupFormComponent', () => {
|
||||
let component: GroupFormComponent;
|
||||
@@ -71,6 +71,7 @@ describe('GroupFormComponent', () => {
|
||||
groupsDataServiceStub = {
|
||||
allGroups: groups,
|
||||
activeGroup: null,
|
||||
createdGroup: null,
|
||||
getActiveGroup(): Observable<Group> {
|
||||
return observableOf(this.activeGroup);
|
||||
},
|
||||
@@ -80,7 +81,10 @@ describe('GroupFormComponent', () => {
|
||||
editGroup(group: Group) {
|
||||
this.activeGroup = group
|
||||
},
|
||||
updateGroup(group: Group) {
|
||||
clearGroupsRequests() {
|
||||
return null;
|
||||
},
|
||||
patch(group: Group, operations: Operation[]) {
|
||||
return null;
|
||||
},
|
||||
cancelEditGroup(): void {
|
||||
@@ -89,12 +93,21 @@ describe('GroupFormComponent', () => {
|
||||
findById(id: string) {
|
||||
return observableOf({ payload: null, hasSucceeded: true });
|
||||
},
|
||||
tryToCreate(group: Group): Observable<RestResponse> {
|
||||
this.allGroups = [...this.allGroups, group]
|
||||
return observableOf(new RestResponse(true, 200, 'Success'));
|
||||
findByHref(href: string) {
|
||||
return createSuccessfulRemoteDataObject$(this.createdGroup);
|
||||
},
|
||||
create(group: Group): Observable<RemoteData<Group>> {
|
||||
this.allGroups = [...this.allGroups, group];
|
||||
this.createdGroup = Object.assign({}, group, {
|
||||
_links: { self: { href: 'group-selflink' } }
|
||||
});
|
||||
return createSuccessfulRemoteDataObject$(this.createdGroup);
|
||||
},
|
||||
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), []))
|
||||
},
|
||||
getGroupEditPageRouterLinkWithID(id: string) {
|
||||
return `group-edit-page-for-${id}`;
|
||||
}
|
||||
};
|
||||
authorizationService = jasmine.createSpyObj('authorizationService', {
|
||||
@@ -171,7 +184,7 @@ describe('GroupFormComponent', () => {
|
||||
describe('with active Group', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(groupsDataServiceStub, 'getActiveGroup').and.returnValue(observableOf(expected));
|
||||
spyOn(groupsDataServiceStub, 'updateGroup').and.returnValue(observableOf(new RestResponse(true, 200, 'OK')));
|
||||
spyOn(groupsDataServiceStub, 'patch').and.returnValue(createSuccessfulRemoteDataObject$(expected));
|
||||
component.groupName.value = 'newGroupName';
|
||||
component.onSubmit();
|
||||
fixture.detectChanges();
|
||||
|
@@ -9,15 +9,20 @@ import {
|
||||
DynamicTextAreaModel
|
||||
} from '@ng-dynamic-forms/core';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { ObservedValueOf, combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs';
|
||||
import {
|
||||
ObservedValueOf,
|
||||
combineLatest as observableCombineLatest,
|
||||
Observable,
|
||||
of as observableOf,
|
||||
Subscription
|
||||
} from 'rxjs';
|
||||
import { catchError, map, switchMap, take } from 'rxjs/operators';
|
||||
import { getCollectionEditRolesRoute } from '../../../../+collection-page/collection-page-routing-paths';
|
||||
import { getCommunityEditRolesRoute } from '../../../../+community-page/community-page-routing-paths';
|
||||
import { RestResponse } from '../../../../core/cache/response.models';
|
||||
import { DSpaceObjectDataService } from '../../../../core/data/dspace-object-data.service';
|
||||
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
|
||||
import { FeatureID } from '../../../../core/data/feature-authorization/feature-id';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { RequestService } from '../../../../core/data/request.service';
|
||||
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
|
||||
@@ -26,13 +31,19 @@ import { Group } from '../../../../core/eperson/models/group.model';
|
||||
import { Collection } from '../../../../core/shared/collection.model';
|
||||
import { Community } from '../../../../core/shared/community.model';
|
||||
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
|
||||
import {
|
||||
getRemoteDataPayload,
|
||||
getFirstSucceededRemoteData,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../../core/shared/operators';
|
||||
import { AlertType } from '../../../../shared/alert/aletr-type';
|
||||
import { ConfirmationModalComponent } from '../../../../shared/confirmation-modal/confirmation-modal.component';
|
||||
import { hasValue, isNotEmpty } from '../../../../shared/empty.util';
|
||||
import { hasValue, isNotEmpty, hasValueOperator } from '../../../../shared/empty.util';
|
||||
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
|
||||
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
|
||||
import { followLink } from '../../../../shared/utils/follow-link-config.model';
|
||||
import { NoContent } from '../../../../core/shared/NoContent.model';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-group-form',
|
||||
@@ -135,6 +146,7 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
||||
this.setActiveGroup(params.groupId)
|
||||
}));
|
||||
this.canEdit$ = this.groupDataService.getActiveGroup().pipe(
|
||||
hasValueOperator(),
|
||||
switchMap((group: Group) => {
|
||||
return observableCombineLatest(
|
||||
this.authorizationService.isAuthorized(FeatureID.CanDelete, hasValue(group) ? group.self : undefined),
|
||||
@@ -231,17 +243,17 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
createNewGroup(values) {
|
||||
const groupToCreate = Object.assign(new Group(), values);
|
||||
const response = this.groupDataService.tryToCreate(groupToCreate);
|
||||
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||
if (restResponse.isSuccessful) {
|
||||
this.groupDataService.create(groupToCreate).pipe(
|
||||
getFirstCompletedRemoteData()
|
||||
).subscribe((rd: RemoteData<Group>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.created.success', { name: groupToCreate.name }));
|
||||
this.submitForm.emit(groupToCreate);
|
||||
const resp: any = restResponse;
|
||||
if (isNotEmpty(resp.resourceSelfLinks)) {
|
||||
const groupSelfLink = resp.resourceSelfLinks[0];
|
||||
if (isNotEmpty(rd.payload)) {
|
||||
const groupSelfLink = rd.payload._links.self.href;
|
||||
this.setActiveGroupWithLink(groupSelfLink);
|
||||
this.groupDataService.clearGroupsRequests();
|
||||
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLinkWithID(this.groupDataService.getUUIDFromString(groupSelfLink)));
|
||||
this.router.navigateByUrl(this.groupDataService.getGroupEditPageRouterLinkWithID(rd.payload.uuid));
|
||||
}
|
||||
} else {
|
||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.created.failure', { name: groupToCreate.name }));
|
||||
@@ -262,7 +274,7 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
||||
this.subs.push(this.groupDataService.searchGroups(group.name, {
|
||||
currentPage: 1,
|
||||
elementsPerPage: 0
|
||||
}).pipe(getSucceededRemoteData(), getRemoteDataPayload())
|
||||
}).pipe(getFirstSucceededRemoteData(), getRemoteDataPayload())
|
||||
.subscribe((list: PaginatedList<Group>) => {
|
||||
if (list.totalElements > 0) {
|
||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.' + notificationSection + '.failure.groupNameInUse', {
|
||||
@@ -277,25 +289,32 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
||||
* @param group Group to edit and old values contained within
|
||||
*/
|
||||
editGroup(group: Group) {
|
||||
const editedGroup = Object.assign(new Group(), {
|
||||
id: group.id,
|
||||
metadata: {
|
||||
'dc.description': [
|
||||
{
|
||||
value: (hasValue(this.groupDescription.value) ? this.groupDescription.value : group.firstMetadataValue('dc.description'))
|
||||
let operations: Operation[] = []
|
||||
|
||||
if (hasValue(this.groupDescription.value)) {
|
||||
operations = [...operations, {
|
||||
op: 'replace',
|
||||
path: '/metadata/dc.description/0/value',
|
||||
value: this.groupDescription.value
|
||||
}];
|
||||
}
|
||||
],
|
||||
},
|
||||
name: (hasValue(this.groupName.value) ? this.groupName.value : group.name),
|
||||
_links: group._links,
|
||||
});
|
||||
const response = this.groupDataService.updateGroup(editedGroup);
|
||||
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||
if (restResponse.isSuccessful) {
|
||||
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.edited.success', { name: editedGroup.name }));
|
||||
this.submitForm.emit(editedGroup);
|
||||
|
||||
if (hasValue(this.groupName.value)) {
|
||||
operations = [...operations, {
|
||||
op: 'replace',
|
||||
path: '/name',
|
||||
value: this.groupName.value
|
||||
}];
|
||||
}
|
||||
|
||||
this.groupDataService.patch(group, operations).pipe(
|
||||
getFirstCompletedRemoteData()
|
||||
).subscribe((rd: RemoteData<Group>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.edited.success', { name: rd.payload.name }));
|
||||
this.submitForm.emit(rd.payload);
|
||||
} else {
|
||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.edited.failure', { name: editedGroup.name }));
|
||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.edited.failure', { name: group.name }));
|
||||
this.cancelForm.emit();
|
||||
}
|
||||
});
|
||||
@@ -309,7 +328,7 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
||||
this.groupDataService.cancelEditGroup();
|
||||
this.groupDataService.findById(groupId)
|
||||
.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload())
|
||||
.subscribe((group: Group) => {
|
||||
this.groupDataService.editGroup(group);
|
||||
@@ -324,9 +343,9 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
||||
this.groupDataService.getActiveGroup().pipe(take(1)).subscribe((activeGroup: Group) => {
|
||||
if (activeGroup === null) {
|
||||
this.groupDataService.cancelEditGroup();
|
||||
this.groupDataService.findByHref(groupSelfLink, followLink('subgroups'), followLink('epersons'), followLink('object'))
|
||||
this.groupDataService.findByHref(groupSelfLink, false, followLink('subgroups'), followLink('epersons'), followLink('object'))
|
||||
.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload())
|
||||
.subscribe((group: Group) => {
|
||||
this.groupDataService.editGroup(group);
|
||||
@@ -350,15 +369,15 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
||||
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
||||
if (confirm) {
|
||||
if (hasValue(group.id)) {
|
||||
this.groupDataService.deleteGroup(group).pipe(take(1))
|
||||
.subscribe(([success, optionalErrorMessage]: [boolean, string]) => {
|
||||
if (success) {
|
||||
this.groupDataService.delete(group.id).pipe(getFirstCompletedRemoteData())
|
||||
.subscribe((rd: RemoteData<NoContent>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.deleted.success', { name: group.name }));
|
||||
this.reset();
|
||||
} else {
|
||||
this.notificationsService.error(
|
||||
this.translateService.get(this.messagePrefix + '.notification.deleted.failure.title', { name: group.name }),
|
||||
this.translateService.get(this.messagePrefix + '.notification.deleted.failure.content', { cause: optionalErrorMessage }));
|
||||
this.translateService.get(this.messagePrefix + '.notification.deleted.failure.content', { cause: rd.errorMessage }));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ds-pagination *ngIf="(ePeopleSearch | async)?.payload.totalElements > 0"
|
||||
<ds-pagination *ngIf="(ePeopleSearch | async)?.payload?.totalElements > 0"
|
||||
[paginationOptions]="configSearch"
|
||||
[pageInfoState]="(ePeopleSearch | async)?.payload"
|
||||
[collectionSize]="(ePeopleSearch | async)?.payload?.totalElements"
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
</ds-pagination>
|
||||
|
||||
<div *ngIf="(ePeopleSearch | async)?.payload.totalElements == 0 && searchDone"
|
||||
<div *ngIf="(ePeopleSearch | async)?.payload?.totalElements == 0 && searchDone"
|
||||
class="alert alert-info w-100 mb-2"
|
||||
role="alert">
|
||||
{{messagePrefix + '.no-items' | translate}}
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
<h4>{{messagePrefix + '.headMembers' | translate}}</h4>
|
||||
|
||||
<ds-pagination *ngIf="(ePeopleMembersOfGroup | async)?.payload.totalElements > 0"
|
||||
<ds-pagination *ngIf="(ePeopleMembersOfGroup | async)?.payload?.totalElements > 0"
|
||||
[paginationOptions]="config"
|
||||
[pageInfoState]="(ePeopleMembersOfGroup | async)?.payload"
|
||||
[collectionSize]="(ePeopleMembersOfGroup | async)?.payload?.totalElements"
|
||||
@@ -116,7 +116,7 @@
|
||||
|
||||
</ds-pagination>
|
||||
|
||||
<div *ngIf="(ePeopleMembersOfGroup | async)?.payload.totalElements == 0" class="alert alert-info w-100 mb-2"
|
||||
<div *ngIf="(ePeopleMembersOfGroup | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2"
|
||||
role="alert">
|
||||
{{messagePrefix + '.no-members-yet' | translate}}
|
||||
</div>
|
||||
|
@@ -1,6 +1,14 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, fakeAsync, flush, inject, TestBed, tick } from '@angular/core/testing';
|
||||
import {
|
||||
async,
|
||||
ComponentFixture,
|
||||
fakeAsync,
|
||||
flush,
|
||||
inject,
|
||||
TestBed,
|
||||
tick
|
||||
} from '@angular/core/testing';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { BrowserModule, By } from '@angular/platform-browser';
|
||||
import { Router } from '@angular/router';
|
||||
@@ -8,7 +16,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RestResponse } from '../../../../../core/cache/response.models';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../../core/data/remote-data';
|
||||
import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service';
|
||||
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
|
||||
@@ -52,13 +60,13 @@ describe('MembersListComponent', () => {
|
||||
epersonMembers: epersonMembers,
|
||||
subgroupMembers: subgroupMembers,
|
||||
findAllByHref(href: string): Observable<RemoteData<PaginatedList<EPerson>>> {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList<EPerson>(new PageInfo(), groupsDataServiceStub.getEPersonMembers()))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList<EPerson>(new PageInfo(), groupsDataServiceStub.getEPersonMembers()))
|
||||
},
|
||||
searchByScope(scope: string, query: string): Observable<RemoteData<PaginatedList<EPerson>>> {
|
||||
if (query === '') {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), allEPersons))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), allEPersons))
|
||||
}
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), []))
|
||||
},
|
||||
clearEPersonRequests() {
|
||||
// empty
|
||||
@@ -83,9 +91,9 @@ describe('MembersListComponent', () => {
|
||||
},
|
||||
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
|
||||
if (query === '') {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), this.allGroups))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), this.allGroups))
|
||||
}
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), []))
|
||||
},
|
||||
addMemberToGroup(parentGroup, eperson: EPerson): Observable<RestResponse> {
|
||||
this.epersonMembers = [...this.epersonMembers, eperson];
|
||||
|
@@ -4,14 +4,17 @@ import { Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable, of as observableOf, Subscription } from 'rxjs';
|
||||
import { map, mergeMap, take } from 'rxjs/operators';
|
||||
import { RestResponse } from '../../../../../core/cache/response.models';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../../core/data/remote-data';
|
||||
import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service';
|
||||
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
|
||||
import { EPerson } from '../../../../../core/eperson/models/eperson.model';
|
||||
import { Group } from '../../../../../core/eperson/models/group.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../../core/shared/operators';
|
||||
import {
|
||||
getRemoteDataPayload,
|
||||
getFirstSucceededRemoteData,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../../../core/shared/operators';
|
||||
import { hasValue } from '../../../../../shared/empty.util';
|
||||
import { NotificationsService } from '../../../../../shared/notifications/notifications.service';
|
||||
import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model';
|
||||
@@ -160,7 +163,7 @@ export class MembersListComponent implements OnInit, OnDestroy {
|
||||
elementsPerPage: Number.MAX_SAFE_INTEGER
|
||||
})
|
||||
.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
map((listEPeopleInGroup: PaginatedList<EPerson>) => listEPeopleInGroup.page.filter((ePersonInList: EPerson) => ePersonInList.id === possibleMember.id)),
|
||||
map((epeople: EPerson[]) => epeople.length > 0))
|
||||
@@ -225,9 +228,9 @@ export class MembersListComponent implements OnInit, OnDestroy {
|
||||
* @param nameObject Object request was about
|
||||
* @param activeGroup Group currently being edited
|
||||
*/
|
||||
showNotifications(messageSuffix: string, response: Observable<RestResponse>, nameObject: string, activeGroup: Group) {
|
||||
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||
if (restResponse.isSuccessful) {
|
||||
showNotifications(messageSuffix: string, response: Observable<RemoteData<any>>, nameObject: string, activeGroup: Group) {
|
||||
response.pipe(getFirstCompletedRemoteData()).subscribe((rd: RemoteData<any>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.success.' + messageSuffix, { name: nameObject }));
|
||||
} else {
|
||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.' + messageSuffix, { name: nameObject }));
|
||||
|
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ds-pagination *ngIf="(groupsSearch | async)?.payload.totalElements > 0"
|
||||
<ds-pagination *ngIf="(groupsSearch | async)?.payload?.totalElements > 0"
|
||||
[paginationOptions]="configSearch"
|
||||
[pageInfoState]="(groupsSearch | async)?.payload"
|
||||
[collectionSize]="(groupsSearch | async)?.payload?.totalElements"
|
||||
@@ -65,14 +65,14 @@
|
||||
</div>
|
||||
</ds-pagination>
|
||||
|
||||
<div *ngIf="(groupsSearch | async)?.payload.totalElements == 0 && searchDone" class="alert alert-info w-100 mb-2"
|
||||
<div *ngIf="(groupsSearch | async)?.payload?.totalElements == 0 && searchDone" class="alert alert-info w-100 mb-2"
|
||||
role="alert">
|
||||
{{messagePrefix + '.no-items' | translate}}
|
||||
</div>
|
||||
|
||||
<h4>{{messagePrefix + '.headSubgroups' | translate}}</h4>
|
||||
|
||||
<ds-pagination *ngIf="(subgroupsOfGroup | async)?.payload.totalElements > 0"
|
||||
<ds-pagination *ngIf="(subgroupsOfGroup | async)?.payload?.totalElements > 0"
|
||||
[paginationOptions]="config"
|
||||
[pageInfoState]="(subgroupsOfGroup | async)?.payload"
|
||||
[collectionSize]="(subgroupsOfGroup | async)?.payload?.totalElements"
|
||||
@@ -109,7 +109,7 @@
|
||||
</div>
|
||||
</ds-pagination>
|
||||
|
||||
<div *ngIf="(subgroupsOfGroup | async)?.payload.totalElements == 0" class="alert alert-info w-100 mb-2"
|
||||
<div *ngIf="(subgroupsOfGroup | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2"
|
||||
role="alert">
|
||||
{{messagePrefix + '.no-subgroups-yet' | translate}}
|
||||
</div>
|
||||
|
@@ -8,7 +8,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RestResponse } from '../../../../../core/cache/response.models';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../../core/data/remote-data';
|
||||
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
|
||||
import { Group } from '../../../../../core/eperson/models/group.model';
|
||||
@@ -52,16 +52,16 @@ describe('SubgroupsListComponent', () => {
|
||||
return this.activeGroup;
|
||||
},
|
||||
findAllByHref(href: string): Observable<RemoteData<PaginatedList<Group>>> {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList<Group>(new PageInfo(), this.subgroups))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList<Group>(new PageInfo(), this.subgroups))
|
||||
},
|
||||
getGroupEditPageRouterLink(group: Group): string {
|
||||
return '/admin/access-control/groups/' + group.id;
|
||||
},
|
||||
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
|
||||
if (query === '') {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), allGroups))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), allGroups))
|
||||
}
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), []))
|
||||
},
|
||||
addSubGroupToGroup(parentGroup, subgroup: Group): Observable<RestResponse> {
|
||||
this.subgroups = [...this.subgroups, subgroup];
|
||||
|
@@ -4,12 +4,15 @@ import { Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable, of as observableOf, Subscription } from 'rxjs';
|
||||
import { map, mergeMap, take } from 'rxjs/operators';
|
||||
import { RestResponse } from '../../../../../core/cache/response.models';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../../core/data/remote-data';
|
||||
import { GroupDataService } from '../../../../../core/eperson/group-data.service';
|
||||
import { Group } from '../../../../../core/eperson/models/group.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../../core/shared/operators';
|
||||
import {
|
||||
getRemoteDataPayload,
|
||||
getFirstSucceededRemoteData,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../../../core/shared/operators';
|
||||
import { hasValue } from '../../../../../shared/empty.util';
|
||||
import { NotificationsService } from '../../../../../shared/notifications/notifications.service';
|
||||
import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model';
|
||||
@@ -125,7 +128,7 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
|
||||
elementsPerPage: Number.MAX_SAFE_INTEGER
|
||||
})
|
||||
.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
map((listTotalGroups: PaginatedList<Group>) => listTotalGroups.page.filter((groupInList: Group) => groupInList.id === possibleSubgroup.id)),
|
||||
map((groups: Group[]) => groups.length > 0))
|
||||
@@ -231,9 +234,9 @@ export class SubgroupsListComponent implements OnInit, OnDestroy {
|
||||
* @param nameObject Object request was about
|
||||
* @param activeGroup Group currently being edited
|
||||
*/
|
||||
showNotifications(messageSuffix: string, response: Observable<RestResponse>, nameObject: string, activeGroup: Group) {
|
||||
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||
if (restResponse.isSuccessful) {
|
||||
showNotifications(messageSuffix: string, response: Observable<RemoteData<Group>>, nameObject: string, activeGroup: Group) {
|
||||
response.pipe(getFirstCompletedRemoteData()).subscribe((rd: RemoteData<Group>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.success.' + messageSuffix, { name: nameObject }));
|
||||
} else {
|
||||
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.failure.' + messageSuffix, { name: nameObject }));
|
||||
|
@@ -9,7 +9,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { DSpaceObjectDataService } from '../../../core/data/dspace-object-data.service';
|
||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
|
||||
@@ -47,11 +47,11 @@ describe('GroupRegistryComponent', () => {
|
||||
findAllByHref(href: string): Observable<RemoteData<PaginatedList<EPerson>>> {
|
||||
switch (href) {
|
||||
case 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups/testgroupid2/epersons':
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 0, totalPages: 0, currentPage: 1 }), []));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 0, totalPages: 0, currentPage: 1 }), []));
|
||||
case 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups/testgroupid/epersons':
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 1, totalPages: 1, currentPage: 1 }), [EPersonMock]));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 1, totalPages: 1, currentPage: 1 }), [EPersonMock]));
|
||||
default:
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 0, totalPages: 0, currentPage: 1 }), []));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 0, totalPages: 0, currentPage: 1 }), []));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -60,11 +60,11 @@ describe('GroupRegistryComponent', () => {
|
||||
findAllByHref(href: string): Observable<RemoteData<PaginatedList<Group>>> {
|
||||
switch (href) {
|
||||
case 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups/testgroupid2/groups':
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 0, totalPages: 0, currentPage: 1 }), []));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 0, totalPages: 0, currentPage: 1 }), []));
|
||||
case 'https://dspace.4science.it/dspace-spring-rest/api/eperson/groups/testgroupid/groups':
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 1, totalPages: 1, currentPage: 1 }), [GroupMock2]));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 1, totalPages: 1, currentPage: 1 }), [GroupMock2]));
|
||||
default:
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 0, totalPages: 0, currentPage: 1 }), []));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: 1, totalElements: 0, totalPages: 0, currentPage: 1 }), []));
|
||||
}
|
||||
},
|
||||
getGroupEditPageRouterLink(group: Group): string {
|
||||
@@ -75,12 +75,12 @@ describe('GroupRegistryComponent', () => {
|
||||
},
|
||||
searchGroups(query: string): Observable<RemoteData<PaginatedList<Group>>> {
|
||||
if (query === '') {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: this.allGroups.length, totalElements: this.allGroups.length, totalPages: 1, currentPage: 1 }), this.allGroups));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: this.allGroups.length, totalElements: this.allGroups.length, totalPages: 1, currentPage: 1 }), this.allGroups));
|
||||
}
|
||||
const result = this.allGroups.find((group: Group) => {
|
||||
return (group.id.includes(query))
|
||||
});
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo({ elementsPerPage: [result].length, totalElements: [result].length, totalPages: 1, currentPage: 1 }), [result]));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo({ elementsPerPage: [result].length, totalElements: [result].length, totalPages: 1, currentPage: 1 }), [result]));
|
||||
}
|
||||
};
|
||||
dsoDataServiceStub = {
|
||||
|
@@ -2,14 +2,20 @@ 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 {
|
||||
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 { 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';
|
||||
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
|
||||
@@ -19,11 +25,15 @@ import { GroupDtoModel } from '../../../core/eperson/models/group-dto.model';
|
||||
import { Group } from '../../../core/eperson/models/group.model';
|
||||
import { RouteService } from '../../../core/services/route.service';
|
||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||
import { getAllSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||
import {
|
||||
getAllSucceededRemoteDataPayload,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../core/shared/operators';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-groups-registry',
|
||||
@@ -115,7 +125,8 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
|
||||
this.subs.push(this.groupService.searchGroups(this.currentSearchQuery.trim(), {
|
||||
currentPage: this.config.currentPage,
|
||||
elementsPerPage: this.config.pageSize
|
||||
}).subscribe((groupsRD: RemoteData<PaginatedList<Group>>) => {
|
||||
}).pipe(getFirstCompletedRemoteData())
|
||||
.subscribe((groupsRD: RemoteData<PaginatedList<Group>>) => {
|
||||
this.groups$.next(groupsRD);
|
||||
this.pageInfoState$.next(groupsRD.payload.pageInfo);
|
||||
}
|
||||
@@ -136,7 +147,7 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
)
|
||||
})).pipe(map((dtos: GroupDtoModel[]) => {
|
||||
return new PaginatedList(groups.pageInfo, dtos);
|
||||
return buildPaginatedList(groups.pageInfo, dtos);
|
||||
}))
|
||||
})).subscribe((value: PaginatedList<GroupDtoModel>) => {
|
||||
this.groupsDto$.next(value);
|
||||
@@ -149,15 +160,15 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
deleteGroup(group: Group) {
|
||||
if (hasValue(group.id)) {
|
||||
this.groupService.deleteGroup(group).pipe(take(1))
|
||||
.subscribe(([success, optionalErrorMessage]: [boolean, string]) => {
|
||||
if (success) {
|
||||
this.groupService.delete(group.id).pipe(getFirstCompletedRemoteData())
|
||||
.subscribe((rd: RemoteData<NoContent>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get(this.messagePrefix + 'notification.deleted.success', { name: group.name }));
|
||||
this.reset();
|
||||
} else {
|
||||
this.notificationsService.error(
|
||||
this.translateService.get(this.messagePrefix + 'notification.deleted.failure.title', { name: group.name }),
|
||||
this.translateService.get(this.messagePrefix + 'notification.deleted.failure.content', { cause: optionalErrorMessage }));
|
||||
this.translateService.get(this.messagePrefix + 'notification.deleted.failure.content', { cause: rd.errorMessage }));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@ import { NotificationsServiceStub } from '../../shared/testing/notifications-ser
|
||||
import { FileValueAccessorDirective } from '../../shared/utils/file-value-accessor.directive';
|
||||
import { FileValidator } from '../../shared/utils/require-file.validator';
|
||||
import { MetadataImportPageComponent } from './metadata-import-page.component';
|
||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
|
||||
describe('MetadataImportPageComponent', () => {
|
||||
let comp: MetadataImportPageComponent;
|
||||
@@ -36,13 +37,7 @@ describe('MetadataImportPageComponent', () => {
|
||||
notificationService = new NotificationsServiceStub();
|
||||
scriptService = jasmine.createSpyObj('scriptService',
|
||||
{
|
||||
invoke: observableOf({
|
||||
response:
|
||||
{
|
||||
isSuccessful: true,
|
||||
resourceSelfLinks: ['https://localhost:8080/api/core/processes/45']
|
||||
}
|
||||
})
|
||||
invoke: createSuccessfulRemoteDataObject$({ processId: '45' })
|
||||
}
|
||||
);
|
||||
user = Object.assign(new EPerson(), {
|
||||
@@ -133,12 +128,7 @@ describe('MetadataImportPageComponent', () => {
|
||||
describe('if proceed is pressed; but script invoke fails', () => {
|
||||
beforeEach(fakeAsync(() => {
|
||||
jasmine.getEnv().allowRespy(true);
|
||||
spyOn(scriptService, 'invoke').and.returnValue(observableOf({
|
||||
response:
|
||||
{
|
||||
isSuccessful: false,
|
||||
}
|
||||
}));
|
||||
spyOn(scriptService, 'invoke').and.returnValue(createFailedRemoteDataObject$('Error', 500));
|
||||
const proceed = fixture.debugElement.query(By.css('#proceedButton')).nativeElement;
|
||||
proceed.click();
|
||||
fixture.detectChanges();
|
||||
|
@@ -3,14 +3,20 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { map, switchMap, take } from 'rxjs/operators';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { AuthService } from '../../core/auth/auth.service';
|
||||
import { METADATA_IMPORT_SCRIPT_NAME, ScriptDataService } from '../../core/data/processes/script-data.service';
|
||||
import { RequestEntry } from '../../core/data/request.reducer';
|
||||
import {
|
||||
METADATA_IMPORT_SCRIPT_NAME,
|
||||
ScriptDataService
|
||||
} from '../../core/data/processes/script-data.service';
|
||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||
import { ProcessParameter } from '../../process-page/processes/process-parameter.model';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Process } from '../../process-page/processes/process.model';
|
||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
||||
import { getProcessDetailRoute } from '../../process-page/process-page-routing.paths';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-import-page',
|
||||
@@ -79,28 +85,23 @@ export class MetadataImportPageComponent implements OnInit {
|
||||
Object.assign(new ProcessParameter(), { name: '-f', value: this.fileObject.name }),
|
||||
];
|
||||
return this.scriptDataService.invoke(METADATA_IMPORT_SCRIPT_NAME, parameterValues, [this.fileObject])
|
||||
.pipe(
|
||||
take(1),
|
||||
map((requestEntry: RequestEntry) => {
|
||||
if (requestEntry.response.isSuccessful) {
|
||||
}
|
||||
}),
|
||||
getFirstCompletedRemoteData(),
|
||||
).subscribe((rd: RemoteData<Process>) => {
|
||||
if (rd.hasSucceeded) {
|
||||
const title = this.translate.get('process.new.notification.success.title');
|
||||
const content = this.translate.get('process.new.notification.success.content');
|
||||
this.notificationsService.success(title, content);
|
||||
const response: any = requestEntry.response;
|
||||
if (isNotEmpty(response.resourceSelfLinks)) {
|
||||
const processNumber = response.resourceSelfLinks[0].split('/').pop();
|
||||
this.router.navigateByUrl('/processes/' + processNumber);
|
||||
if (isNotEmpty(rd.payload)) {
|
||||
this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId));
|
||||
}
|
||||
} else {
|
||||
const title = this.translate.get('process.new.notification.error.title');
|
||||
const content = this.translate.get('process.new.notification.error.content');
|
||||
this.notificationsService.error(title, content);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}),
|
||||
take(1)
|
||||
).subscribe();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@ import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RestResponse } from '../../../../core/cache/response.models';
|
||||
import { BitstreamFormatDataService } from '../../../../core/data/bitstream-format-data.service';
|
||||
import { BitstreamFormatSupportLevel } from '../../../../core/shared/bitstream-format-support-level';
|
||||
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
|
||||
@@ -14,6 +13,7 @@ import { NotificationsService } from '../../../../shared/notifications/notificat
|
||||
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service.stub';
|
||||
import { RouterStub } from '../../../../shared/testing/router.stub';
|
||||
import { AddBitstreamFormatComponent } from './add-bitstream-format.component';
|
||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
|
||||
|
||||
describe('AddBitstreamFormatComponent', () => {
|
||||
let comp: AddBitstreamFormatComponent;
|
||||
@@ -37,7 +37,7 @@ describe('AddBitstreamFormatComponent', () => {
|
||||
router = new RouterStub();
|
||||
notificationService = new NotificationsServiceStub();
|
||||
bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
|
||||
createBitstreamFormat: observableOf(new RestResponse(true, 200, 'Success')),
|
||||
createBitstreamFormat: createSuccessfulRemoteDataObject$({}),
|
||||
clearBitStreamFormatRequests: observableOf(null)
|
||||
});
|
||||
|
||||
@@ -77,7 +77,7 @@ describe('AddBitstreamFormatComponent', () => {
|
||||
router = new RouterStub();
|
||||
notificationService = new NotificationsServiceStub();
|
||||
bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
|
||||
createBitstreamFormat: observableOf(new RestResponse(false, 400, 'Bad Request')),
|
||||
createBitstreamFormat: createFailedRemoteDataObject$('Error', 500),
|
||||
clearBitStreamFormatRequests: observableOf(null)
|
||||
});
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import { take } from 'rxjs/operators';
|
||||
import { Router } from '@angular/router';
|
||||
import { Component } from '@angular/core';
|
||||
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
|
||||
import { BitstreamFormatDataService } from '../../../../core/data/bitstream-format-data.service';
|
||||
import { RestResponse } from '../../../../core/cache/response.models';
|
||||
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { getBitstreamFormatsModuleRoute } from '../../admin-registries-routing-paths';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
|
||||
|
||||
/**
|
||||
* This component renders the page to create a new bitstream format.
|
||||
@@ -32,9 +32,10 @@ export class AddBitstreamFormatComponent {
|
||||
* @param bitstreamFormat
|
||||
*/
|
||||
createBitstreamFormat(bitstreamFormat: BitstreamFormat) {
|
||||
this.bitstreamFormatDataService.createBitstreamFormat(bitstreamFormat).pipe(take(1)
|
||||
).subscribe((response: RestResponse) => {
|
||||
if (response.isSuccessful) {
|
||||
this.bitstreamFormatDataService.createBitstreamFormat(bitstreamFormat).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
).subscribe((response: RemoteData<BitstreamFormat>) => {
|
||||
if (response.hasSucceeded) {
|
||||
this.notificationService.success(this.translateService.get('admin.registries.bitstream-formats.create.success.head'),
|
||||
this.translateService.get('admin.registries.bitstream-formats.create.success.content'));
|
||||
this.router.navigate([getBitstreamFormatsModuleRoute()]);
|
||||
|
@@ -1,8 +1,6 @@
|
||||
import { BitstreamFormatsComponent } from './bitstream-formats.component';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@@ -19,6 +17,12 @@ import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
|
||||
import { BitstreamFormatSupportLevel } from '../../../core/shared/bitstream-format-support-level';
|
||||
import { cold, getTestScheduler, hot } from 'jasmine-marbles';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import {
|
||||
createNoContentRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
|
||||
describe('BitstreamFormatsComponent', () => {
|
||||
let comp: BitstreamFormatsComponent;
|
||||
@@ -73,7 +77,7 @@ describe('BitstreamFormatsComponent', () => {
|
||||
bitstreamFormat3,
|
||||
bitstreamFormat4
|
||||
];
|
||||
const mockFormatsRD = new RemoteData(false, false, true, undefined, new PaginatedList(null, mockFormatsList));
|
||||
const mockFormatsRD = createSuccessfulRemoteDataObject(createPaginatedList(mockFormatsList));
|
||||
|
||||
const initAsync = () => {
|
||||
notificationsServiceStub = new NotificationsServiceStub();
|
||||
@@ -82,12 +86,12 @@ describe('BitstreamFormatsComponent', () => {
|
||||
|
||||
bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', {
|
||||
findAll: observableOf(mockFormatsRD),
|
||||
find: observableOf(new RemoteData(false, false, true, undefined, mockFormatsList[0])),
|
||||
find: createSuccessfulRemoteDataObject$(mockFormatsList[0]),
|
||||
getSelectedBitstreamFormats: hot('a', {a: mockFormatsList}),
|
||||
selectBitstreamFormat: {},
|
||||
deselectBitstreamFormat: {},
|
||||
deselectAllBitstreamFormats: {},
|
||||
delete: observableOf(true),
|
||||
delete: createSuccessfulRemoteDataObject$({}),
|
||||
clearBitStreamFormatRequests: observableOf('cleared')
|
||||
});
|
||||
|
||||
@@ -204,12 +208,12 @@ describe('BitstreamFormatsComponent', () => {
|
||||
|
||||
bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', {
|
||||
findAll: observableOf(mockFormatsRD),
|
||||
find: observableOf(new RemoteData(false, false, true, undefined, mockFormatsList[0])),
|
||||
find: createSuccessfulRemoteDataObject$(mockFormatsList[0]),
|
||||
getSelectedBitstreamFormats: observableOf(mockFormatsList),
|
||||
selectBitstreamFormat: {},
|
||||
deselectBitstreamFormat: {},
|
||||
deselectAllBitstreamFormats: {},
|
||||
delete: observableOf({ isSuccessful: true }),
|
||||
delete: createNoContentRemoteDataObject$(),
|
||||
clearBitStreamFormatRequests: observableOf('cleared')
|
||||
});
|
||||
|
||||
@@ -250,7 +254,7 @@ describe('BitstreamFormatsComponent', () => {
|
||||
|
||||
bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', {
|
||||
findAll: observableOf(mockFormatsRD),
|
||||
find: observableOf(new RemoteData(false, false, true, undefined, mockFormatsList[0])),
|
||||
find: createSuccessfulRemoteDataObject$(mockFormatsList[0]),
|
||||
getSelectedBitstreamFormats: observableOf(mockFormatsList),
|
||||
selectBitstreamFormat: {},
|
||||
deselectBitstreamFormat: {},
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, zip } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
|
||||
import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service';
|
||||
@@ -11,7 +11,7 @@ import { hasValue } from '../../../shared/empty.util';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
|
||||
/**
|
||||
* This component renders a list of bitstream formats
|
||||
@@ -65,7 +65,7 @@ export class BitstreamFormatsComponent implements OnInit {
|
||||
const tasks$ = [];
|
||||
for (const format of formats) {
|
||||
if (hasValue(format.id)) {
|
||||
tasks$.push(this.bitstreamFormatService.delete(format.id).pipe(map((response: RestResponse) => response.isSuccessful)));
|
||||
tasks$.push(this.bitstreamFormatService.delete(format.id).pipe(map((response: RemoteData<NoContent>) => response.hasSucceeded)));
|
||||
}
|
||||
}
|
||||
zip(...tasks$).subscribe((results: boolean[]) => {
|
||||
|
@@ -1,11 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { find } from 'rxjs/operators';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
|
||||
import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||
|
||||
/**
|
||||
* This class represents a resolver that requests a specific bitstreamFormat before the route is activated
|
||||
@@ -25,7 +24,7 @@ export class BitstreamFormatsResolver implements Resolve<RemoteData<BitstreamFor
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<BitstreamFormat>> {
|
||||
return this.bitstreamFormatDataService.findById(route.params.id)
|
||||
.pipe(
|
||||
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
|
||||
getFirstCompletedRemoteData()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@ import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RestResponse } from '../../../../core/cache/response.models';
|
||||
import { BitstreamFormatDataService } from '../../../../core/data/bitstream-format-data.service';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { BitstreamFormatSupportLevel } from '../../../../core/shared/bitstream-format-support-level';
|
||||
@@ -15,6 +14,11 @@ import { NotificationsService } from '../../../../shared/notifications/notificat
|
||||
import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service.stub';
|
||||
import { RouterStub } from '../../../../shared/testing/router.stub';
|
||||
import { EditBitstreamFormatComponent } from './edit-bitstream-format.component';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../../shared/remote-data.utils';
|
||||
|
||||
describe('EditBitstreamFormatComponent', () => {
|
||||
let comp: EditBitstreamFormatComponent;
|
||||
@@ -32,7 +36,7 @@ describe('EditBitstreamFormatComponent', () => {
|
||||
|
||||
const routeStub = {
|
||||
data: observableOf({
|
||||
bitstreamFormat: new RemoteData(false, false, true, null, bitstreamFormat)
|
||||
bitstreamFormat: createSuccessfulRemoteDataObject(bitstreamFormat)
|
||||
})
|
||||
};
|
||||
|
||||
@@ -44,7 +48,7 @@ describe('EditBitstreamFormatComponent', () => {
|
||||
router = new RouterStub();
|
||||
notificationService = new NotificationsServiceStub();
|
||||
bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
|
||||
updateBitstreamFormat: observableOf(new RestResponse(true, 200, 'Success'))
|
||||
updateBitstreamFormat: createSuccessfulRemoteDataObject$({})
|
||||
});
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
@@ -73,7 +77,8 @@ describe('EditBitstreamFormatComponent', () => {
|
||||
it('should initialise the bitstreamFormat based on the route', () => {
|
||||
|
||||
comp.bitstreamFormatRD$.subscribe((format: RemoteData<BitstreamFormat>) => {
|
||||
expect(format).toEqual(new RemoteData(false, false, true, null, bitstreamFormat));
|
||||
const expected = createSuccessfulRemoteDataObject(bitstreamFormat);
|
||||
expect(format.payload).toEqual(expected.payload);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -94,7 +99,7 @@ describe('EditBitstreamFormatComponent', () => {
|
||||
router = new RouterStub();
|
||||
notificationService = new NotificationsServiceStub();
|
||||
bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
|
||||
updateBitstreamFormat: observableOf(new RestResponse(false, 400, 'Bad Request'))
|
||||
updateBitstreamFormat: createFailedRemoteDataObject$('Error', 500)
|
||||
});
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
@@ -1,14 +1,14 @@
|
||||
import { map, take } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
|
||||
import { BitstreamFormatDataService } from '../../../../core/data/bitstream-format-data.service';
|
||||
import { RestResponse } from '../../../../core/cache/response.models';
|
||||
import { NotificationsService } from '../../../../shared/notifications/notifications.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { getBitstreamFormatsModuleRoute } from '../../admin-registries-routing-paths';
|
||||
import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
|
||||
|
||||
/**
|
||||
* This component renders the edit page of a bitstream format.
|
||||
@@ -46,9 +46,10 @@ export class EditBitstreamFormatComponent implements OnInit {
|
||||
* When failed, an error notification will be shown.
|
||||
*/
|
||||
updateFormat(bitstreamFormat: BitstreamFormat) {
|
||||
this.bitstreamFormatDataService.updateBitstreamFormat(bitstreamFormat).pipe(take(1)
|
||||
).subscribe((response: RestResponse) => {
|
||||
if (response.isSuccessful) {
|
||||
this.bitstreamFormatDataService.updateBitstreamFormat(bitstreamFormat).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
).subscribe((response: RemoteData<BitstreamFormat>) => {
|
||||
if (response.hasSucceeded) {
|
||||
this.notificationService.success(this.translateService.get('admin.registries.bitstream-formats.edit.success.head'),
|
||||
this.translateService.get('admin.registries.bitstream-formats.edit.success.content'));
|
||||
this.router.navigate([getBitstreamFormatsModuleRoute()]);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { MetadataRegistryComponent } from './metadata-registry.component';
|
||||
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@@ -45,7 +45,7 @@ describe('MetadataRegistryComponent', () => {
|
||||
namespace: 'http://dspace.org/mockschema'
|
||||
}
|
||||
];
|
||||
const mockSchemas = createSuccessfulRemoteDataObject$(new PaginatedList(null, mockSchemasList));
|
||||
const mockSchemas = createSuccessfulRemoteDataObject$(buildPaginatedList(null, mockSchemasList));
|
||||
/* tslint:disable:no-empty */
|
||||
const registryServiceStub = {
|
||||
getMetadataSchemas: () => mockSchemas,
|
||||
|
@@ -2,18 +2,19 @@ import { Component } from '@angular/core';
|
||||
import { RegistryService } from '../../../core/registry/registry.service';
|
||||
import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { filter, map, switchMap, take } from 'rxjs/operators';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { zip } from 'rxjs/internal/observable/zip';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { Route, Router } from '@angular/router';
|
||||
import { Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
import { toFindListOptions } from '../../../shared/pagination/pagination.utils';
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-registry',
|
||||
@@ -140,12 +141,12 @@ export class MetadataRegistryComponent {
|
||||
const tasks$ = [];
|
||||
for (const schema of schemas) {
|
||||
if (hasValue(schema.id)) {
|
||||
tasks$.push(this.registryService.deleteMetadataSchema(schema.id));
|
||||
tasks$.push(this.registryService.deleteMetadataSchema(schema.id).pipe(getFirstCompletedRemoteData()));
|
||||
}
|
||||
}
|
||||
zip(...tasks$).subscribe((responses: RestResponse[]) => {
|
||||
const successResponses = responses.filter((response: RestResponse) => response.isSuccessful);
|
||||
const failedResponses = responses.filter((response: RestResponse) => !response.isSuccessful);
|
||||
zip(...tasks$).subscribe((responses: Array<RemoteData<NoContent>>) => {
|
||||
const successResponses = responses.filter((response: RemoteData<NoContent>) => response.hasSucceeded);
|
||||
const failedResponses = responses.filter((response: RemoteData<NoContent>) => response.hasFailed);
|
||||
if (successResponses.length > 0) {
|
||||
this.showNotification(true, successResponses.length);
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { MetadataSchemaComponent } from './metadata-schema.component';
|
||||
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
@@ -100,11 +100,11 @@ describe('MetadataSchemaComponent', () => {
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[1])
|
||||
}
|
||||
];
|
||||
const mockSchemas = createSuccessfulRemoteDataObject$(new PaginatedList(null, mockSchemasList));
|
||||
const mockSchemas = createSuccessfulRemoteDataObject$(buildPaginatedList(null, mockSchemasList));
|
||||
/* tslint:disable:no-empty */
|
||||
const registryServiceStub = {
|
||||
getMetadataSchemas: () => mockSchemas,
|
||||
getMetadataFieldsBySchema: (schema: MetadataSchema) => createSuccessfulRemoteDataObject$(new PaginatedList(null, mockFieldsList.filter((value) => value.id === 3 || value.id === 4))),
|
||||
getMetadataFieldsBySchema: (schema: MetadataSchema) => createSuccessfulRemoteDataObject$(buildPaginatedList(null, mockFieldsList.filter((value) => value.id === 3 || value.id === 4))),
|
||||
getMetadataSchemaByPrefix: (schemaName: string) => createSuccessfulRemoteDataObject$(mockSchemasList.filter((value) => value.prefix === schemaName)[0]),
|
||||
getActiveMetadataField: () => observableOf(undefined),
|
||||
getSelectedMetadataFields: () => observableOf([]),
|
||||
|
@@ -3,21 +3,24 @@ import { RegistryService } from '../../../core/registry/registry.service';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { map, switchMap, take } from 'rxjs/operators';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { zip } from 'rxjs/internal/observable/zip';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||
import {
|
||||
getFirstSucceededRemoteDataPayload,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../core/shared/operators';
|
||||
import { toFindListOptions } from '../../../shared/pagination/pagination.utils';
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
import { combineLatest } from 'rxjs/internal/observable/combineLatest';
|
||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-schema',
|
||||
@@ -92,7 +95,7 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
this.metadataFields$ = combineLatest(this.metadataSchema$, this.needsUpdate$).pipe(
|
||||
switchMap(([schema, update]: [MetadataSchema, boolean]) => {
|
||||
if (update) {
|
||||
return this.registryService.getMetadataFieldsBySchema(schema, toFindListOptions(this.config), followLink('schema'));
|
||||
return this.registryService.getMetadataFieldsBySchema(schema, toFindListOptions(this.config), true, followLink('schema'));
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -168,12 +171,12 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
const tasks$ = [];
|
||||
for (const field of fields) {
|
||||
if (hasValue(field.id)) {
|
||||
tasks$.push(this.registryService.deleteMetadataField(field.id));
|
||||
tasks$.push(this.registryService.deleteMetadataField(field.id).pipe(getFirstCompletedRemoteData()));
|
||||
}
|
||||
}
|
||||
zip(...tasks$).subscribe((responses: RestResponse[]) => {
|
||||
const successResponses = responses.filter((response: RestResponse) => response.isSuccessful);
|
||||
const failedResponses = responses.filter((response: RestResponse) => !response.isSuccessful);
|
||||
zip(...tasks$).subscribe((responses: Array<RemoteData<NoContent>>) => {
|
||||
const successResponses = responses.filter((response: RemoteData<NoContent>) => response.hasSucceeded);
|
||||
const failedResponses = responses.filter((response: RemoteData<NoContent>) => response.hasFailed);
|
||||
if (successResponses.length > 0) {
|
||||
this.showNotification(true, successResponses.length);
|
||||
}
|
||||
|
@@ -2,11 +2,10 @@ import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { find } from 'rxjs/operators';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
import { Bitstream } from '../core/shared/bitstream.model';
|
||||
import { BitstreamDataService } from '../core/data/bitstream-data.service';
|
||||
import {followLink, FollowLinkConfig} from '../shared/utils/follow-link-config.model';
|
||||
import { getFirstCompletedRemoteData } from '../core/shared/operators';
|
||||
|
||||
/**
|
||||
* This class represents a resolver that requests a specific bitstream before the route is activated
|
||||
@@ -24,9 +23,9 @@ export class BitstreamPageResolver implements Resolve<RemoteData<Bitstream>> {
|
||||
* or an error if something went wrong
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Bitstream>> {
|
||||
return this.bitstreamService.findById(route.params.id, ...this.followLinks)
|
||||
return this.bitstreamService.findById(route.params.id, false, ...this.followLinks)
|
||||
.pipe(
|
||||
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
|
||||
getFirstCompletedRemoteData(),
|
||||
);
|
||||
}
|
||||
/**
|
||||
|
@@ -2,7 +2,6 @@ import { EditBitstreamPageComponent } from './edit-bitstream-page.component';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import { DynamicFormControlModel, DynamicFormService } from '@ng-dynamic-forms/core';
|
||||
@@ -17,16 +16,15 @@ import { BitstreamFormat } from '../../core/shared/bitstream-format.model';
|
||||
import { BitstreamFormatSupportLevel } from '../../core/shared/bitstream-format-support-level';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../core/shared/page-info.model';
|
||||
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
|
||||
import { RestResponse } from '../../core/cache/response.models';
|
||||
import { VarDirective } from '../../shared/utils/var.directive';
|
||||
import {
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../shared/remote-data.utils';
|
||||
import {RouterStub} from '../../shared/testing/router.stub';
|
||||
import { getItemEditRoute } from '../../+item-page/item-page-routing-paths';
|
||||
import { createPaginatedList } from '../../shared/testing/utils.test';
|
||||
|
||||
const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
|
||||
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
|
||||
@@ -109,7 +107,7 @@ describe('EditBitstreamPageComponent', () => {
|
||||
}
|
||||
]
|
||||
},
|
||||
format: observableOf(new RemoteData(false, false, true, null, selectedFormat)),
|
||||
format: createSuccessfulRemoteDataObject$(selectedFormat),
|
||||
_links: {
|
||||
self: 'bitstream-selflink'
|
||||
},
|
||||
@@ -120,14 +118,14 @@ describe('EditBitstreamPageComponent', () => {
|
||||
})
|
||||
});
|
||||
bitstreamService = jasmine.createSpyObj('bitstreamService', {
|
||||
findById: observableOf(new RemoteData(false, false, true, null, bitstream)),
|
||||
update: observableOf(new RemoteData(false, false, true, null, bitstream)),
|
||||
updateFormat: observableOf(new RestResponse(true, 200, 'OK')),
|
||||
findById: createSuccessfulRemoteDataObject$(bitstream),
|
||||
update: createSuccessfulRemoteDataObject$(bitstream),
|
||||
updateFormat: createSuccessfulRemoteDataObject$(bitstream),
|
||||
commitUpdates: {},
|
||||
patch: {}
|
||||
});
|
||||
bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', {
|
||||
findAll: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), allFormats)))
|
||||
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(allFormats))
|
||||
});
|
||||
|
||||
const itemPageUrl = `fake-url/some-uuid`;
|
||||
@@ -140,7 +138,7 @@ describe('EditBitstreamPageComponent', () => {
|
||||
providers: [
|
||||
{ provide: NotificationsService, useValue: notificationsService },
|
||||
{ provide: DynamicFormService, useValue: formService },
|
||||
{ provide: ActivatedRoute, useValue: { data: observableOf({ bitstream: new RemoteData(false, false, true, null, bitstream) }), snapshot: { queryParams: {} } } },
|
||||
{ provide: ActivatedRoute, useValue: { data: observableOf({ bitstream: createSuccessfulRemoteDataObject(bitstream) }), snapshot: { queryParams: {} } } },
|
||||
{ provide: BitstreamDataService, useValue: bitstreamService },
|
||||
{ provide: BitstreamFormatDataService, useValue: bitstreamFormatService },
|
||||
{ provide: Router, useValue: routerStub },
|
||||
|
@@ -22,19 +22,19 @@ import {
|
||||
getAllSucceededRemoteDataPayload,
|
||||
getFirstSucceededRemoteDataPayload,
|
||||
getRemoteDataPayload,
|
||||
getSucceededRemoteData
|
||||
getFirstSucceededRemoteData,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../core/shared/operators';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { BitstreamFormatDataService } from '../../core/data/bitstream-format-data.service';
|
||||
import { BitstreamFormat } from '../../core/shared/bitstream-format.model';
|
||||
import { BitstreamFormatSupportLevel } from '../../core/shared/bitstream-format-support-level';
|
||||
import { RestResponse } from '../../core/cache/response.models';
|
||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { Metadata } from '../../core/shared/metadata.utils';
|
||||
import { Location } from '@angular/common';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { getItemEditRoute } from '../../+item-page/item-page-routing-paths';
|
||||
import { Bundle } from '../../core/shared/bundle.model';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
@@ -299,12 +299,12 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
this.bitstreamFormatsRD$ = this.bitstreamFormatService.findAll(this.findAllOptions);
|
||||
|
||||
const bitstream$ = this.bitstreamRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload()
|
||||
);
|
||||
|
||||
const allFormats$ = this.bitstreamFormatsRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload()
|
||||
);
|
||||
|
||||
@@ -438,16 +438,15 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy {
|
||||
|
||||
if (isNewFormat) {
|
||||
bitstream$ = this.bitstreamService.updateFormat(this.bitstream, selectedFormat).pipe(
|
||||
switchMap((formatResponse: RestResponse) => {
|
||||
if (hasValue(formatResponse) && !formatResponse.isSuccessful) {
|
||||
getFirstCompletedRemoteData(),
|
||||
map((formatResponse: RemoteData<Bitstream>) => {
|
||||
if (hasValue(formatResponse) && formatResponse.hasFailed) {
|
||||
this.notificationsService.error(
|
||||
this.translate.instant(this.NOTIFICATIONS_PREFIX + 'error.format.title'),
|
||||
formatResponse.statusText
|
||||
formatResponse.errorMessage
|
||||
);
|
||||
} else {
|
||||
return this.bitstreamService.findById(this.bitstream.id).pipe(
|
||||
getFirstSucceededRemoteDataPayload()
|
||||
);
|
||||
return formatResponse.payload;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectorRef, Component, Inject } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component } from '@angular/core';
|
||||
import {
|
||||
BrowseByMetadataPageComponent,
|
||||
browseParamsToOptions
|
||||
@@ -43,7 +43,7 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
||||
|
||||
ngOnInit(): void {
|
||||
this.startsWithType = StartsWithType.date;
|
||||
this.updatePage(new BrowseEntrySearchOptions(null, this.paginationConfig, this.sortConfig));
|
||||
this.updatePage(new BrowseEntrySearchOptions(this.defaultBrowseId, this.paginationConfig, this.sortConfig));
|
||||
this.subs.push(
|
||||
observableCombineLatest(
|
||||
this.route.params,
|
||||
|
@@ -12,7 +12,7 @@ import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { PageInfo } from '../../core/shared/page-info.model';
|
||||
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
|
||||
import { SortDirection } from '../../core/cache/models/sort-options.model';
|
||||
@@ -157,5 +157,5 @@ describe('BrowseByMetadataPageComponent', () => {
|
||||
});
|
||||
|
||||
export function toRemoteData(objects: any[]): Observable<RemoteData<PaginatedList<any>>> {
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), objects));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), objects));
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import {combineLatest as observableCombineLatest, merge as observableMerge, Observable, Subscription } from 'rxjs';
|
||||
import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
@@ -10,10 +10,9 @@ import { BrowseService } from '../../core/browse/browse.service';
|
||||
import { BrowseEntry } from '../../core/shared/browse-entry.model';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
|
||||
import { getSucceededRemoteData } from '../../core/shared/operators';
|
||||
import { getFirstSucceededRemoteData } from '../../core/shared/operators';
|
||||
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { StartsWithType } from '../../shared/starts-with/starts-with-decorator';
|
||||
import { BrowseByType, rendersBrowseBy } from '../+browse-by-switcher/browse-by-decorator';
|
||||
|
||||
@@ -105,7 +104,7 @@ export class BrowseByMetadataPageComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.updatePage(new BrowseEntrySearchOptions(null, this.paginationConfig, this.sortConfig));
|
||||
this.updatePage(new BrowseEntrySearchOptions(this.defaultBrowseId, this.paginationConfig, this.sortConfig));
|
||||
this.subs.push(
|
||||
observableCombineLatest(
|
||||
this.route.params,
|
||||
@@ -169,7 +168,7 @@ export class BrowseByMetadataPageComponent implements OnInit {
|
||||
updateParent(scope: string) {
|
||||
if (hasValue(scope)) {
|
||||
this.parent$ = this.dsoService.findById(scope).pipe(
|
||||
getSucceededRemoteData()
|
||||
getFirstSucceededRemoteData()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -179,11 +178,11 @@ export class BrowseByMetadataPageComponent implements OnInit {
|
||||
*/
|
||||
goPrev() {
|
||||
if (this.items$) {
|
||||
this.items$.pipe(take(1)).subscribe((items) => {
|
||||
this.items$.pipe(getFirstSucceededRemoteData()).subscribe((items) => {
|
||||
this.items$ = this.browseService.getPrevBrowseItems(items);
|
||||
});
|
||||
} else if (this.browseEntries$) {
|
||||
this.browseEntries$.pipe(take(1)).subscribe((entries) => {
|
||||
this.browseEntries$.pipe(getFirstSucceededRemoteData()).subscribe((entries) => {
|
||||
this.browseEntries$ = this.browseService.getPrevBrowseEntries(entries);
|
||||
});
|
||||
}
|
||||
@@ -194,11 +193,11 @@ export class BrowseByMetadataPageComponent implements OnInit {
|
||||
*/
|
||||
goNext() {
|
||||
if (this.items$) {
|
||||
this.items$.pipe(take(1)).subscribe((items) => {
|
||||
this.items$.pipe(getFirstSucceededRemoteData()).subscribe((items) => {
|
||||
this.items$ = this.browseService.getNextBrowseItems(items);
|
||||
});
|
||||
} else if (this.browseEntries$) {
|
||||
this.browseEntries$.pipe(take(1)).subscribe((entries) => {
|
||||
this.browseEntries$.pipe(getFirstSucceededRemoteData()).subscribe((entries) => {
|
||||
this.browseEntries$ = this.browseService.getNextBrowseEntries(entries);
|
||||
});
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ export class BrowseByTitlePageComponent extends BrowseByMetadataPageComponent {
|
||||
|
||||
ngOnInit(): void {
|
||||
this.sortConfig = new SortOptions('dc.title', SortDirection.ASC);
|
||||
this.updatePage(new BrowseEntrySearchOptions(null, this.paginationConfig, this.sortConfig));
|
||||
this.updatePage(new BrowseEntrySearchOptions(this.defaultBrowseId, this.paginationConfig, this.sortConfig));
|
||||
this.subs.push(
|
||||
observableCombineLatest(
|
||||
this.route.params,
|
||||
|
@@ -6,7 +6,7 @@ import { Collection } from '../core/shared/collection.model';
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
import { BreadcrumbConfig } from '../breadcrumbs/breadcrumb/breadcrumb-config.model';
|
||||
import { Observable } from 'rxjs';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../core/shared/operators';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../core/shared/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
import { getDSORoute } from '../app-routing-paths';
|
||||
@@ -29,7 +29,7 @@ export class BrowseByDSOBreadcrumbResolver {
|
||||
const uuid = route.queryParams.scope;
|
||||
if (hasValue(uuid)) {
|
||||
return this.dataService.findById(uuid).pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
map((object: Community | Collection) => {
|
||||
return { provider: this.breadcrumbService, key: object, url: getDSORoute(object) };
|
||||
|
@@ -3,7 +3,7 @@ import { Inject, Injectable } from '@angular/core';
|
||||
import { DSpaceObjectDataService } from '../core/data/dspace-object-data.service';
|
||||
import { hasNoValue, hasValue } from '../shared/empty.util';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { getSucceededRemoteData } from '../core/shared/operators';
|
||||
import { getFirstSucceededRemoteData } from '../core/shared/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { environment } from '../../environments/environment';
|
||||
@@ -32,7 +32,7 @@ export class BrowseByGuard implements CanActivate {
|
||||
const value = route.queryParams.value;
|
||||
const metadataTranslated = this.translate.instant('browse.metadata.' + id);
|
||||
if (hasValue(scope)) {
|
||||
const dsoAndMetadata$ = this.dsoService.findById(scope).pipe(getSucceededRemoteData());
|
||||
const dsoAndMetadata$ = this.dsoService.findById(scope).pipe(getFirstSucceededRemoteData());
|
||||
return dsoAndMetadata$.pipe(
|
||||
map((dsoRD) => {
|
||||
const name = dsoRD.payload.name;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { filter, tap } from 'rxjs/operators';
|
||||
import { CollectionItemMapperComponent } from './collection-item-mapper.component';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
@@ -22,8 +21,6 @@ import { EventEmitter } from '@angular/core';
|
||||
import { HostWindowService } from '../../shared/host-window.service';
|
||||
import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../core/shared/page-info.model';
|
||||
import { CollectionDataService } from '../../core/data/collection-data.service';
|
||||
import { PaginationComponent } from '../../shared/pagination/pagination.component';
|
||||
import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe';
|
||||
@@ -39,6 +36,12 @@ import { LoadingComponent } from '../../shared/loading/loading.component';
|
||||
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
|
||||
import { SearchService } from '../../core/shared/search/search.service';
|
||||
import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../shared/testing/utils.test';
|
||||
|
||||
describe('CollectionItemMapperComponent', () => {
|
||||
let comp: CollectionItemMapperComponent;
|
||||
@@ -60,7 +63,7 @@ describe('CollectionItemMapperComponent', () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
const mockCollectionRD: RemoteData<Collection> = new RemoteData<Collection>(false, false, true, null, mockCollection);
|
||||
const mockCollectionRD: RemoteData<Collection> = createSuccessfulRemoteDataObject(mockCollection);
|
||||
const mockSearchOptions = of(new PaginatedSearchOptions({
|
||||
pagination: Object.assign(new PaginationComponentOptions(), {
|
||||
id: 'search-page-configuration',
|
||||
@@ -81,7 +84,7 @@ describe('CollectionItemMapperComponent', () => {
|
||||
paginatedSearchOptions: mockSearchOptions
|
||||
};
|
||||
const itemDataServiceStub = {
|
||||
mapToCollection: () => of(new RestResponse(true, 200, 'OK'))
|
||||
mapToCollection: () => createSuccessfulRemoteDataObject$({})
|
||||
};
|
||||
const activatedRouteStub = new ActivatedRouteStub({}, { dso: mockCollectionRD });
|
||||
const translateServiceStub = {
|
||||
@@ -90,7 +93,7 @@ describe('CollectionItemMapperComponent', () => {
|
||||
onTranslationChange: new EventEmitter(),
|
||||
onDefaultLangChange: new EventEmitter()
|
||||
};
|
||||
const emptyList = new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []));
|
||||
const emptyList = createSuccessfulRemoteDataObject(createPaginatedList([]));
|
||||
const searchServiceStub = Object.assign(new SearchServiceStub(), {
|
||||
search: () => of(emptyList),
|
||||
/* tslint:disable:no-empty */
|
||||
@@ -167,7 +170,7 @@ describe('CollectionItemMapperComponent', () => {
|
||||
});
|
||||
|
||||
it('should display an error message if at least one mapping was unsuccessful', () => {
|
||||
spyOn(itemDataService, 'mapToCollection').and.returnValue(of(new RestResponse(false, 404, 'Not Found')));
|
||||
spyOn(itemDataService, 'mapToCollection').and.returnValue(createFailedRemoteDataObject$('Not Found', 404));
|
||||
comp.mapItems(ids);
|
||||
expect(notificationsService.success).not.toHaveBeenCalled();
|
||||
expect(notificationsService.error).toHaveBeenCalled();
|
||||
|
@@ -5,9 +5,13 @@ import { fadeIn, fadeInOut } from '../../shared/animations/fade';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Collection } from '../../core/shared/collection.model';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { map, startWith, switchMap, take } from 'rxjs/operators';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData, toDSpaceObjectListRD } from '../../core/shared/operators';
|
||||
import {
|
||||
getRemoteDataPayload,
|
||||
getFirstSucceededRemoteData,
|
||||
toDSpaceObjectListRD
|
||||
} from '../../core/shared/operators';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
@@ -16,13 +20,13 @@ import { ItemDataService } from '../../core/data/item-data.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CollectionDataService } from '../../core/data/collection-data.service';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { RestResponse } from '../../core/cache/response.models';
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
import { SEARCH_CONFIG_SERVICE } from '../../+my-dspace-page/my-dspace-page.component';
|
||||
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
|
||||
import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model';
|
||||
import { SearchService } from '../../core/shared/search/search.service';
|
||||
import { followLink } from '../../shared/utils/follow-link-config.model';
|
||||
import { NoContent } from '../../core/shared/NoContent.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-collection-item-mapper',
|
||||
@@ -102,7 +106,7 @@ export class CollectionItemMapperComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.collectionRD$ = this.route.data.pipe(map((data) => data.dso)).pipe(getSucceededRemoteData()) as Observable<RemoteData<Collection>>;
|
||||
this.collectionRD$ = this.route.data.pipe(map((data) => data.dso)).pipe(getFirstSucceededRemoteData()) as Observable<RemoteData<Collection>>;
|
||||
this.searchOptions$ = this.searchConfigService.paginatedSearchOptions;
|
||||
this.loadItemLists();
|
||||
}
|
||||
@@ -151,7 +155,7 @@ export class CollectionItemMapperComponent implements OnInit {
|
||||
*/
|
||||
mapItems(ids: string[], remove?: boolean) {
|
||||
const responses$ = this.collectionRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
map((collectionRD: RemoteData<Collection>) => collectionRD.payload),
|
||||
switchMap((collection: Collection) =>
|
||||
observableCombineLatest(ids.map((id: string) =>
|
||||
@@ -168,12 +172,12 @@ export class CollectionItemMapperComponent implements OnInit {
|
||||
* @param {Observable<RestResponse[]>} responses$ The responses after adding/removing a mapping
|
||||
* @param {boolean} remove Whether or not the goal was to remove mappings
|
||||
*/
|
||||
private showNotifications(responses$: Observable<RestResponse[]>, remove?: boolean) {
|
||||
private showNotifications(responses$: Observable<Array<RemoteData<NoContent>>>, remove?: boolean) {
|
||||
const messageInsertion = remove ? 'unmap' : 'map';
|
||||
|
||||
responses$.subscribe((responses: RestResponse[]) => {
|
||||
const successful = responses.filter((response: RestResponse) => response.isSuccessful);
|
||||
const unsuccessful = responses.filter((response: RestResponse) => !response.isSuccessful);
|
||||
responses$.subscribe((responses: Array<RemoteData<NoContent>>) => {
|
||||
const successful = responses.filter((response: RemoteData<any>) => response.hasSucceeded);
|
||||
const unsuccessful = responses.filter((response: RemoteData<any>) => response.hasFailed);
|
||||
if (successful.length > 0) {
|
||||
const successMessages = observableCombineLatest(
|
||||
this.translateService.get(`collection.edit.item-mapper.notifications.${messageInsertion}.success.head`),
|
||||
@@ -246,7 +250,7 @@ export class CollectionItemMapperComponent implements OnInit {
|
||||
*/
|
||||
onCancel() {
|
||||
this.collectionRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
take(1)
|
||||
).subscribe((collection: Collection) => {
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BehaviorSubject, of as observableOf, Observable, Subject } from 'rxjs';
|
||||
import { filter, flatMap, map, startWith, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
import { filter, flatMap, map, startWith, switchMap, take } from 'rxjs/operators';
|
||||
import { PaginatedSearchOptions } from '../shared/search/paginated-search-options.model';
|
||||
import { SearchService } from '../core/shared/search/search.service';
|
||||
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
|
||||
import { CollectionDataService } from '../core/data/collection-data.service';
|
||||
import { PaginatedList } from '../core/data/paginated-list';
|
||||
import { PaginatedList } from '../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
|
||||
import { MetadataService } from '../core/metadata/metadata.service';
|
||||
@@ -16,13 +16,13 @@ import { Collection } from '../core/shared/collection.model';
|
||||
import { DSpaceObjectType } from '../core/shared/dspace-object-type.model';
|
||||
import { Item } from '../core/shared/item.model';
|
||||
import {
|
||||
getSucceededRemoteData,
|
||||
getFirstSucceededRemoteData,
|
||||
redirectOn4xx,
|
||||
toDSpaceObjectListRD
|
||||
} from '../core/shared/operators';
|
||||
|
||||
import { fadeIn, fadeInOut } from '../shared/animations/fade';
|
||||
import { hasNoValue, hasValue, isNotEmpty } from '../shared/empty.util';
|
||||
import { hasValue, isNotEmpty } from '../shared/empty.util';
|
||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||
import { AuthService } from '../core/auth/auth.service';
|
||||
|
||||
@@ -81,7 +81,7 @@ export class CollectionPageComponent implements OnInit {
|
||||
|
||||
this.itemRD$ = this.paginationChanges$.pipe(
|
||||
switchMap((dto) => this.collectionRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
map((rd) => rd.payload.id),
|
||||
switchMap((id: string) => {
|
||||
return this.searchService.search(
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { first } from 'rxjs/operators';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { CollectionPageResolver } from './collection-page.resolver';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
|
||||
|
||||
describe('CollectionPageResolver', () => {
|
||||
describe('resolve', () => {
|
||||
@@ -10,17 +10,18 @@ describe('CollectionPageResolver', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
collectionService = {
|
||||
findById: (id: string) => observableOf({ payload: { id }, hasSucceeded: true })
|
||||
findById: (id: string) => createSuccessfulRemoteDataObject$({ id })
|
||||
};
|
||||
resolver = new CollectionPageResolver(collectionService);
|
||||
});
|
||||
|
||||
it('should resolve a collection with the correct id', () => {
|
||||
it('should resolve a collection with the correct id', (done) => {
|
||||
resolver.resolve({ params: { id: uuid } } as any, undefined)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(resolved) => {
|
||||
expect(resolved.payload.id).toEqual(uuid);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@@ -4,9 +4,8 @@ import { Collection } from '../core/shared/collection.model';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CollectionDataService } from '../core/data/collection-data.service';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
import { find } from 'rxjs/operators';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
import { followLink } from '../shared/utils/follow-link-config.model';
|
||||
import { getFirstCompletedRemoteData } from '../core/shared/operators';
|
||||
|
||||
/**
|
||||
* This class represents a resolver that requests a specific collection before the route is activated
|
||||
@@ -24,8 +23,8 @@ export class CollectionPageResolver implements Resolve<RemoteData<Collection>> {
|
||||
* or an error if something went wrong
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Collection>> {
|
||||
return this.collectionService.findById(route.params.id, followLink('logo')).pipe(
|
||||
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
|
||||
return this.collectionService.findById(route.params.id, false, followLink('logo')).pipe(
|
||||
getFirstCompletedRemoteData()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ describe('CreateCollectionPageGuard', () => {
|
||||
} else if (id === 'invalid-id') {
|
||||
return createSuccessfulRemoteDataObject$(undefined);
|
||||
} else if (id === 'error-id') {
|
||||
return createFailedRemoteDataObject$(new Community());
|
||||
return createFailedRemoteDataObject$('not found', 404);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -5,8 +5,9 @@ import { hasNoValue, hasValue } from '../../shared/empty.util';
|
||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { map, tap, find } from 'rxjs/operators';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
||||
|
||||
/**
|
||||
* Prevent creation of a collection without a parent community provided
|
||||
@@ -30,7 +31,7 @@ export class CreateCollectionPageGuard implements CanActivate {
|
||||
}
|
||||
return this.communityService.findById(parentID)
|
||||
.pipe(
|
||||
find((communityRD: RemoteData<Community>) => hasValue(communityRD.payload) || hasValue(communityRD.error)),
|
||||
getFirstCompletedRemoteData(),
|
||||
map((communityRD: RemoteData<Community>) => hasValue(communityRD) && communityRD.hasSucceeded && hasValue(communityRD.payload)),
|
||||
tap((isValid: boolean) => {
|
||||
if (!isValid) {
|
||||
|
@@ -7,7 +7,7 @@ import { ItemTemplateDataService } from '../../../core/data/item-template-data.s
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { switchMap, take } from 'rxjs/operators';
|
||||
import { combineLatest as combineLatestObservable } from 'rxjs';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
@@ -54,7 +54,7 @@ export class CollectionMetadataComponent extends ComcolMetadataComponent<Collect
|
||||
*/
|
||||
initTemplateItem() {
|
||||
this.itemTemplateRD$ = this.dsoRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
switchMap((collection: Collection) => this.itemTemplateService.findByCollectionID(collection.uuid))
|
||||
);
|
||||
@@ -65,13 +65,13 @@ export class CollectionMetadataComponent extends ComcolMetadataComponent<Collect
|
||||
*/
|
||||
addItemTemplate() {
|
||||
const collection$ = this.dsoRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
take(1)
|
||||
);
|
||||
const template$ = collection$.pipe(
|
||||
switchMap((collection: Collection) => this.itemTemplateService.create(new Item(), collection.uuid)),
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
take(1)
|
||||
);
|
||||
@@ -86,13 +86,13 @@ export class CollectionMetadataComponent extends ComcolMetadataComponent<Collect
|
||||
*/
|
||||
deleteItemTemplate() {
|
||||
const collection$ = this.dsoRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
take(1)
|
||||
);
|
||||
const template$ = collection$.pipe(
|
||||
switchMap((collection: Collection) => this.itemTemplateService.findByCollectionID(collection.uuid)),
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
take(1)
|
||||
);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<ds-comcol-role
|
||||
*ngFor="let comcolRole of getComcolRoles() | async"
|
||||
*ngFor="let comcolRole of comcolRoles$ | async"
|
||||
[dso]="collection$ | async"
|
||||
[comcolRole]="comcolRole"
|
||||
>
|
||||
|
@@ -11,6 +11,7 @@ import { SharedModule } from '../../../shared/shared.module';
|
||||
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
|
||||
describe('CollectionRolesComponent', () => {
|
||||
|
||||
@@ -23,11 +24,7 @@ describe('CollectionRolesComponent', () => {
|
||||
const route = {
|
||||
parent: {
|
||||
data: observableOf({
|
||||
dso: new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
dso: createSuccessfulRemoteDataObject(
|
||||
Object.assign(new Collection(), {
|
||||
_links: {
|
||||
irrelevant: {
|
||||
@@ -52,25 +49,18 @@ describe('CollectionRolesComponent', () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
})
|
||||
),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
const requestService = {
|
||||
hasByHrefObservable: () => observableOf(true),
|
||||
hasByHref$: () => observableOf(true),
|
||||
};
|
||||
|
||||
const groupDataService = {
|
||||
findByHref: () => observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
{},
|
||||
200,
|
||||
)),
|
||||
findByHref: () => createSuccessfulRemoteDataObject$({}),
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
@@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
|
||||
import { first, map } from 'rxjs/operators';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { HALLink } from '../../../core/shared/hal-link.model';
|
||||
|
||||
/**
|
||||
@@ -18,21 +18,33 @@ export class CollectionRolesComponent implements OnInit {
|
||||
|
||||
dsoRD$: Observable<RemoteData<Collection>>;
|
||||
|
||||
/**
|
||||
* The collection to manage, as an observable.
|
||||
*/
|
||||
get collection$(): Observable<Collection> {
|
||||
return this.dsoRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The different roles for the collection, as an observable.
|
||||
*/
|
||||
getComcolRoles(): Observable<HALLink[]> {
|
||||
return this.collection$.pipe(
|
||||
comcolRoles$: Observable<HALLink[]>
|
||||
|
||||
/**
|
||||
* The collection to manage, as an observable.
|
||||
*/
|
||||
collection$: Observable<Collection>
|
||||
|
||||
constructor(
|
||||
protected route: ActivatedRoute,
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.dsoRD$ = this.route.parent.data.pipe(
|
||||
first(),
|
||||
map((data) => data.dso),
|
||||
);
|
||||
|
||||
this.collection$ = this.dsoRD$.pipe(
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
);
|
||||
|
||||
this.comcolRoles$ = this.collection$.pipe(
|
||||
map((collection) => [
|
||||
{
|
||||
name: 'collection-admin',
|
||||
@@ -54,16 +66,4 @@ export class CollectionRolesComponent implements OnInit {
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
protected route: ActivatedRoute,
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.dsoRD$ = this.route.parent.data.pipe(
|
||||
first(),
|
||||
map((data) => data.dso),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -17,9 +17,9 @@ import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
|
||||
const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
|
||||
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
|
||||
@@ -111,7 +111,7 @@ describe('CollectionSourceComponent', () => {
|
||||
uuid: 'fake-collection-id'
|
||||
});
|
||||
collectionService = jasmine.createSpyObj('collectionService', {
|
||||
getContentSource: observableOf(contentSource),
|
||||
getContentSource: createSuccessfulRemoteDataObject$(contentSource),
|
||||
updateContentSource: observableOf(contentSource),
|
||||
getHarvesterEndpoint: observableOf('harvester-endpoint')
|
||||
});
|
||||
@@ -125,7 +125,7 @@ describe('CollectionSourceComponent', () => {
|
||||
{ provide: NotificationsService, useValue: notificationsService },
|
||||
{ provide: Location, useValue: location },
|
||||
{ provide: DynamicFormService, useValue: formService },
|
||||
{ provide: ActivatedRoute, useValue: { parent: { data: observableOf({ dso: new RemoteData(false, false, true, null, collection) }) } } },
|
||||
{ provide: ActivatedRoute, useValue: { parent: { data: observableOf({ dso: createSuccessfulRemoteDataObject(collection) }) } } },
|
||||
{ provide: Router, useValue: router },
|
||||
{ provide: CollectionDataService, useValue: collectionService },
|
||||
{ provide: RequestService, useValue: requestService }
|
||||
|
@@ -27,7 +27,7 @@ import { FieldUpdate, FieldUpdates } from '../../../core/data/object-updates/obj
|
||||
import { Subscription } from 'rxjs/internal/Subscription';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { getFirstSucceededRemoteData, getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||
import { MetadataConfig } from '../../../core/shared/metadata-config.model';
|
||||
import { INotification } from '../../../shared/notifications/models/notification.model';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
@@ -255,12 +255,12 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
|
||||
this.collectionRD$ = this.route.parent.data.pipe(first(), map((data) => data.dso));
|
||||
|
||||
this.collectionRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
map((col) => col.payload.uuid),
|
||||
switchMap((uuid) => this.collectionService.getContentSource(uuid)),
|
||||
take(1)
|
||||
).subscribe((contentSource: ContentSource) => {
|
||||
this.initializeOriginalContentSource(contentSource);
|
||||
getFirstCompletedRemoteData(),
|
||||
).subscribe((rd: RemoteData<ContentSource>) => {
|
||||
this.initializeOriginalContentSource(rd.payload);
|
||||
});
|
||||
|
||||
this.updateFieldTranslations();
|
||||
@@ -376,7 +376,7 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
|
||||
onSubmit() {
|
||||
// Remove cached harvester request to allow for latest harvester to be displayed when switching tabs
|
||||
this.collectionRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
map((col) => col.payload.uuid),
|
||||
switchMap((uuid) => this.collectionService.getHarvesterEndpoint(uuid)),
|
||||
take(1)
|
||||
@@ -384,7 +384,7 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
|
||||
|
||||
// Update harvester
|
||||
this.collectionRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
map((col) => col.payload.uuid),
|
||||
switchMap((uuid) => this.collectionService.updateContentSource(uuid, this.contentSource)),
|
||||
take(1)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { ItemTemplatePageResolver } from './item-template-page.resolver';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
|
||||
describe('ItemTemplatePageResolver', () => {
|
||||
describe('resolve', () => {
|
||||
@@ -10,17 +10,18 @@ describe('ItemTemplatePageResolver', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
itemTemplateService = {
|
||||
findByCollectionID: (id: string) => observableOf({ payload: { id }, hasSucceeded: true })
|
||||
findByCollectionID: (id: string) => createSuccessfulRemoteDataObject$({ id })
|
||||
};
|
||||
resolver = new ItemTemplatePageResolver(itemTemplateService);
|
||||
});
|
||||
|
||||
it('should resolve an item template with the correct id', () => {
|
||||
it('should resolve an item template with the correct id', (done) => {
|
||||
resolver.resolve({ params: { id: uuid } } as any, undefined)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(resolved) => {
|
||||
expect(resolved.payload.id).toEqual(uuid);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@@ -4,9 +4,8 @@ import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import { ItemTemplateDataService } from '../../core/data/item-template-data.service';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { find } from 'rxjs/operators';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { followLink } from '../../shared/utils/follow-link-config.model';
|
||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
||||
|
||||
/**
|
||||
* This class represents a resolver that requests a specific collection's item template before the route is activated
|
||||
@@ -24,8 +23,8 @@ export class ItemTemplatePageResolver implements Resolve<RemoteData<Item>> {
|
||||
* or an error if something went wrong
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Item>> {
|
||||
return this.itemTemplateService.findByCollectionID(route.params.id, followLink('templateItemOf')).pipe(
|
||||
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
|
||||
return this.itemTemplateService.findByCollectionID(route.params.id, false, followLink('templateItemOf')).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import { mergeMap, filter, map } from 'rxjs/operators';
|
||||
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { Subscription, Observable } from 'rxjs';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CommunityDataService } from '../core/data/community-data.service';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
import { Bitstream } from '../core/shared/bitstream.model';
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { CommunityPageResolver } from './community-page.resolver';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
|
||||
|
||||
describe('CommunityPageResolver', () => {
|
||||
describe('resolve', () => {
|
||||
@@ -10,17 +10,18 @@ describe('CommunityPageResolver', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
communityService = {
|
||||
findById: (id: string) => observableOf({ payload: { id }, hasSucceeded: true })
|
||||
findById: (id: string) => createSuccessfulRemoteDataObject$({ id })
|
||||
};
|
||||
resolver = new CommunityPageResolver(communityService);
|
||||
});
|
||||
|
||||
it('should resolve a community with the correct id', () => {
|
||||
it('should resolve a community with the correct id', (done) => {
|
||||
resolver.resolve({ params: { id: uuid } } as any, undefined)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(resolved) => {
|
||||
expect(resolved.payload.id).toEqual(uuid);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@@ -4,9 +4,8 @@ import { Observable } from 'rxjs';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
import { Community } from '../core/shared/community.model';
|
||||
import { CommunityDataService } from '../core/data/community-data.service';
|
||||
import { find } from 'rxjs/operators';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
import { followLink } from '../shared/utils/follow-link-config.model';
|
||||
import { getFirstCompletedRemoteData } from '../core/shared/operators';
|
||||
|
||||
/**
|
||||
* This class represents a resolver that requests a specific community before the route is activated
|
||||
@@ -26,11 +25,12 @@ export class CommunityPageResolver implements Resolve<RemoteData<Community>> {
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Community>> {
|
||||
return this.communityService.findById(
|
||||
route.params.id,
|
||||
false,
|
||||
followLink('logo'),
|
||||
followLink('subcommunities'),
|
||||
followLink('collections')
|
||||
).pipe(
|
||||
find((RD) => hasValue(RD.error) || RD.hasSucceeded)
|
||||
getFirstCompletedRemoteData(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,10 @@ import { CreateCommunityPageGuard } from './create-community-page.guard';
|
||||
import { RouterMock } from '../../shared/mocks/router.mock';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../shared/remote-data.utils';
|
||||
|
||||
describe('CreateCommunityPageGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
@@ -18,7 +21,7 @@ describe('CreateCommunityPageGuard', () => {
|
||||
} else if (id === 'invalid-id') {
|
||||
return createSuccessfulRemoteDataObject$(undefined);
|
||||
} else if (id === 'error-id') {
|
||||
return createFailedRemoteDataObject$(new Community());
|
||||
return createFailedRemoteDataObject$('not found', 404);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -5,8 +5,9 @@ import { hasNoValue, hasValue } from '../../shared/empty.util';
|
||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { map, tap, find } from 'rxjs/operators';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
||||
|
||||
/**
|
||||
* Prevent creation of a community with an invalid parent community provided
|
||||
@@ -30,7 +31,7 @@ export class CreateCommunityPageGuard implements CanActivate {
|
||||
|
||||
return this.communityService.findById(parentID)
|
||||
.pipe(
|
||||
find((communityRD: RemoteData<Community>) => hasValue(communityRD.payload) || hasValue(communityRD.error)),
|
||||
getFirstCompletedRemoteData(),
|
||||
map((communityRD: RemoteData<Community>) => hasValue(communityRD) && communityRD.hasSucceeded && hasValue(communityRD.payload)),
|
||||
tap((isValid: boolean) => {
|
||||
if (!isValid) {
|
||||
|
@@ -11,6 +11,7 @@ import { RequestService } from '../../../core/data/request.service';
|
||||
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
||||
import { SharedModule } from '../../../shared/shared.module';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
|
||||
describe('CommunityRolesComponent', () => {
|
||||
|
||||
@@ -23,11 +24,7 @@ describe('CommunityRolesComponent', () => {
|
||||
const route = {
|
||||
parent: {
|
||||
data: observableOf({
|
||||
dso: new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
dso: createSuccessfulRemoteDataObject(
|
||||
Object.assign(new Community(), {
|
||||
_links: {
|
||||
irrelevant: {
|
||||
@@ -37,25 +34,18 @@ describe('CommunityRolesComponent', () => {
|
||||
href: 'adminGroup link',
|
||||
},
|
||||
},
|
||||
}),
|
||||
})
|
||||
),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
const requestService = {
|
||||
hasByHrefObservable: () => observableOf(true),
|
||||
hasByHref$: () => observableOf(true),
|
||||
};
|
||||
|
||||
const groupDataService = {
|
||||
findByHref: () => observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
{},
|
||||
200,
|
||||
)),
|
||||
findByHref: () => createSuccessfulRemoteDataObject$({}),
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
@@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { first, map } from 'rxjs/operators';
|
||||
import { Community } from '../../../core/shared/community.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { HALLink } from '../../../core/shared/hal-link.model';
|
||||
|
||||
@@ -23,7 +23,7 @@ export class CommunityRolesComponent implements OnInit {
|
||||
*/
|
||||
get community$(): Observable<Community> {
|
||||
return this.dsoRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
)
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ import { SharedModule } from '../../shared/shared.module';
|
||||
import { CollectionDataService } from '../../core/data/collection-data.service';
|
||||
import { FindListOptions } from '../../core/data/request.models';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { buildPaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { PageInfo } from '../../core/shared/page-info.model';
|
||||
import { HostWindowService } from '../../shared/host-window.service';
|
||||
import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub';
|
||||
@@ -105,7 +105,7 @@ describe('CommunityPageSubCollectionList Component', () => {
|
||||
if (endPageIndex > subCollList.length) {
|
||||
endPageIndex = subCollList.length;
|
||||
}
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), subCollList.slice(startPageIndex, endPageIndex)));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), subCollList.slice(startPageIndex, endPageIndex)));
|
||||
|
||||
}
|
||||
};
|
||||
|
@@ -1,16 +1,16 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Collection } from '../../core/shared/collection.model';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { fadeIn } from '../../shared/animations/fade';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
import { CollectionDataService } from '../../core/data/collection-data.service';
|
||||
import { takeUntilCompletedRemoteData } from '../../core/shared/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-community-page-sub-collection-list',
|
||||
@@ -72,7 +72,7 @@ export class CommunityPageSubCollectionListComponent implements OnInit {
|
||||
currentPage: this.config.currentPage,
|
||||
elementsPerPage: this.config.pageSize,
|
||||
sort: { field: this.sortConfig.field, direction: this.sortConfig.direction }
|
||||
}).pipe(take(1)).subscribe((results) => {
|
||||
}).pipe(takeUntilCompletedRemoteData()).subscribe((results) => {
|
||||
this.subCollectionsRDObs.next(results);
|
||||
});
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
import { CommunityPageSubCommunityListComponent } from './community-page-sub-community-list.component';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { PageInfo } from '../../core/shared/page-info.model';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
@@ -106,7 +106,7 @@ describe('CommunityPageSubCommunityListComponent Component', () => {
|
||||
if (endPageIndex > subCommList.length) {
|
||||
endPageIndex = subCommList.length;
|
||||
}
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), subCommList.slice(startPageIndex, endPageIndex)));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), subCommList.slice(startPageIndex, endPageIndex)));
|
||||
|
||||
}
|
||||
};
|
||||
|
@@ -1,15 +1,15 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { fadeIn } from '../../shared/animations/fade';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||
import { takeUntilCompletedRemoteData } from '../../core/shared/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-community-page-sub-community-list',
|
||||
@@ -75,7 +75,7 @@ export class CommunityPageSubCommunityListComponent implements OnInit {
|
||||
currentPage: this.config.currentPage,
|
||||
elementsPerPage: this.config.pageSize,
|
||||
sort: { field: this.sortConfig.field, direction: this.sortConfig.direction }
|
||||
}).pipe(take(1)).subscribe((results) => {
|
||||
}).pipe(takeUntilCompletedRemoteData()).subscribe((results) => {
|
||||
this.subCommunitiesRDObs.next(results);
|
||||
});
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
import { TopLevelCommunityListComponent } from './top-level-community-list.component';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { PageInfo } from '../../core/shared/page-info.model';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
@@ -96,7 +96,7 @@ describe('TopLevelCommunityList Component', () => {
|
||||
if (endPageIndex > topCommList.length) {
|
||||
endPageIndex = topCommList.length;
|
||||
}
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), topCommList.slice(startPageIndex, endPageIndex)));
|
||||
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), topCommList.slice(startPageIndex, endPageIndex)));
|
||||
|
||||
}
|
||||
};
|
||||
|
@@ -1,15 +1,15 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, OnInit, OnDestroy } from '@angular/core';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { BehaviorSubject, Subscription } from 'rxjs';
|
||||
|
||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { fadeInOut } from '../../shared/animations/fade';
|
||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
|
||||
/**
|
||||
* this component renders the Top-Level Community list
|
||||
@@ -22,7 +22,7 @@ import { PaginationComponentOptions } from '../../shared/pagination/pagination-c
|
||||
animations: [fadeInOut]
|
||||
})
|
||||
|
||||
export class TopLevelCommunityListComponent implements OnInit {
|
||||
export class TopLevelCommunityListComponent implements OnInit, OnDestroy {
|
||||
/**
|
||||
* A list of remote data objects of all top communities
|
||||
*/
|
||||
@@ -43,6 +43,11 @@ export class TopLevelCommunityListComponent implements OnInit {
|
||||
*/
|
||||
sortConfig: SortOptions;
|
||||
|
||||
/**
|
||||
* The subscription to the observable for the current page.
|
||||
*/
|
||||
currentPageSubscription: Subscription;
|
||||
|
||||
constructor(private cds: CommunityDataService) {
|
||||
this.config = new PaginationComponentOptions();
|
||||
this.config.id = this.pageId;
|
||||
@@ -71,12 +76,29 @@ export class TopLevelCommunityListComponent implements OnInit {
|
||||
* Update the list of top communities
|
||||
*/
|
||||
updatePage() {
|
||||
this.cds.findTop({
|
||||
this.unsubscribe();
|
||||
this.currentPageSubscription = this.cds.findTop({
|
||||
currentPage: this.config.currentPage,
|
||||
elementsPerPage: this.config.pageSize,
|
||||
sort: { field: this.sortConfig.field, direction: this.sortConfig.direction }
|
||||
}).pipe(take(1)).subscribe((results) => {
|
||||
}).subscribe((results) => {
|
||||
this.communitiesRD$.next(results);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe the top list subscription if it exists
|
||||
*/
|
||||
private unsubscribe() {
|
||||
if (hasValue(this.currentPageSubscription)) {
|
||||
this.currentPageSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up subscriptions when the component is destroyed
|
||||
*/
|
||||
ngOnDestroy() {
|
||||
this.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,10 @@ import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||
import { BundleDataService } from '../../../core/data/bundle-data.service';
|
||||
import { Bundle } from '../../../core/shared/bundle.model';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
import {
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
|
||||
@@ -192,7 +195,7 @@ describe('UploadBistreamComponent', () => {
|
||||
function createUploadBitstreamTestingModule(queryParams) {
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
item: createSuccessfulRemoteDataObject(mockItem)
|
||||
dso: createSuccessfulRemoteDataObject(mockItem)
|
||||
}),
|
||||
queryParams: observableOf(queryParams),
|
||||
snapshot: {
|
||||
|
@@ -11,7 +11,7 @@ import { ItemDataService } from '../../../core/data/item-data.service';
|
||||
import { AuthService } from '../../../core/auth/auth.service';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { Bundle } from '../../../core/shared/bundle.model';
|
||||
import { BundleDataService } from '../../../core/data/bundle-data.service';
|
||||
import {
|
||||
@@ -103,7 +103,7 @@ export class UploadBitstreamComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.itemId = this.route.snapshot.params.id;
|
||||
this.itemRD$ = this.route.data.pipe(map((data) => data.item));
|
||||
this.itemRD$ = this.route.data.pipe(map((data) => data.dso));
|
||||
this.bundlesRD$ = this.itemRD$.pipe(
|
||||
switchMap((itemRD: RemoteData<Item>) => itemRD.payload.bundles)
|
||||
);
|
||||
|
@@ -6,6 +6,7 @@ import {
|
||||
createFailedRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject
|
||||
} from '../../shared/remote-data.utils';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
|
||||
describe('findSuccessfulAccordingTo', () => {
|
||||
let mockItem1;
|
||||
@@ -19,12 +20,12 @@ describe('findSuccessfulAccordingTo', () => {
|
||||
mockItem2 = new Item();
|
||||
mockItem1.isWithdrawn = false;
|
||||
|
||||
predicate = (rd: RemoteData<Item>) => rd.payload.isWithdrawn;
|
||||
predicate = (rd: RemoteData<Item>) => isNotEmpty(rd.payload) ? rd.payload.isWithdrawn : false;
|
||||
});
|
||||
it('should return first successful RemoteData Observable that complies to predicate', () => {
|
||||
const testRD = {
|
||||
a: createSuccessfulRemoteDataObject(undefined),
|
||||
b: createFailedRemoteDataObject(mockItem1),
|
||||
b: createFailedRemoteDataObject(),
|
||||
c: createSuccessfulRemoteDataObject(mockItem2),
|
||||
d: createSuccessfulRemoteDataObject(mockItem1),
|
||||
e: createSuccessfulRemoteDataObject(mockItem2),
|
||||
|
@@ -2,21 +2,18 @@ import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'
|
||||
import { Component, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { cold } from 'jasmine-marbles';
|
||||
|
||||
import { ItemAuthorizationsComponent } from './item-authorizations.component';
|
||||
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||
import { Bundle } from '../../../core/shared/bundle.model';
|
||||
import { createMockRDPaginatedObs } from '../item-bitstreams/item-bitstreams.component.spec';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { LinkService } from '../../../core/cache/builders/link.service';
|
||||
import { getMockLinkService } from '../../../shared/mocks/link-service.mock';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils';
|
||||
import { createTestComponent } from '../../../shared/testing/utils.test';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
import { createPaginatedList, createTestComponent } from '../../../shared/testing/utils.test';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
|
||||
describe('ItemAuthorizationsComponent test suite', () => {
|
||||
@@ -49,7 +46,7 @@ describe('ItemAuthorizationsComponent test suite', () => {
|
||||
_links: {
|
||||
self: { href: 'bundle1-selflink' }
|
||||
},
|
||||
bitstreams: createMockRDPaginatedObs([bitstream1, bitstream2])
|
||||
bitstreams: createSuccessfulRemoteDataObject$(createPaginatedList([bitstream1, bitstream2]))
|
||||
});
|
||||
const bundle2 = Object.assign(new Bundle(), {
|
||||
id: 'bundle2',
|
||||
@@ -57,11 +54,11 @@ describe('ItemAuthorizationsComponent test suite', () => {
|
||||
_links: {
|
||||
self: { href: 'bundle2-selflink' }
|
||||
},
|
||||
bitstreams: createMockRDPaginatedObs([bitstream3, bitstream4])
|
||||
bitstreams: createSuccessfulRemoteDataObject$(createPaginatedList([bitstream3, bitstream4]))
|
||||
});
|
||||
const bundles = [bundle1, bundle2];
|
||||
const bitstreamList1: PaginatedList<Bitstream> = new PaginatedList(new PageInfo(), [bitstream1, bitstream2]);
|
||||
const bitstreamList2: PaginatedList<Bitstream> = new PaginatedList(new PageInfo(), [bitstream3, bitstream4]);
|
||||
const bitstreamList1: PaginatedList<Bitstream> = buildPaginatedList(new PageInfo(), [bitstream1, bitstream2]);
|
||||
const bitstreamList2: PaginatedList<Bitstream> = buildPaginatedList(new PageInfo(), [bitstream3, bitstream4]);
|
||||
|
||||
const item = Object.assign(new Item(), {
|
||||
uuid: 'item',
|
||||
@@ -69,7 +66,7 @@ describe('ItemAuthorizationsComponent test suite', () => {
|
||||
_links: {
|
||||
self: { href: 'item-selflink' }
|
||||
},
|
||||
bundles: createMockRDPaginatedObs([bundle1, bundle2])
|
||||
bundles: createSuccessfulRemoteDataObject$(createPaginatedList([bundle1, bundle2]))
|
||||
});
|
||||
|
||||
const routeStub = {
|
||||
|
@@ -4,7 +4,7 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { BehaviorSubject, Observable, of as observableOf, Subscription } from 'rxjs';
|
||||
import { catchError, filter, first, flatMap, map, take } from 'rxjs/operators';
|
||||
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import {
|
||||
getFirstSucceededRemoteDataPayload,
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload
|
||||
@@ -89,7 +89,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
||||
catchError((error) => {
|
||||
console.error(error);
|
||||
return observableOf(new PaginatedList(null, []))
|
||||
return observableOf(buildPaginatedList(null, []))
|
||||
})
|
||||
);
|
||||
|
||||
@@ -139,7 +139,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
catchError((error) => {
|
||||
console.error(error);
|
||||
return observableOf(new PaginatedList(null, []))
|
||||
return observableOf(buildPaginatedList(null, []))
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@@ -1,8 +1,5 @@
|
||||
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ItemBitstreamsComponent } from './item-bitstreams.component';
|
||||
@@ -13,7 +10,10 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { ChangeDetectorRef, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions';
|
||||
import { INotification, Notification } from '../../../shared/notifications/models/notification.model';
|
||||
import {
|
||||
INotification,
|
||||
Notification
|
||||
} from '../../../shared/notifications/models/notification.model';
|
||||
import { NotificationType } from '../../../shared/notifications/models/notification-type';
|
||||
import { BitstreamDataService } from '../../../core/data/bitstream-data.service';
|
||||
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
|
||||
@@ -26,6 +26,11 @@ import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { getMockRequestService } from '../../../shared/mocks/request.service.mock';
|
||||
import {
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
|
||||
let comp: ItemBitstreamsComponent;
|
||||
let fixture: ComponentFixture<ItemBitstreamsComponent>;
|
||||
@@ -55,7 +60,7 @@ const bundle = Object.assign(new Bundle(), {
|
||||
_links: {
|
||||
self: { href: 'bundle1-selflink' }
|
||||
},
|
||||
bitstreams: createMockRDPaginatedObs([bitstream1, bitstream2])
|
||||
bitstreams: createSuccessfulRemoteDataObject$(createPaginatedList([bitstream1, bitstream2]))
|
||||
});
|
||||
const moveOperations = [
|
||||
{
|
||||
@@ -130,17 +135,17 @@ describe('ItemBitstreamsComponent', () => {
|
||||
_links: {
|
||||
self: { href: 'item-selflink' }
|
||||
},
|
||||
bundles: createMockRDPaginatedObs([bundle]),
|
||||
bundles: createSuccessfulRemoteDataObject$(createPaginatedList([bundle])),
|
||||
lastModified: date
|
||||
});
|
||||
itemService = Object.assign( {
|
||||
getBitstreams: () => createMockRDPaginatedObs([bitstream1, bitstream2]),
|
||||
findById: () => createMockRDObs(item),
|
||||
getBundles: () => createMockRDPaginatedObs([bundle])
|
||||
getBitstreams: () => createSuccessfulRemoteDataObject$(createPaginatedList([bitstream1, bitstream2])),
|
||||
findById: () => createSuccessfulRemoteDataObject$(item),
|
||||
getBundles: () => createSuccessfulRemoteDataObject$(createPaginatedList([bundle]))
|
||||
});
|
||||
route = Object.assign({
|
||||
parent: {
|
||||
data: observableOf({ dso: createMockRD(item) })
|
||||
data: observableOf({ dso: createSuccessfulRemoteDataObject(item) })
|
||||
},
|
||||
data: observableOf({}),
|
||||
url: url
|
||||
@@ -235,15 +240,3 @@ describe('ItemBitstreamsComponent', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
export function createMockRDPaginatedObs(list: any[]) {
|
||||
return createMockRDObs(new PaginatedList(new PageInfo(), list));
|
||||
}
|
||||
|
||||
export function createMockRDObs(obj: any) {
|
||||
return observableOf(createMockRD(obj));
|
||||
}
|
||||
|
||||
export function createMockRD(obj: any) {
|
||||
return new RemoteData(false, false, true, null, obj);
|
||||
}
|
||||
|
@@ -11,13 +11,12 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { BitstreamDataService } from '../../../core/data/bitstream-data.service';
|
||||
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { zip as observableZip, of as observableOf } from 'rxjs';
|
||||
import { ErrorResponse, RestResponse } from '../../../core/cache/response.models';
|
||||
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { Bundle } from '../../../core/shared/bundle.model';
|
||||
import { FieldUpdate, FieldUpdates } from '../../../core/data/object-updates/object-updates.reducer';
|
||||
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||
@@ -26,6 +25,8 @@ import { BundleDataService } from '../../../core/data/bundle-data.service';
|
||||
import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model';
|
||||
import { ResponsiveColumnSizes } from '../../../shared/responsive-table-sizes/responsive-column-sizes';
|
||||
import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-bitstreams',
|
||||
@@ -107,7 +108,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
|
||||
*/
|
||||
postItemInit(): void {
|
||||
this.bundles$ = this.itemService.getBundles(this.item.id, new PaginatedSearchOptions({pagination: this.bundlesOptions})).pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
map((bundlePage: PaginatedList<Bundle>) => bundlePage.page)
|
||||
);
|
||||
@@ -125,10 +126,10 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
|
||||
* Also re-initialize the original fields and updates
|
||||
*/
|
||||
initializeItemUpdate(): void {
|
||||
this.itemUpdateSubscription = this.requestService.hasByHrefObservable(this.item.self).pipe(
|
||||
this.itemUpdateSubscription = this.requestService.hasByHref$(this.item.self).pipe(
|
||||
filter((exists: boolean) => !exists),
|
||||
switchMap(() => this.itemService.findById(this.item.uuid)),
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
).subscribe((itemRD: RemoteData<Item>) => {
|
||||
if (hasValue(itemRD)) {
|
||||
this.item = itemRD.payload;
|
||||
@@ -173,7 +174,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
|
||||
);
|
||||
|
||||
// Perform the setup actions from above in order and display notifications
|
||||
removedResponses$.pipe(take(1)).subscribe((responses: RestResponse[]) => {
|
||||
removedResponses$.pipe(take(1)).subscribe((responses: Array<RemoteData<NoContent>>) => {
|
||||
this.displayNotifications('item.edit.bitstreams.notifications.remove', responses);
|
||||
this.reset();
|
||||
this.submitting = false;
|
||||
@@ -190,12 +191,12 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
|
||||
dropBitstream(bundle: Bundle, event: any) {
|
||||
this.zone.runOutsideAngular(() => {
|
||||
if (hasValue(event) && hasValue(event.fromIndex) && hasValue(event.toIndex) && hasValue(event.finish)) {
|
||||
const moveOperation = Object.assign({
|
||||
const moveOperation = {
|
||||
op: 'move',
|
||||
from: `/_links/bitstreams/${event.fromIndex}/href`,
|
||||
path: `/_links/bitstreams/${event.toIndex}/href`
|
||||
});
|
||||
this.bundleService.patch(bundle, [moveOperation]).pipe(take(1)).subscribe((response: RestResponse) => {
|
||||
} as Operation;
|
||||
this.bundleService.patch(bundle, [moveOperation]).pipe(take(1)).subscribe((response: RemoteData<Bundle>) => {
|
||||
this.zone.run(() => {
|
||||
this.displayNotifications('item.edit.bitstreams.notifications.move', [response]);
|
||||
// Remove all cached requests from this bundle and call the event's callback when the requests are cleared
|
||||
@@ -216,12 +217,12 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
|
||||
* @param key The i18n key for the notification messages
|
||||
* @param responses The returned responses to display notifications for
|
||||
*/
|
||||
displayNotifications(key: string, responses: RestResponse[]) {
|
||||
displayNotifications(key: string, responses: Array<RemoteData<any>>) {
|
||||
if (isNotEmpty(responses)) {
|
||||
const failedResponses = responses.filter((response: RestResponse) => hasValue(response) && !response.isSuccessful);
|
||||
const successfulResponses = responses.filter((response: RestResponse) => hasValue(response) && response.isSuccessful);
|
||||
const failedResponses = responses.filter((response: RemoteData<Bundle>) => hasValue(response) && response.hasFailed);
|
||||
const successfulResponses = responses.filter((response: RemoteData<Bundle>) => hasValue(response) && response.hasSucceeded);
|
||||
|
||||
failedResponses.forEach((response: ErrorResponse) => {
|
||||
failedResponses.forEach((response: RemoteData<Bundle>) => {
|
||||
this.notificationsService.error(this.translateService.instant(`${key}.failed.title`), response.errorMessage);
|
||||
});
|
||||
if (successfulResponses.length > 0) {
|
||||
|
@@ -7,7 +7,6 @@ import { VarDirective } from '../../../../../shared/utils/var.directive';
|
||||
import { ObjectValuesPipe } from '../../../../../shared/utils/object-values-pipe';
|
||||
import { ObjectUpdatesService } from '../../../../../core/data/object-updates/object-updates.service';
|
||||
import { BundleDataService } from '../../../../../core/data/bundle-data.service';
|
||||
import { createMockRDObs } from '../../item-bitstreams.component.spec';
|
||||
import { Bitstream } from '../../../../../core/shared/bitstream.model';
|
||||
import { BitstreamFormat } from '../../../../../core/shared/bitstream-format.model';
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
@@ -49,7 +48,7 @@ describe('PaginatedDragAndDropBitstreamListComponent', () => {
|
||||
name: 'Fake Bitstream 1',
|
||||
bundleName: 'ORIGINAL',
|
||||
description: 'Description',
|
||||
format: createMockRDObs(format)
|
||||
format: createSuccessfulRemoteDataObject$(format)
|
||||
});
|
||||
const fieldUpdate1 = {
|
||||
field: bitstream1,
|
||||
@@ -60,7 +59,7 @@ describe('PaginatedDragAndDropBitstreamListComponent', () => {
|
||||
name: 'Fake Bitstream 2',
|
||||
bundleName: 'ORIGINAL',
|
||||
description: 'Description',
|
||||
format: createMockRDObs(format)
|
||||
format: createSuccessfulRemoteDataObject$(format)
|
||||
});
|
||||
const fieldUpdate2 = {
|
||||
field: bitstream2,
|
||||
@@ -107,7 +106,7 @@ describe('PaginatedDragAndDropBitstreamListComponent', () => {
|
||||
objectValuesPipe = new ObjectValuesPipe();
|
||||
|
||||
requestService = jasmine.createSpyObj('requestService', {
|
||||
hasByHrefObservable: observableOf(true)
|
||||
hasByHref$: observableOf(true)
|
||||
});
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
|
@@ -53,7 +53,7 @@ export class PaginatedDragAndDropBitstreamListComponent extends AbstractPaginate
|
||||
switchMap((page: number) => {
|
||||
const paginatedOptions = new PaginatedSearchOptions({pagination: Object.assign({}, this.options, { currentPage: page })});
|
||||
return this.bundleService.getBitstreamsEndpoint(this.bundle.id, paginatedOptions).pipe(
|
||||
switchMap((href) => this.requestService.hasByHrefObservable(href)),
|
||||
switchMap((href) => this.requestService.hasByHref$(href)),
|
||||
switchMap(() => this.bundleService.getBitstreams(
|
||||
this.bundle.id,
|
||||
paginatedOptions,
|
||||
|
@@ -6,10 +6,10 @@ import { Bitstream } from '../../../../core/shared/bitstream.model';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { VarDirective } from '../../../../shared/utils/var.directive';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { createMockRDObs } from '../item-bitstreams.component.spec';
|
||||
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
|
||||
import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes';
|
||||
import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes/responsive-column-sizes';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
|
||||
|
||||
let comp: ItemEditBitstreamComponent;
|
||||
let fixture: ComponentFixture<ItemEditBitstreamComponent>;
|
||||
@@ -29,7 +29,7 @@ const bitstream = Object.assign(new Bitstream(), {
|
||||
name: 'Fake Bitstream',
|
||||
bundleName: 'ORIGINAL',
|
||||
description: 'Description',
|
||||
format: createMockRDObs(format)
|
||||
format: createSuccessfulRemoteDataObject$(format)
|
||||
});
|
||||
const fieldUpdate = {
|
||||
field: bitstream,
|
||||
|
@@ -6,7 +6,7 @@ import { ObjectUpdatesService } from '../../../../core/data/object-updates/objec
|
||||
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../../core/shared/operators';
|
||||
import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes';
|
||||
import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service';
|
||||
|
||||
@@ -74,7 +74,7 @@ export class ItemEditBitstreamComponent implements OnChanges, OnInit {
|
||||
this.bitstream = cloneDeep(this.fieldUpdate.field) as Bitstream;
|
||||
this.bitstreamName = this.dsoNameService.getName(this.bitstream);
|
||||
this.format$ = this.bitstream.format.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload()
|
||||
);
|
||||
}
|
||||
|
@@ -12,11 +12,9 @@ import { SortDirection, SortOptions } from '../../../core/cache/models/sort-opti
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
||||
import { SearchService } from '../../../core/shared/search/search.service';
|
||||
import { ErrorComponent } from '../../../shared/error/error.component';
|
||||
@@ -38,6 +36,12 @@ import { SearchServiceStub } from '../../../shared/testing/search-service.stub';
|
||||
import { EnumKeysPipe } from '../../../shared/utils/enum-keys-pipe';
|
||||
import { VarDirective } from '../../../shared/utils/var.directive';
|
||||
import { ItemCollectionMapperComponent } from './item-collection-mapper.component';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
|
||||
describe('ItemCollectionMapperComponent', () => {
|
||||
let comp: ItemCollectionMapperComponent;
|
||||
@@ -55,7 +59,7 @@ describe('ItemCollectionMapperComponent', () => {
|
||||
id: '932c7d50-d85a-44cb-b9dc-b427b12877bd',
|
||||
name: 'test-item'
|
||||
});
|
||||
const mockItemRD: RemoteData<Item> = new RemoteData<Item>(false, false, true, null, mockItem);
|
||||
const mockItemRD: RemoteData<Item> = createSuccessfulRemoteDataObject(mockItem);
|
||||
const mockSearchOptions = of(new PaginatedSearchOptions({
|
||||
pagination: Object.assign(new PaginationComponentOptions(), {
|
||||
id: 'search-page-configuration',
|
||||
@@ -74,10 +78,10 @@ describe('ItemCollectionMapperComponent', () => {
|
||||
const searchConfigServiceStub = {
|
||||
paginatedSearchOptions: mockSearchOptions
|
||||
};
|
||||
const mockCollectionsRD = new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []));
|
||||
const mockCollectionsRD = createSuccessfulRemoteDataObject(createPaginatedList([]));
|
||||
const itemDataServiceStub = {
|
||||
mapToCollection: () => of(new RestResponse(true, 200, 'OK')),
|
||||
removeMappingFromCollection: () => of(new RestResponse(true, 200, 'OK')),
|
||||
mapToCollection: () => createSuccessfulRemoteDataObject$({}),
|
||||
removeMappingFromCollection: () => createSuccessfulRemoteDataObject$({}),
|
||||
getMappedCollections: () => of(mockCollectionsRD),
|
||||
/* tslint:disable:no-empty */
|
||||
clearMappedCollectionsRequests: () => {}
|
||||
@@ -143,7 +147,7 @@ describe('ItemCollectionMapperComponent', () => {
|
||||
});
|
||||
|
||||
it('should display an error message if at least one mapping was unsuccessful', () => {
|
||||
spyOn(itemDataService, 'mapToCollection').and.returnValue(of(new RestResponse(false, 404, 'Not Found')));
|
||||
spyOn(itemDataService, 'mapToCollection').and.returnValue(createFailedRemoteDataObject$('Not Found', 404));
|
||||
comp.mapCollections(ids);
|
||||
expect(notificationsService.success).not.toHaveBeenCalled();
|
||||
expect(notificationsService.error).toHaveBeenCalled();
|
||||
@@ -160,7 +164,7 @@ describe('ItemCollectionMapperComponent', () => {
|
||||
});
|
||||
|
||||
it('should display an error message if the removal of at least one mapping was unsuccessful', () => {
|
||||
spyOn(itemDataService, 'removeMappingFromCollection').and.returnValue(of(new RestResponse(false, 404, 'Not Found')));
|
||||
spyOn(itemDataService, 'removeMappingFromCollection').and.returnValue(createFailedRemoteDataObject$('Not Found', 404));
|
||||
comp.removeMappings(ids);
|
||||
expect(notificationsService.success).not.toHaveBeenCalled();
|
||||
expect(notificationsService.error).toHaveBeenCalled();
|
||||
|
@@ -4,13 +4,13 @@ import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/
|
||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||
import { fadeIn, fadeInOut } from '../../../shared/animations/fade';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import {
|
||||
getFirstSucceededRemoteDataPayload,
|
||||
getRemoteDataPayload,
|
||||
getSucceededRemoteData,
|
||||
getFirstSucceededRemoteData,
|
||||
toDSpaceObjectListRD
|
||||
} from '../../../core/shared/operators';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
@@ -20,11 +20,11 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model';
|
||||
import { isNotEmpty } from '../../../shared/empty.util';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model';
|
||||
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
||||
import { SearchService } from '../../../core/shared/search/search.service';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-collection-mapper',
|
||||
@@ -92,7 +92,7 @@ export class ItemCollectionMapperComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.itemRD$ = this.route.data.pipe(map((data) => data.dso)).pipe(getSucceededRemoteData()) as Observable<RemoteData<Item>>;
|
||||
this.itemRD$ = this.route.data.pipe(map((data) => data.dso)).pipe(getFirstSucceededRemoteData()) as Observable<RemoteData<Item>>;
|
||||
this.searchOptions$ = this.searchConfigService.paginatedSearchOptions;
|
||||
this.loadCollectionLists();
|
||||
}
|
||||
@@ -141,13 +141,13 @@ export class ItemCollectionMapperComponent implements OnInit {
|
||||
mapCollections(ids: string[]) {
|
||||
const itemIdAndExcludingIds$ = observableCombineLatest(
|
||||
this.itemRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
take(1),
|
||||
map((rd: RemoteData<Item>) => rd.payload),
|
||||
map((item: Item) => item.id)
|
||||
),
|
||||
this.itemCollectionsRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
take(1),
|
||||
map((rd: RemoteData<PaginatedList<Collection>>) => rd.payload.page),
|
||||
map((collections: Collection[]) => collections.map((collection: Collection) => collection.id))
|
||||
@@ -168,7 +168,7 @@ export class ItemCollectionMapperComponent implements OnInit {
|
||||
*/
|
||||
removeMappings(ids: string[]) {
|
||||
const responses$ = this.itemRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
map((itemRD: RemoteData<Item>) => itemRD.payload.id),
|
||||
switchMap((itemId: string) => observableCombineLatest(ids.map((id: string) => this.itemDataService.removeMappingFromCollection(itemId, id))))
|
||||
);
|
||||
@@ -191,10 +191,10 @@ export class ItemCollectionMapperComponent implements OnInit {
|
||||
* @param {Observable<RestResponse[]>} responses$ The responses after adding/removing a mapping
|
||||
* @param {string} messagePrefix The prefix to build the notification messages with
|
||||
*/
|
||||
private showNotifications(responses$: Observable<RestResponse[]>, messagePrefix: string) {
|
||||
responses$.subscribe((responses: RestResponse[]) => {
|
||||
const successful = responses.filter((response: RestResponse) => response.isSuccessful);
|
||||
const unsuccessful = responses.filter((response: RestResponse) => !response.isSuccessful);
|
||||
private showNotifications(responses$: Observable<Array<RemoteData<NoContent>>>, messagePrefix: string) {
|
||||
responses$.subscribe((responses: Array<RemoteData<NoContent>>) => {
|
||||
const successful = responses.filter((response: RemoteData<NoContent>) => response.hasSucceeded);
|
||||
const unsuccessful = responses.filter((response: RemoteData<NoContent>) => response.hasFailed);
|
||||
if (successful.length > 0) {
|
||||
const successMessages = observableCombineLatest(
|
||||
this.translateService.get(`${messagePrefix}.success.head`),
|
||||
@@ -280,7 +280,7 @@ export class ItemCollectionMapperComponent implements OnInit {
|
||||
*/
|
||||
onCancel() {
|
||||
this.itemRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
take(1)
|
||||
).subscribe((item: Item) => {
|
||||
|
@@ -16,16 +16,17 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ItemDeleteComponent } from './item-delete.component';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils';
|
||||
import {
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/remote-data.utils';
|
||||
import { VarDirective } from '../../../shared/utils/var.directive';
|
||||
import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service';
|
||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
||||
import { RelationshipType } from '../../../core/shared/item-relationships/relationship-type.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { EntityTypeService } from '../../../core/data/entity-type.service';
|
||||
import { getItemEditRoute } from '../../item-page-routing-paths';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
|
||||
let comp: ItemDeleteComponent;
|
||||
let fixture: ComponentFixture<ItemDeleteComponent>;
|
||||
@@ -78,52 +79,16 @@ describe('ItemDeleteComponent', () => {
|
||||
Object.assign(new Relationship(), {
|
||||
id: '1',
|
||||
uuid: 'relationship-1',
|
||||
relationshipType: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
type1
|
||||
)),
|
||||
leftItem: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
mockItem,
|
||||
)),
|
||||
rightItem: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
Object.assign(new Item(), {})
|
||||
)),
|
||||
relationshipType: createSuccessfulRemoteDataObject$(type1),
|
||||
leftItem: createSuccessfulRemoteDataObject$(mockItem),
|
||||
rightItem: createSuccessfulRemoteDataObject$(new Item()),
|
||||
}),
|
||||
Object.assign(new Relationship(), {
|
||||
id: '2',
|
||||
uuid: 'relationship-2',
|
||||
relationshipType: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
type2
|
||||
)),
|
||||
leftItem: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
mockItem,
|
||||
)),
|
||||
rightItem: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
Object.assign(new Item(), {})
|
||||
)),
|
||||
relationshipType: createSuccessfulRemoteDataObject$(type2),
|
||||
leftItem: createSuccessfulRemoteDataObject$(mockItem),
|
||||
rightItem: createSuccessfulRemoteDataObject$(new Item()),
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -133,7 +98,7 @@ describe('ItemDeleteComponent', () => {
|
||||
});
|
||||
|
||||
mockItemDataService = jasmine.createSpyObj('mockItemDataService', {
|
||||
delete: observableOf(true)
|
||||
delete: createSuccessfulRemoteDataObject$({})
|
||||
});
|
||||
|
||||
routeStub = {
|
||||
@@ -149,20 +114,8 @@ describe('ItemDeleteComponent', () => {
|
||||
|
||||
entityTypeService = jasmine.createSpyObj('entityTypeService',
|
||||
{
|
||||
getEntityTypeByLabel: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
itemType,
|
||||
)),
|
||||
getEntityTypeRelationships: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
new PaginatedList(new PageInfo(), types),
|
||||
)),
|
||||
getEntityTypeByLabel: createSuccessfulRemoteDataObject$(itemType),
|
||||
getEntityTypeRelationships: createSuccessfulRemoteDataObject$(createPaginatedList(types)),
|
||||
}
|
||||
);
|
||||
|
||||
@@ -236,5 +189,4 @@ describe('ItemDeleteComponent', () => {
|
||||
expect(routerStub.navigate).toHaveBeenCalledWith([getItemEditRoute('fake-id')]);
|
||||
});
|
||||
});
|
||||
})
|
||||
;
|
||||
});
|
||||
|
@@ -1,12 +1,21 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { defaultIfEmpty, filter, first, map, switchMap, take } from 'rxjs/operators';
|
||||
import { defaultIfEmpty, filter, map, switchMap, take } from 'rxjs/operators';
|
||||
import { AbstractSimpleItemActionComponent } from '../simple-item-action/abstract-simple-item-action.component';
|
||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { combineLatest as observableCombineLatest, combineLatest, Observable, of as observableOf } from 'rxjs';
|
||||
import {
|
||||
combineLatest as observableCombineLatest,
|
||||
combineLatest,
|
||||
Observable,
|
||||
of as observableOf
|
||||
} from 'rxjs';
|
||||
import { RelationshipType } from '../../../core/shared/item-relationships/relationship-type.model';
|
||||
import { VirtualMetadata } from '../virtual-metadata/virtual-metadata.component';
|
||||
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import {
|
||||
getRemoteDataPayload,
|
||||
getFirstSucceededRemoteData,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../core/shared/operators';
|
||||
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { MetadataValue } from '../../../core/shared/metadata.models';
|
||||
@@ -20,8 +29,9 @@ import { RelationshipService } from '../../../core/data/relationship.service';
|
||||
import { EntityTypeService } from '../../../core/data/entity-type.service';
|
||||
import { LinkService } from '../../../core/cache/builders/link.service';
|
||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { getItemEditRoute } from '../../item-page-routing-paths';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-delete',
|
||||
@@ -105,10 +115,10 @@ export class ItemDeleteComponent
|
||||
const label = this.item.firstMetadataValue('relationship.type');
|
||||
if (label !== undefined) {
|
||||
this.types$ = this.entityTypeService.getEntityTypeByLabel(label).pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
switchMap((entityType) => this.entityTypeService.getEntityTypeRelationships(entityType.id)),
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
map((relationshipTypes) => relationshipTypes.page),
|
||||
switchMap((types) =>
|
||||
@@ -220,7 +230,7 @@ export class ItemDeleteComponent
|
||||
followLink('rightItem'),
|
||||
);
|
||||
return relationship.relationshipType.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
filter((relationshipType: RelationshipType) => hasValue(relationshipType) && isNotEmpty(relationshipType.uuid))
|
||||
);
|
||||
@@ -238,7 +248,7 @@ export class ItemDeleteComponent
|
||||
relationship,
|
||||
this.isLeftItem(relationship).pipe(
|
||||
switchMap((isLeftItem) => isLeftItem ? relationship.rightItem : relationship.leftItem),
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
),
|
||||
);
|
||||
@@ -285,7 +295,7 @@ export class ItemDeleteComponent
|
||||
private isLeftItem(relationship: Relationship): Observable<boolean> {
|
||||
|
||||
return relationship.leftItem.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
filter((item: Item) => hasValue(item) && isNotEmpty(item.uuid)),
|
||||
map((leftItem) => leftItem.uuid === this.item.uuid)
|
||||
@@ -327,9 +337,9 @@ export class ItemDeleteComponent
|
||||
)
|
||||
),
|
||||
).subscribe((types) => {
|
||||
this.itemDataService.delete(this.item.id, types).pipe(first()).subscribe(
|
||||
(response: RestResponse) => {
|
||||
this.notify(response.isSuccessful);
|
||||
this.itemDataService.delete(this.item.id, types).pipe(getFirstCompletedRemoteData()).subscribe(
|
||||
(rd: RemoteData<NoContent>) => {
|
||||
this.notify(rd.hasSucceeded);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@@ -9,7 +9,7 @@ import { TestScheduler } from 'rxjs/testing';
|
||||
import { MetadataFieldDataService } from '../../../../core/data/metadata-field-data.service';
|
||||
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
||||
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { PaginatedList, buildPaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model';
|
||||
import { RegistryService } from '../../../../core/registry/registry.service';
|
||||
@@ -66,7 +66,7 @@ describe('EditInPlaceFieldComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
scheduler = getTestScheduler();
|
||||
|
||||
paginatedMetadataFields = new PaginatedList(undefined, [mdField1, mdField2, mdField3]);
|
||||
paginatedMetadataFields = buildPaginatedList(undefined, [mdField1, mdField2, mdField3]);
|
||||
|
||||
metadataFieldService = jasmine.createSpyObj({
|
||||
queryMetadataFields: createSuccessfulRemoteDataObject$(paginatedMetadataFields),
|
||||
@@ -221,7 +221,7 @@ describe('EditInPlaceFieldComponent', () => {
|
||||
}));
|
||||
|
||||
it('it should call queryMetadataFields on the metadataFieldService with the correct query', () => {
|
||||
expect(metadataFieldService.queryMetadataFields).toHaveBeenCalledWith(query, null, followLink('schema'));
|
||||
expect(metadataFieldService.queryMetadataFields).toHaveBeenCalledWith(query, null, false, followLink('schema'));
|
||||
});
|
||||
|
||||
it('it should set metadataFieldSuggestions to the right value', () => {
|
||||
|
@@ -1,10 +1,13 @@
|
||||
import { Component, Input, OnChanges, OnInit } from '@angular/core';
|
||||
import { metadataFieldsToString } from '../../../../core/shared/operators';
|
||||
import {
|
||||
metadataFieldsToString,
|
||||
getFirstSucceededRemoteData
|
||||
} from '../../../../core/shared/operators';
|
||||
import { hasValue, isNotEmpty } from '../../../../shared/empty.util';
|
||||
import { RegistryService } from '../../../../core/registry/registry.service';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { BehaviorSubject, Observable, of as observableOf } from 'rxjs';
|
||||
import { map, take } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
||||
import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer';
|
||||
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
||||
@@ -124,10 +127,10 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
||||
*/
|
||||
findMetadataFieldSuggestions(query: string) {
|
||||
if (isNotEmpty(query)) {
|
||||
return this.registryService.queryMetadataFields(query, null, followLink('schema')).pipe(
|
||||
return this.registryService.queryMetadataFields(query, null, false, followLink('schema')).pipe(
|
||||
getFirstSucceededRemoteData(),
|
||||
metadataFieldsToString(),
|
||||
take(1))
|
||||
.subscribe((fieldNames: string[]) => {
|
||||
).subscribe((fieldNames: string[]) => {
|
||||
this.setInputSuggestions(fieldNames);
|
||||
})
|
||||
} else {
|
||||
|
@@ -21,7 +21,6 @@ import { Item } from '../../../core/shared/item.model';
|
||||
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions';
|
||||
import { MetadatumViewModel } from '../../../core/shared/metadata.models';
|
||||
import { RegistryService } from '../../../core/registry/registry.service';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
import {
|
||||
@@ -30,6 +29,7 @@ import {
|
||||
} from '../../../shared/remote-data.utils';
|
||||
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
|
||||
import { DSOSuccessResponse } from '../../../core/cache/response.models';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
|
||||
let comp: any;
|
||||
let fixture: ComponentFixture<ItemMetadataComponent>;
|
||||
@@ -133,7 +133,7 @@ describe('ItemMetadataComponent', () => {
|
||||
data: observableOf({ dso: createSuccessfulRemoteDataObject(item) })
|
||||
}
|
||||
};
|
||||
paginatedMetadataFields = new PaginatedList(undefined, [mdField1, mdField2, mdField3]);
|
||||
paginatedMetadataFields = createPaginatedList([mdField1, mdField2, mdField3]);
|
||||
|
||||
metadataFieldService = jasmine.createSpyObj({
|
||||
getAllMetadataFields: createSuccessfulRemoteDataObject$(paginatedMetadataFields)
|
||||
|
@@ -4,19 +4,18 @@ import { ItemDataService } from '../../../core/data/item-data.service';
|
||||
import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { first, switchMap, tap } from 'rxjs/operators';
|
||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { first, switchMap } from 'rxjs/operators';
|
||||
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MetadataValue, MetadatumViewModel } from '../../../core/shared/metadata.models';
|
||||
import { AbstractItemUpdateComponent } from '../abstract-item-update/abstract-item-update.component';
|
||||
import { UpdateDataService } from '../../../core/data/update-data.service';
|
||||
import { hasNoValue, hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { hasNoValue, hasValue } from '../../../shared/empty.util';
|
||||
import { AlertType } from '../../../shared/alert/aletr-type';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { METADATA_PATCH_OPERATION_SERVICE_TOKEN } from '../../../core/data/object-updates/patch-operation-service/metadata-patch-operation.service';
|
||||
import { DSOSuccessResponse, ErrorResponse } from '../../../core/cache/response.models';
|
||||
import { MetadataPatchOperationService } from '../../../core/data/object-updates/patch-operation-service/metadata-patch-operation.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-metadata',
|
||||
@@ -87,7 +86,7 @@ export class ItemMetadataComponent extends AbstractItemUpdateComponent {
|
||||
* Sends all initial values of this item to the object updates service
|
||||
*/
|
||||
public initializeOriginalFields() {
|
||||
this.objectUpdatesService.initialize(this.url, this.item.metadataAsList, this.item.lastModified, METADATA_PATCH_OPERATION_SERVICE_TOKEN);
|
||||
this.objectUpdatesService.initialize(this.url, this.item.metadataAsList, this.item.lastModified, MetadataPatchOperationService);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,27 +100,21 @@ export class ItemMetadataComponent extends AbstractItemUpdateComponent {
|
||||
first(),
|
||||
switchMap((patch: Operation[]) => {
|
||||
return this.updateService.patch(this.item, patch).pipe(
|
||||
tap((response) => {
|
||||
if (!response.isSuccessful) {
|
||||
this.notificationsService.error(this.getNotificationTitle('error'), (response as ErrorResponse).errorMessage);
|
||||
}
|
||||
}),
|
||||
switchMap((response: DSOSuccessResponse) => {
|
||||
if (isNotEmpty(response.resourceSelfLinks)) {
|
||||
return this.itemService.findByHref(response.resourceSelfLinks[0]);
|
||||
}
|
||||
}),
|
||||
getSucceededRemoteData()
|
||||
getFirstCompletedRemoteData()
|
||||
);
|
||||
})
|
||||
).subscribe(
|
||||
(rd: RemoteData<Item>) => {
|
||||
if (rd.hasFailed) {
|
||||
this.notificationsService.error(this.getNotificationTitle('error'), rd.errorMessage);
|
||||
} else {
|
||||
this.item = rd.payload;
|
||||
this.checkAndFixMetadataUUIDs();
|
||||
this.initializeOriginalFields();
|
||||
this.updates$ = this.objectUpdatesService.getFieldUpdates(this.url, this.item.metadataAsList);
|
||||
this.notificationsService.success(this.getNotificationTitle('saved'), this.getNotificationContent('saved'));
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
this.notificationsService.error(this.getNotificationTitle('invalid'), this.getNotificationContent('invalid'));
|
||||
|
@@ -7,10 +7,7 @@ import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { SearchService } from '../../../core/shared/search/search.service';
|
||||
@@ -18,6 +15,12 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { ItemMoveComponent } from './item-move.component';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
|
||||
describe('ItemMoveComponent', () => {
|
||||
let comp: ItemMoveComponent;
|
||||
@@ -34,22 +37,6 @@ describe('ItemMoveComponent', () => {
|
||||
url: `${itemPageUrl}/edit`
|
||||
});
|
||||
|
||||
const mockItemDataService = jasmine.createSpyObj({
|
||||
moveToCollection: observableOf(new RestResponse(true, 200, 'Success'))
|
||||
});
|
||||
|
||||
const mockItemDataServiceFail = jasmine.createSpyObj({
|
||||
moveToCollection: observableOf(new RestResponse(false, 500, 'Internal server error'))
|
||||
});
|
||||
|
||||
const routeStub = {
|
||||
data: observableOf({
|
||||
dso: new RemoteData(false, false, true, null, {
|
||||
id: 'item1'
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
const collection1 = Object.assign(new Collection(), {
|
||||
uuid: 'collection-uuid-1',
|
||||
name: 'Test collection 1'
|
||||
@@ -60,10 +47,25 @@ describe('ItemMoveComponent', () => {
|
||||
name: 'Test collection 2'
|
||||
});
|
||||
|
||||
const mockItemDataService = jasmine.createSpyObj({
|
||||
moveToCollection: createSuccessfulRemoteDataObject$(collection1)
|
||||
});
|
||||
|
||||
const mockItemDataServiceFail = jasmine.createSpyObj({
|
||||
moveToCollection: createFailedRemoteDataObject$('Internal server error', 500)
|
||||
});
|
||||
|
||||
const routeStub = {
|
||||
data: observableOf({
|
||||
dso: createSuccessfulRemoteDataObject({
|
||||
id: 'item1'
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
const mockSearchService = {
|
||||
search: () => {
|
||||
return observableOf(new RemoteData(false, false, true, null,
|
||||
new PaginatedList(null, [
|
||||
return createSuccessfulRemoteDataObject$(createPaginatedList([
|
||||
{
|
||||
indexableObject: collection1,
|
||||
hitHighlights: {}
|
||||
@@ -71,7 +73,7 @@ describe('ItemMoveComponent', () => {
|
||||
indexableObject: collection2,
|
||||
hitHighlights: {}
|
||||
}
|
||||
])));
|
||||
]));
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -3,15 +3,17 @@ import { first, map } from 'rxjs/operators';
|
||||
import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import {
|
||||
getFirstSucceededRemoteData,
|
||||
getFirstCompletedRemoteData
|
||||
} from '../../../core/shared/operators';
|
||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { Collection } from '../../../core/shared/collection.model';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { SearchService } from '../../../core/shared/search/search.service';
|
||||
@@ -55,7 +57,7 @@ export class ItemMoveComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.itemRD$ = this.route.data.pipe(map((data) => data.dso), getSucceededRemoteData()) as Observable<RemoteData<Item>>;
|
||||
this.itemRD$ = this.route.data.pipe(map((data) => data.dso), getFirstSucceededRemoteData()) as Observable<RemoteData<Item>>;
|
||||
this.itemRD$.subscribe((rd) => {
|
||||
this.itemId = rd.payload.id;
|
||||
}
|
||||
@@ -114,10 +116,10 @@ export class ItemMoveComponent implements OnInit {
|
||||
*/
|
||||
moveCollection() {
|
||||
this.processing = true;
|
||||
this.itemDataService.moveToCollection(this.itemId, this.selectedCollection).pipe(first()).subscribe(
|
||||
(response: RestResponse) => {
|
||||
this.itemDataService.moveToCollection(this.itemId, this.selectedCollection).pipe(getFirstCompletedRemoteData()).subscribe(
|
||||
(response: RemoteData<Collection>) => {
|
||||
this.router.navigate([getItemEditRoute(this.itemId)]);
|
||||
if (response.isSuccessful) {
|
||||
if (response.hasSucceeded) {
|
||||
this.notificationsService.success(this.translateService.get('item.edit.move.success'));
|
||||
} else {
|
||||
this.notificationsService.error(this.translateService.get('item.edit.move.error'));
|
||||
|
@@ -2,7 +2,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
@@ -16,7 +15,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ItemPrivateComponent } from './item-private.component';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
|
||||
let comp: ItemPrivateComponent;
|
||||
let fixture: ComponentFixture<ItemPrivateComponent>;
|
||||
@@ -46,14 +45,12 @@ describe('ItemPrivateComponent', () => {
|
||||
});
|
||||
|
||||
mockItemDataService = jasmine.createSpyObj('mockItemDataService', {
|
||||
setDiscoverable: observableOf(new RestResponse(true, 200, 'OK'))
|
||||
setDiscoverable: createSuccessfulRemoteDataObject$(mockItem)
|
||||
});
|
||||
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
dso: createSuccessfulRemoteDataObject({
|
||||
id: 'fake-id'
|
||||
})
|
||||
dso: createSuccessfulRemoteDataObject(mockItem)
|
||||
})
|
||||
};
|
||||
|
||||
@@ -98,9 +95,8 @@ describe('ItemPrivateComponent', () => {
|
||||
spyOn(comp, 'processRestResponse');
|
||||
comp.performAction();
|
||||
|
||||
expect(mockItemDataService.setDiscoverable).toHaveBeenCalledWith(mockItem.id, false);
|
||||
expect(mockItemDataService.setDiscoverable).toHaveBeenCalledWith(mockItem, false);
|
||||
expect(comp.processRestResponse).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
})
|
||||
;
|
||||
});
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { AbstractSimpleItemActionComponent } from '../simple-item-action/abstract-simple-item-action.component';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-private',
|
||||
@@ -21,9 +20,9 @@ export class ItemPrivateComponent extends AbstractSimpleItemActionComponent {
|
||||
* Perform the make private action to the item
|
||||
*/
|
||||
performAction() {
|
||||
this.itemDataService.setDiscoverable(this.item.id, false).pipe(first()).subscribe(
|
||||
(response: RestResponse) => {
|
||||
this.processRestResponse(response);
|
||||
this.itemDataService.setDiscoverable(this.item, false).pipe(getFirstCompletedRemoteData()).subscribe(
|
||||
(rd: RemoteData<Item>) => {
|
||||
this.processRestResponse(rd);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
@@ -15,8 +14,7 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ItemPublicComponent } from './item-public.component';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
|
||||
let comp: ItemPublicComponent;
|
||||
let fixture: ComponentFixture<ItemPublicComponent>;
|
||||
@@ -27,8 +25,6 @@ let routerStub;
|
||||
let mockItemDataService: ItemDataService;
|
||||
let routeStub;
|
||||
let notificationsServiceStub;
|
||||
let successfulRestResponse;
|
||||
let failRestResponse;
|
||||
|
||||
describe('ItemPublicComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
@@ -46,14 +42,12 @@ describe('ItemPublicComponent', () => {
|
||||
});
|
||||
|
||||
mockItemDataService = jasmine.createSpyObj('mockItemDataService', {
|
||||
setDiscoverable: observableOf(new RestResponse(true, 200, 'OK'))
|
||||
setDiscoverable: createSuccessfulRemoteDataObject$(mockItem)
|
||||
});
|
||||
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
dso: createSuccessfulRemoteDataObject({
|
||||
id: 'fake-id'
|
||||
})
|
||||
dso: createSuccessfulRemoteDataObject(mockItem)
|
||||
})
|
||||
};
|
||||
|
||||
@@ -74,9 +68,6 @@ describe('ItemPublicComponent', () => {
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
successfulRestResponse = new RestResponse(true, 200, 'OK');
|
||||
failRestResponse = new RestResponse(false, 500, 'Internal Server Error');
|
||||
|
||||
fixture = TestBed.createComponent(ItemPublicComponent);
|
||||
comp = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
@@ -98,9 +89,8 @@ describe('ItemPublicComponent', () => {
|
||||
spyOn(comp, 'processRestResponse');
|
||||
comp.performAction();
|
||||
|
||||
expect(mockItemDataService.setDiscoverable).toHaveBeenCalledWith(mockItem.id, true);
|
||||
expect(mockItemDataService.setDiscoverable).toHaveBeenCalledWith(mockItem, true);
|
||||
expect(comp.processRestResponse).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
})
|
||||
;
|
||||
});
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { AbstractSimpleItemActionComponent } from '../simple-item-action/abstract-simple-item-action.component';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-public',
|
||||
@@ -21,8 +20,8 @@ export class ItemPublicComponent extends AbstractSimpleItemActionComponent {
|
||||
* Perform the make public action to the item
|
||||
*/
|
||||
performAction() {
|
||||
this.itemDataService.setDiscoverable(this.item.id, true).pipe(first()).subscribe(
|
||||
(response: RestResponse) => {
|
||||
this.itemDataService.setDiscoverable(this.item, true).pipe(getFirstCompletedRemoteData()).subscribe(
|
||||
(response: RemoteData<Item>) => {
|
||||
this.processRestResponse(response);
|
||||
}
|
||||
);
|
||||
|
@@ -2,7 +2,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
@@ -15,8 +14,10 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ItemReinstateComponent } from './item-reinstate.component';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils';
|
||||
import {
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/remote-data.utils';
|
||||
|
||||
let comp: ItemReinstateComponent;
|
||||
let fixture: ComponentFixture<ItemReinstateComponent>;
|
||||
@@ -27,8 +28,6 @@ let routerStub;
|
||||
let mockItemDataService: ItemDataService;
|
||||
let routeStub;
|
||||
let notificationsServiceStub;
|
||||
let successfulRestResponse;
|
||||
let failRestResponse;
|
||||
|
||||
describe('ItemReinstateComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
@@ -46,7 +45,7 @@ describe('ItemReinstateComponent', () => {
|
||||
});
|
||||
|
||||
mockItemDataService = jasmine.createSpyObj('mockItemDataService', {
|
||||
setWithDrawn: observableOf(new RestResponse(true, 200, 'OK'))
|
||||
setWithDrawn: createSuccessfulRemoteDataObject$(mockItem)
|
||||
});
|
||||
|
||||
routeStub = {
|
||||
@@ -74,9 +73,6 @@ describe('ItemReinstateComponent', () => {
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
successfulRestResponse = new RestResponse(true, 200, 'OK');
|
||||
failRestResponse = new RestResponse(false, 500, 'Internal Server Error');
|
||||
|
||||
fixture = TestBed.createComponent(ItemReinstateComponent);
|
||||
comp = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
@@ -98,9 +94,8 @@ describe('ItemReinstateComponent', () => {
|
||||
spyOn(comp, 'processRestResponse');
|
||||
comp.performAction();
|
||||
|
||||
expect(mockItemDataService.setWithDrawn).toHaveBeenCalledWith(mockItem.id, false);
|
||||
expect(mockItemDataService.setWithDrawn).toHaveBeenCalledWith(comp.item, false);
|
||||
expect(comp.processRestResponse).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
})
|
||||
;
|
||||
});
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { AbstractSimpleItemActionComponent } from '../simple-item-action/abstract-simple-item-action.component';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-reinstate',
|
||||
@@ -21,8 +20,8 @@ export class ItemReinstateComponent extends AbstractSimpleItemActionComponent {
|
||||
* Perform the reinstate action to the item
|
||||
*/
|
||||
performAction() {
|
||||
this.itemDataService.setWithDrawn(this.item.id, false).pipe(first()).subscribe(
|
||||
(response: RestResponse) => {
|
||||
this.itemDataService.setWithDrawn(this.item, false).pipe(getFirstCompletedRemoteData()).subscribe(
|
||||
(response: RemoteData<Item>) => {
|
||||
this.processRestResponse(response);
|
||||
}
|
||||
);
|
||||
|
@@ -6,19 +6,16 @@ import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
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 { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { RelationshipTypeService } from '../../../../core/data/relationship-type.service';
|
||||
import { RelationshipService } from '../../../../core/data/relationship.service';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { ItemType } from '../../../../core/shared/item-relationships/item-type.model';
|
||||
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
||||
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { getMockLinkService } from '../../../../shared/mocks/link-service.mock';
|
||||
import { SelectableListService } from '../../../../shared/object-list/selectable-list/selectable-list.service';
|
||||
import { SharedModule } from '../../../../shared/shared.module';
|
||||
import { EditRelationshipListComponent } from './edit-relationship-list.component';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../../shared/testing/utils.test';
|
||||
|
||||
let comp: EditRelationshipListComponent;
|
||||
let fixture: ComponentFixture<EditRelationshipListComponent>;
|
||||
@@ -60,20 +57,8 @@ describe('EditRelationshipListComponent', () => {
|
||||
relationshipType = Object.assign(new RelationshipType(), {
|
||||
id: '1',
|
||||
uuid: '1',
|
||||
leftType: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
entityType,
|
||||
)),
|
||||
rightType: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
relatedEntityType,
|
||||
)),
|
||||
leftType: createSuccessfulRemoteDataObject$(entityType),
|
||||
rightType: createSuccessfulRemoteDataObject$(relatedEntityType),
|
||||
leftwardType: 'isAuthorOfPublication',
|
||||
rightwardType: 'isPublicationOfAuthor',
|
||||
});
|
||||
@@ -92,53 +77,17 @@ describe('EditRelationshipListComponent', () => {
|
||||
self: url + '/2',
|
||||
id: '2',
|
||||
uuid: '2',
|
||||
relationshipType: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
relationshipType
|
||||
)),
|
||||
leftItem: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
item,
|
||||
)),
|
||||
rightItem: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
author1,
|
||||
)),
|
||||
relationshipType: createSuccessfulRemoteDataObject$(relationshipType),
|
||||
leftItem: createSuccessfulRemoteDataObject$(item),
|
||||
rightItem: createSuccessfulRemoteDataObject$(author1),
|
||||
}),
|
||||
Object.assign(new Relationship(), {
|
||||
self: url + '/3',
|
||||
id: '3',
|
||||
uuid: '3',
|
||||
relationshipType: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
relationshipType
|
||||
)),
|
||||
leftItem: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
item,
|
||||
)),
|
||||
rightItem: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
author2,
|
||||
)),
|
||||
relationshipType: createSuccessfulRemoteDataObject$(relationshipType),
|
||||
leftItem: createSuccessfulRemoteDataObject$(item),
|
||||
rightItem: createSuccessfulRemoteDataObject$(author2),
|
||||
})
|
||||
];
|
||||
|
||||
@@ -148,13 +97,7 @@ describe('EditRelationshipListComponent', () => {
|
||||
},
|
||||
id: 'publication',
|
||||
uuid: 'publication',
|
||||
relationships: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
undefined,
|
||||
new PaginatedList(new PageInfo(), relationships),
|
||||
))
|
||||
relationships: createSuccessfulRemoteDataObject$(createPaginatedList(relationships))
|
||||
});
|
||||
|
||||
fieldUpdate1 = {
|
||||
@@ -185,8 +128,8 @@ describe('EditRelationshipListComponent', () => {
|
||||
|
||||
relationshipService = jasmine.createSpyObj('relationshipService',
|
||||
{
|
||||
getRelatedItemsByLabel: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), [author1, author2]))),
|
||||
getItemRelationshipsByLabel: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), relationships))),
|
||||
getRelatedItemsByLabel: createSuccessfulRemoteDataObject$(createPaginatedList([author1, author2])),
|
||||
getItemRelationshipsByLabel: createSuccessfulRemoteDataObject$(createPaginatedList(relationships)),
|
||||
isLeftItem: observableOf(true),
|
||||
}
|
||||
);
|
||||
|
@@ -11,19 +11,14 @@ import {
|
||||
} from '../../../../core/data/object-updates/object-updates.reducer';
|
||||
import { RelationshipService } from '../../../../core/data/relationship.service';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import {
|
||||
defaultIfEmpty, filter, flatMap,
|
||||
map,
|
||||
switchMap,
|
||||
take, tap,
|
||||
} from 'rxjs/operators';
|
||||
import { hasValue } from '../../../../shared/empty.util';
|
||||
import { defaultIfEmpty, flatMap, map, switchMap, take, } from 'rxjs/operators';
|
||||
import { hasValue, hasValueOperator } from '../../../../shared/empty.util';
|
||||
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
||||
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
||||
import {
|
||||
getAllSucceededRemoteData,
|
||||
getRemoteDataPayload,
|
||||
getSucceededRemoteData
|
||||
getFirstSucceededRemoteData,
|
||||
} from '../../../../core/shared/operators';
|
||||
import { combineLatest as observableCombineLatest, of } from 'rxjs';
|
||||
import { ItemType } from '../../../../core/shared/item-relationships/item-type.model';
|
||||
@@ -33,6 +28,8 @@ import { ItemSearchResult } from '../../../../shared/object-collection/shared/it
|
||||
import { SelectableListService } from '../../../../shared/object-list/selectable-list/selectable-list.service';
|
||||
import { SearchResult } from '../../../../shared/search/search-result.model';
|
||||
import { followLink } from '../../../../shared/utils/follow-link-config.model';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-edit-relationship-list',
|
||||
@@ -121,10 +118,10 @@ export class EditRelationshipListComponent implements OnInit {
|
||||
this.relationshipType.leftType,
|
||||
this.relationshipType.rightType,
|
||||
].map((itemTypeRD) => itemTypeRD.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
))).pipe(
|
||||
map((itemTypes) => [
|
||||
map((itemTypes: ItemType[]) => [
|
||||
this.relationshipType.leftwardType,
|
||||
this.relationshipType.rightwardType,
|
||||
][itemTypes.findIndex((itemType) => itemType.id === this.itemType.id)]),
|
||||
@@ -259,9 +256,9 @@ export class EditRelationshipListComponent implements OnInit {
|
||||
private getRelatedItem(relationship: Relationship): Observable<Item> {
|
||||
return this.relationshipService.isLeftItem(relationship, this.item).pipe(
|
||||
switchMap((isLeftItem) => isLeftItem ? relationship.rightItem : relationship.leftItem),
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
)
|
||||
) as Observable<Item>
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -271,10 +268,11 @@ export class EditRelationshipListComponent implements OnInit {
|
||||
this.relationshipType.leftType,
|
||||
this.relationshipType.rightType,
|
||||
].map((type) => type.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
))).pipe(
|
||||
map((relatedTypes) => relatedTypes.find((relatedType) => relatedType.uuid !== this.itemType.uuid)),
|
||||
map((relatedTypes: ItemType[]) => relatedTypes.find((relatedType) => relatedType.uuid !== this.itemType.uuid)),
|
||||
hasValueOperator()
|
||||
);
|
||||
|
||||
this.relatedEntityType$.pipe(
|
||||
@@ -304,10 +302,12 @@ export class EditRelationshipListComponent implements OnInit {
|
||||
map((fieldUpdates) => {
|
||||
const fieldUpdatesFiltered: FieldUpdates = {};
|
||||
Object.keys(fieldUpdates).forEach((uuid) => {
|
||||
if (hasValue(fieldUpdates[uuid])) {
|
||||
const field = fieldUpdates[uuid].field;
|
||||
if ((field as RelationshipIdentifiable).type.id === this.relationshipType.id) {
|
||||
fieldUpdatesFiltered[uuid] = fieldUpdates[uuid];
|
||||
}
|
||||
}
|
||||
});
|
||||
return fieldUpdatesFiltered;
|
||||
}),
|
||||
@@ -316,26 +316,20 @@ export class EditRelationshipListComponent implements OnInit {
|
||||
}
|
||||
|
||||
private getItemRelationships() {
|
||||
this.linkService.resolveLink(this.item, followLink('relationships'));
|
||||
return this.item.relationships.pipe(
|
||||
getAllSucceededRemoteData(),
|
||||
map((relationships) => relationships.payload.page.filter((relationship) => relationship)),
|
||||
filter((relationships) => relationships.every((relationship) => !!relationship)),
|
||||
tap((relationships: Relationship[]) =>
|
||||
relationships.forEach((relationship: Relationship) => {
|
||||
this.linkService.resolveLinks(
|
||||
relationship,
|
||||
this.linkService.resolveLink(this.item,
|
||||
followLink('relationships', undefined, true,
|
||||
followLink('relationshipType'),
|
||||
followLink('leftItem'),
|
||||
followLink('rightItem'),
|
||||
);
|
||||
})
|
||||
),
|
||||
));
|
||||
return this.item.relationships.pipe(
|
||||
getAllSucceededRemoteData(),
|
||||
map((relationships: RemoteData<PaginatedList<Relationship>>) => relationships.payload.page.filter((relationship: Relationship) => hasValue(relationship))),
|
||||
switchMap((itemRelationships: Relationship[]) =>
|
||||
observableCombineLatest(
|
||||
itemRelationships
|
||||
.map((relationship) => relationship.relationshipType.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
))
|
||||
).pipe(
|
||||
|
@@ -4,14 +4,13 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
||||
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
||||
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { EditRelationshipComponent } from './edit-relationship.component';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../../shared/testing/utils.test';
|
||||
|
||||
let objectUpdatesService;
|
||||
const url = 'http://test-url.com/test-url';
|
||||
@@ -49,7 +48,7 @@ describe('EditRelationshipComponent', () => {
|
||||
},
|
||||
id: 'publication',
|
||||
uuid: 'publication',
|
||||
relationships: observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(new PageInfo(), relationships)))
|
||||
relationships: createSuccessfulRemoteDataObject$(createPaginatedList(relationships))
|
||||
});
|
||||
|
||||
relatedItem = Object.assign(new Item(), {
|
||||
@@ -65,9 +64,9 @@ describe('EditRelationshipComponent', () => {
|
||||
uuid: '2',
|
||||
leftId: 'author1',
|
||||
rightId: 'publication',
|
||||
relationshipType: observableOf(new RemoteData(false, false, true, undefined, relationshipType)),
|
||||
leftItem: observableOf(new RemoteData(false, false, true, undefined, relatedItem)),
|
||||
rightItem: observableOf(new RemoteData(false, false, true, undefined, item)),
|
||||
relationshipType: createSuccessfulRemoteDataObject$(relationshipType),
|
||||
leftItem: createSuccessfulRemoteDataObject$(relatedItem),
|
||||
rightItem: createSuccessfulRemoteDataObject$(item),
|
||||
}),
|
||||
Object.assign(new Relationship(), {
|
||||
_links: {
|
||||
@@ -77,7 +76,7 @@ describe('EditRelationshipComponent', () => {
|
||||
uuid: '3',
|
||||
leftId: 'author2',
|
||||
rightId: 'publication',
|
||||
relationshipType: observableOf(new RemoteData(false, false, true, undefined, relationshipType))
|
||||
relationshipType: createSuccessfulRemoteDataObject$(relationshipType)
|
||||
})
|
||||
];
|
||||
|
||||
|
@@ -9,7 +9,7 @@ import {
|
||||
} from '../../../../core/data/object-updates/object-updates.reducer';
|
||||
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../../core/shared/operators';
|
||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||
import { hasValue, isNotEmpty } from '../../../../shared/empty.util';
|
||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||
@@ -81,12 +81,12 @@ export class EditRelationshipComponent implements OnChanges {
|
||||
ngOnChanges(): void {
|
||||
if (this.relationship) {
|
||||
this.leftItem$ = this.relationship.leftItem.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
filter((item: Item) => hasValue(item) && isNotEmpty(item.uuid))
|
||||
);
|
||||
this.rightItem$ = this.relationship.rightItem.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
filter((item: Item) => hasValue(item) && isNotEmpty(item.uuid))
|
||||
);
|
||||
|
@@ -11,7 +11,6 @@ import { EntityTypeService } from '../../../core/data/entity-type.service';
|
||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions';
|
||||
import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
@@ -29,6 +28,8 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { SharedModule } from '../../../shared/shared.module';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { ItemRelationshipsComponent } from './item-relationships.component';
|
||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
|
||||
let comp: any;
|
||||
let fixture: ComponentFixture<ItemRelationshipsComponent>;
|
||||
@@ -84,7 +85,7 @@ describe('ItemRelationshipsComponent', () => {
|
||||
},
|
||||
id: '2',
|
||||
uuid: '2',
|
||||
relationshipType: observableOf(new RemoteData(false, false, true, undefined, relationshipType))
|
||||
relationshipType: createSuccessfulRemoteDataObject$(relationshipType)
|
||||
}),
|
||||
Object.assign(new Relationship(), {
|
||||
_links: {
|
||||
@@ -92,7 +93,7 @@ describe('ItemRelationshipsComponent', () => {
|
||||
},
|
||||
id: '3',
|
||||
uuid: '3',
|
||||
relationshipType: observableOf(new RemoteData(false, false, true, undefined, relationshipType))
|
||||
relationshipType: createSuccessfulRemoteDataObject$(relationshipType)
|
||||
})
|
||||
];
|
||||
|
||||
@@ -102,7 +103,7 @@ describe('ItemRelationshipsComponent', () => {
|
||||
},
|
||||
id: 'publication',
|
||||
uuid: 'publication',
|
||||
relationships: observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(new PageInfo(), relationships))),
|
||||
relationships: createSuccessfulRemoteDataObject$(createPaginatedList(relationships)),
|
||||
lastModified: date
|
||||
});
|
||||
|
||||
@@ -119,10 +120,10 @@ describe('ItemRelationshipsComponent', () => {
|
||||
uuid: 'author2'
|
||||
});
|
||||
|
||||
relationships[0].leftItem = observableOf(new RemoteData(false, false, true, undefined, author1));
|
||||
relationships[0].rightItem = observableOf(new RemoteData(false, false, true, undefined, item));
|
||||
relationships[1].leftItem = observableOf(new RemoteData(false, false, true, undefined, author2));
|
||||
relationships[1].rightItem = observableOf(new RemoteData(false, false, true, undefined, item));
|
||||
relationships[0].leftItem = createSuccessfulRemoteDataObject$(author1);
|
||||
relationships[0].rightItem = createSuccessfulRemoteDataObject$(item);
|
||||
relationships[1].leftItem = createSuccessfulRemoteDataObject$(author2);
|
||||
relationships[1].rightItem = createSuccessfulRemoteDataObject$(item);
|
||||
|
||||
fieldUpdate1 = {
|
||||
field: relationships[0],
|
||||
@@ -137,12 +138,12 @@ describe('ItemRelationshipsComponent', () => {
|
||||
};
|
||||
|
||||
itemService = jasmine.createSpyObj('itemService', {
|
||||
findById: observableOf(new RemoteData(false, false, true, undefined, item))
|
||||
findById: createSuccessfulRemoteDataObject$(item)
|
||||
});
|
||||
routeStub = {
|
||||
data: observableOf({}),
|
||||
parent: {
|
||||
data: observableOf({ dso: new RemoteData(false, false, true, null, item) })
|
||||
data: observableOf({ dso: createSuccessfulRemoteDataObject(item) })
|
||||
}
|
||||
};
|
||||
|
||||
@@ -184,7 +185,7 @@ describe('ItemRelationshipsComponent', () => {
|
||||
requestService = jasmine.createSpyObj('requestService',
|
||||
{
|
||||
removeByHrefSubstring: {},
|
||||
hasByHrefObservable: observableOf(false)
|
||||
hasByHref$: observableOf(false)
|
||||
}
|
||||
);
|
||||
|
||||
@@ -194,20 +195,8 @@ describe('ItemRelationshipsComponent', () => {
|
||||
|
||||
entityTypeService = jasmine.createSpyObj('entityTypeService',
|
||||
{
|
||||
getEntityTypeByLabel: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
entityType,
|
||||
)),
|
||||
getEntityTypeRelationships: observableOf(new RemoteData(
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
new PaginatedList(new PageInfo(), [relationshipType]),
|
||||
)),
|
||||
getEntityTypeByLabel: createSuccessfulRemoteDataObject$(entityType),
|
||||
getEntityTypeRelationships: createSuccessfulRemoteDataObject$(createPaginatedList([relationshipType])),
|
||||
}
|
||||
);
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectorRef, Component, Inject, OnDestroy } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component } from '@angular/core';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import {
|
||||
DeleteRelationship,
|
||||
@@ -8,7 +8,11 @@ import {
|
||||
} from '../../../core/data/object-updates/object-updates.reducer';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { filter, map, startWith, switchMap, take } from 'rxjs/operators';
|
||||
import { combineLatest as observableCombineLatest, of as observableOf, zip as observableZip} from 'rxjs';
|
||||
import {
|
||||
combineLatest as observableCombineLatest,
|
||||
of as observableOf,
|
||||
zip as observableZip
|
||||
} from 'rxjs';
|
||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||
import { AbstractItemUpdateComponent } from '../abstract-item-update/abstract-item-update.component';
|
||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||
@@ -17,16 +21,17 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
||||
import { ErrorResponse, RestResponse } from '../../../core/cache/response.models';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
import { RelationshipType } from '../../../core/shared/item-relationships/relationship-type.model';
|
||||
import { ItemType } from '../../../core/shared/item-relationships/item-type.model';
|
||||
import { EntityTypeService } from '../../../core/data/entity-type.service';
|
||||
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions';
|
||||
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
|
||||
import { NoContent } from '../../../core/shared/NoContent.model';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-relationships',
|
||||
@@ -78,10 +83,11 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
||||
* Update the item (and view) when it's removed in the request cache
|
||||
*/
|
||||
public initializeItemUpdate(): void {
|
||||
this.itemRD$ = this.requestService.hasByHrefObservable(this.item.self).pipe(
|
||||
this.itemRD$ = this.requestService.hasByHref$(this.item.self).pipe(
|
||||
filter((exists: boolean) => !exists),
|
||||
switchMap(() => this.itemService.findById(
|
||||
this.item.uuid,
|
||||
true,
|
||||
followLink('owningCollection'),
|
||||
followLink('bundles'),
|
||||
followLink('relationships')),
|
||||
@@ -90,7 +96,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
||||
);
|
||||
|
||||
this.itemRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
).subscribe((item) => {
|
||||
this.item = item;
|
||||
@@ -108,7 +114,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
||||
if (label !== undefined) {
|
||||
|
||||
this.entityType$ = this.entityTypeService.getEntityTypeByLabel(label).pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
);
|
||||
|
||||
@@ -119,7 +125,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
||||
followLink('leftType'),
|
||||
followLink('rightType'))
|
||||
.pipe(
|
||||
getSucceededRemoteData(),
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
map((relationshipTypes) => relationshipTypes.page),
|
||||
)
|
||||
@@ -162,6 +168,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
||||
const addRelatedItems$: Observable<RelationshipIdentifiable[]> = this.objectUpdatesService.getFieldUpdates(this.url, []).pipe(
|
||||
map((fieldUpdates: FieldUpdates) =>
|
||||
Object.values(fieldUpdates)
|
||||
.filter((fieldUpdate: FieldUpdate) => hasValue(fieldUpdate))
|
||||
.filter((fieldUpdate: FieldUpdate) => fieldUpdate.changeType === FieldChangeType.ADD)
|
||||
.map((fieldUpdate: FieldUpdate) => fieldUpdate.field as RelationshipIdentifiable)
|
||||
),
|
||||
@@ -191,7 +198,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
||||
});
|
||||
}
|
||||
|
||||
deleteRelationships(deleteRelationshipIDs: DeleteRelationship[]): Observable<RestResponse[]> {
|
||||
deleteRelationships(deleteRelationshipIDs: DeleteRelationship[]): Observable<Array<RemoteData<NoContent>>> {
|
||||
return observableZip(...deleteRelationshipIDs.map((deleteRelationship) => {
|
||||
let copyVirtualMetadata: string;
|
||||
if (deleteRelationship.keepLeftVirtualMetadata && deleteRelationship.keepRightVirtualMetadata) {
|
||||
@@ -208,7 +215,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
||||
));
|
||||
}
|
||||
|
||||
addRelationships(addRelatedItems: RelationshipIdentifiable[]): Observable<RestResponse[]> {
|
||||
addRelationships(addRelatedItems: RelationshipIdentifiable[]): Observable<Array<RemoteData<Relationship>>> {
|
||||
return observableZip(...addRelatedItems.map((addRelationship) =>
|
||||
this.entityType$.pipe(
|
||||
switchMap((entityType) => this.entityTypeService.isLeftType(addRelationship.type, entityType)),
|
||||
@@ -240,11 +247,11 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
||||
* - Success notification in case there's at least one successful response
|
||||
* @param responses
|
||||
*/
|
||||
displayNotifications(responses: RestResponse[]) {
|
||||
const failedResponses = responses.filter((response: RestResponse) => !response.isSuccessful);
|
||||
const successfulResponses = responses.filter((response: RestResponse) => response.isSuccessful);
|
||||
displayNotifications(responses: Array<RemoteData<NoContent>>) {
|
||||
const failedResponses = responses.filter((response: RemoteData<NoContent>) => response.hasFailed);
|
||||
const successfulResponses = responses.filter((response: RemoteData<NoContent>) => response.hasSucceeded);
|
||||
|
||||
failedResponses.forEach((response: ErrorResponse) => {
|
||||
failedResponses.forEach((response: RemoteData<NoContent>) => {
|
||||
this.notificationsService.error(this.getNotificationTitle('failed'), response.errorMessage);
|
||||
});
|
||||
if (successfulResponses.length > 0) {
|
||||
|
@@ -3,7 +3,7 @@ import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { getFirstSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AlertType } from '../../../shared/alert/aletr-type';
|
||||
|
||||
@@ -30,6 +30,6 @@ export class ItemVersionHistoryComponent {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.itemRD$ = this.route.parent.data.pipe(map((data) => data.dso)).pipe(getSucceededRemoteData()) as Observable<RemoteData<Item>>;
|
||||
this.itemRD$ = this.route.parent.data.pipe(map((data) => data.dso)).pipe(getFirstSucceededRemoteData()) as Observable<RemoteData<Item>>;
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user