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