mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
[CST-7757] Refactoring code
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<button *ngIf="isAuthorized$ | async"
|
<button *ngIf="isAuthorized$ | async" data-test="subscription-button"
|
||||||
(click)="openSubscriptionModal()"
|
(click)="openSubscriptionModal()"
|
||||||
[ngbTooltip]="'item.page.subscriptions.tooltip' | translate"
|
[ngbTooltip]="'item.page.subscriptions.tooltip' | translate"
|
||||||
class="subscription-button btn btn-dark btn-sm">
|
class="subscription-button btn btn-dark btn-sm">
|
||||||
|
@@ -1,14 +1,53 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { DsoPageSubscriptionButtonComponent } from './dso-page-subscription-button.component';
|
import { DsoPageSubscriptionButtonComponent } from './dso-page-subscription-button.component';
|
||||||
|
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
import { Item } from '../../../core/shared/item.model';
|
||||||
|
import { ITEM } from '../../../core/shared/item.resource-type';
|
||||||
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { TranslateLoaderMock } from '../../mocks/translate-loader.mock';
|
||||||
|
|
||||||
describe('DsoPageSubscriptionButtonComponent', () => {
|
describe('DsoPageSubscriptionButtonComponent', () => {
|
||||||
let component: DsoPageSubscriptionButtonComponent;
|
let component: DsoPageSubscriptionButtonComponent;
|
||||||
let fixture: ComponentFixture<DsoPageSubscriptionButtonComponent>;
|
let fixture: ComponentFixture<DsoPageSubscriptionButtonComponent>;
|
||||||
|
let de: DebugElement;
|
||||||
|
|
||||||
|
const authorizationService = jasmine.createSpyObj('authorizationService', {
|
||||||
|
isAuthorized: jasmine.createSpy('isAuthorized') // observableOf(true)
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockItem = Object.assign(new Item(), {
|
||||||
|
id: 'fake-id',
|
||||||
|
uuid: 'fake-id',
|
||||||
|
handle: 'fake/handle',
|
||||||
|
lastModified: '2018',
|
||||||
|
type: ITEM,
|
||||||
|
_links: {
|
||||||
|
self: {
|
||||||
|
href: 'https://localhost:8000/items/fake-id'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [ DsoPageSubscriptionButtonComponent ]
|
imports: [
|
||||||
|
NgbModalModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useClass: TranslateLoaderMock
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
declarations: [ DsoPageSubscriptionButtonComponent ],
|
||||||
|
providers: [
|
||||||
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
});
|
});
|
||||||
@@ -16,10 +55,29 @@ describe('DsoPageSubscriptionButtonComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DsoPageSubscriptionButtonComponent);
|
fixture = TestBed.createComponent(DsoPageSubscriptionButtonComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
de = fixture.debugElement;
|
||||||
|
component.dso = mockItem;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create', () => {
|
describe('when is authorized', () => {
|
||||||
expect(component).toBeTruthy();
|
beforeEach(() => {
|
||||||
|
authorizationService.isAuthorized.and.returnValue(observableOf(true))
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display subscription button', () => {
|
||||||
|
expect(de.query(By.css(' [data-test="subscription-button"]'))).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when is not authorized', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
authorizationService.isAuthorized.and.returnValue(observableOf(false))
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not display subscription button', () => {
|
||||||
|
expect(de.query(By.css(' [data-test="subscription-button"]'))).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -3,12 +3,7 @@ import { Observable, of } from 'rxjs';
|
|||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { AuthService } from '../../../core/auth/auth.service';
|
import { SubscriptionModalComponent } from '../../subscriptions/subscription-modal/subscription-modal.component';
|
||||||
import { EPerson } from '../../../core/eperson/models/eperson.model';
|
|
||||||
import { take } from 'rxjs/operators';
|
|
||||||
import {
|
|
||||||
SubscriptionModalComponent
|
|
||||||
} from '../../subscriptions/components/subscription-modal/subscription-modal.component';
|
|
||||||
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@@ -1,44 +0,0 @@
|
|||||||
<div class="modal-header">
|
|
||||||
<h4 class="modal-title">{{'item.page.subscriptions.modal.title' | translate}}</h4>
|
|
||||||
<button type="button" class="close" aria-label="Close" (click)="c('cancel')">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!!subscriptionForm" class="modal-body">
|
|
||||||
<form [formGroup]="subscriptionForm">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="custom-control custom-checkbox">
|
|
||||||
<label class="checkbox-label">
|
|
||||||
{{ subscriptionForm.get('type').value == 'content' ? 'Content:' : 'Statistics:' }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-12" *ngFor="let frequency of frequencies; let j=index">
|
|
||||||
<input [id]="'checkbox-'+j" (change)="selectCheckbox($event,frequency.value)" [checked]="getIsChecked(frequency)" value="{{frequency.value}}" type="checkbox" />
|
|
||||||
<label [for]="'checkbox-'+j">{{ 'context-menu.actions.subscription.'+frequency.name | translate }}</label>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!!submitted" class="alert">
|
|
||||||
<div *ngIf="subscriptionForm.get('subscriptionParameterList').errors?.required">
|
|
||||||
{{ 'context-menu.actions.subscription.frequency.required' | translate }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
|
|
||||||
<button type="button" class="btn btn-outline-secondary" (click)="c('cancel')">{{'context-menu.actions.request-correction.confirm.cancel' | translate}}</button>
|
|
||||||
|
|
||||||
<button type="button" (click)="submit()" class="btn btn-success" [disabled]="(processing$ | async)">
|
|
||||||
<span *ngIf="(processing$ | async)"><i class='fas fa-circle-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span>
|
|
||||||
<span *ngIf="!(processing$ | async)">{{'context-menu.actions.subscription.confirm.submit' | translate}}</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
|
@@ -1,4 +0,0 @@
|
|||||||
.alert{
|
|
||||||
font-weight: bold;
|
|
||||||
color:red;
|
|
||||||
}
|
|
@@ -1,116 +0,0 @@
|
|||||||
import { ComponentFixture, ComponentFixtureAutoDetect, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { cold } from 'jasmine-marbles';
|
|
||||||
|
|
||||||
// Import modules
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { DebugElement } from '@angular/core';
|
|
||||||
|
|
||||||
import { SubscriptionEditModalComponent } from './subscription-edit-modal.component';
|
|
||||||
|
|
||||||
// Import mocks
|
|
||||||
import { TranslateLoaderMock } from '../../../mocks/translate-loader.mock';
|
|
||||||
import { subscription } from '../../../testing/subscriptions-data.mock';
|
|
||||||
import { ItemInfo } from '../../../testing/relationships-mocks';
|
|
||||||
|
|
||||||
// Import utils
|
|
||||||
import { NotificationsService } from '../../../notifications/notifications.service';
|
|
||||||
import { NotificationsServiceStub } from '../../../testing/notifications-service.stub';
|
|
||||||
import { SubscriptionService } from '../../subscription.service';
|
|
||||||
import { Subscription } from '../../models/subscription.model';
|
|
||||||
|
|
||||||
|
|
||||||
describe('SubscriptionEditModalComponent', () => {
|
|
||||||
let component: SubscriptionEditModalComponent;
|
|
||||||
let fixture: ComponentFixture<SubscriptionEditModalComponent>;
|
|
||||||
let de: DebugElement;
|
|
||||||
|
|
||||||
const subscriptionServiceStub = jasmine.createSpyObj('SubscriptionService', {
|
|
||||||
updateSubscription: jasmine.createSpy('updateSubscription'),
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
beforeEach(waitForAsync (() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
TranslateModule.forRoot({
|
|
||||||
loader: {
|
|
||||||
provide: TranslateLoader,
|
|
||||||
useClass: TranslateLoaderMock
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
declarations: [ SubscriptionEditModalComponent ],
|
|
||||||
providers: [
|
|
||||||
{ provide: ComponentFixtureAutoDetect, useValue: true },
|
|
||||||
{ provide: NotificationsService, useValue: NotificationsServiceStub },
|
|
||||||
{ provide: SubscriptionService, useValue: subscriptionServiceStub },
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(SubscriptionEditModalComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
component.eperson = 'testid123';
|
|
||||||
component.dso = ItemInfo.payload;
|
|
||||||
|
|
||||||
de = fixture.debugElement;
|
|
||||||
|
|
||||||
subscriptionServiceStub.updateSubscription.and.returnValue(cold('a|', {
|
|
||||||
a: {}
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('No Subscription inserted', () => {
|
|
||||||
it('should not show form', () => {
|
|
||||||
expect(de.query(By.css('form'))).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('Subscription inserted', () => {
|
|
||||||
|
|
||||||
beforeEach(fakeAsync(() => {
|
|
||||||
component.subscription = Object.assign(new Subscription(), subscription);
|
|
||||||
component.ngOnInit();
|
|
||||||
fixture.detectChanges();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('when insert subscription show form', () => {
|
|
||||||
expect(de.query(By.css('form'))).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have right checkboxes checked', () => {
|
|
||||||
expect(de.query(By.css('#checkbox-0'))?.nativeElement?.checked).toEqual(true);
|
|
||||||
expect(de.query(By.css('#checkbox-1'))?.nativeElement?.checked).toEqual(true);
|
|
||||||
expect(de.query(By.css('#checkbox-2'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('on checkbox clicked should change form values', () => {
|
|
||||||
const checkbox = de.query(By.css('#checkbox-2')).nativeElement;
|
|
||||||
checkbox.click();
|
|
||||||
|
|
||||||
expect(de.query(By.css('#checkbox-2'))?.nativeElement?.checked).toEqual(true);
|
|
||||||
expect(component.subscriptionParameterList?.value?.length).toEqual(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('on submit clicked update should have been called', () => {
|
|
||||||
const button = de.query(By.css('.btn-success')).nativeElement;
|
|
||||||
button.click();
|
|
||||||
expect(subscriptionServiceStub.updateSubscription).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,190 +0,0 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
|
|
||||||
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|
||||||
|
|
||||||
import { Subscription } from '../../models/subscription.model';
|
|
||||||
|
|
||||||
import { BehaviorSubject } from 'rxjs';
|
|
||||||
|
|
||||||
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
|
||||||
|
|
||||||
import { SubscriptionService } from '../../subscription.service';
|
|
||||||
import { NotificationsService } from '../../../notifications/notifications.service';
|
|
||||||
|
|
||||||
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-subscription-edit-modal',
|
|
||||||
templateUrl: './subscription-edit-modal.component.html',
|
|
||||||
styleUrls: ['./subscription-edit-modal.component.scss']
|
|
||||||
})
|
|
||||||
export class SubscriptionEditModalComponent implements OnInit {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DSpaceObject of the subscription
|
|
||||||
*/
|
|
||||||
@Input() dso: DSpaceObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EPerson of the subscription
|
|
||||||
*/
|
|
||||||
@Input() eperson: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of subscription for the dso object and eperson relation
|
|
||||||
*/
|
|
||||||
@Input() subscription!: Subscription;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close event emit to close modal
|
|
||||||
*/
|
|
||||||
@Output() close: EventEmitter<string> = new EventEmitter<string>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reload event emit to refresh informations
|
|
||||||
*/
|
|
||||||
@Output() reload: EventEmitter<string> = new EventEmitter<string>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A boolean representing if a request operation is pending
|
|
||||||
* @type {BehaviorSubject<boolean>}
|
|
||||||
*/
|
|
||||||
public processing$ = new BehaviorSubject<boolean>(false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reactive form group that will be used to add subscriptions
|
|
||||||
*/
|
|
||||||
subscriptionForm: FormGroup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to show validation errors when user submits
|
|
||||||
*/
|
|
||||||
submitted = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to NgbModal
|
|
||||||
*/
|
|
||||||
public modalRef: NgbModalRef;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frequencies to be shown as checkboxes
|
|
||||||
*/
|
|
||||||
frequencies = [
|
|
||||||
{name: 'daily' ,value: 'D'},
|
|
||||||
{name: 'monthly' ,value: 'M'},
|
|
||||||
{name: 'weekly' ,value: 'W'},
|
|
||||||
];
|
|
||||||
|
|
||||||
constructor(private formGroup: FormBuilder,
|
|
||||||
private notificationsService: NotificationsService,
|
|
||||||
private subscriptionService: SubscriptionService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When component starts initialize starting functionality
|
|
||||||
*/
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.initSubscription();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the subscription is passed start the form with the information of subscription
|
|
||||||
*/
|
|
||||||
initSubscription(): void {
|
|
||||||
if (!!this.subscription) {
|
|
||||||
this.buildFormBuilder(this.subscription);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to get subscriptionParameterList form array cleaner
|
|
||||||
*/
|
|
||||||
get subscriptionParameterList(): FormArray {
|
|
||||||
return this.subscriptionForm.get('subscriptionParameterList') as FormArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When frequency checkboxes are being changed we add/remove frequencies from subscriptionParameterList
|
|
||||||
*/
|
|
||||||
selectCheckbox(event,frequency): void {
|
|
||||||
if (event.target.checked) {
|
|
||||||
this.addFrequency(frequency);
|
|
||||||
} else {
|
|
||||||
this.removeFrequency(frequency);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the form with preinserted informations
|
|
||||||
*/
|
|
||||||
buildFormBuilder(subscription): void {
|
|
||||||
|
|
||||||
this.subscriptionForm = this.formGroup.group({
|
|
||||||
id: subscription.id,
|
|
||||||
type: subscription.subscriptionType,
|
|
||||||
subscriptionParameterList: this.formGroup.array([], Validators.required)
|
|
||||||
});
|
|
||||||
|
|
||||||
subscription.subscriptionParameterList.forEach( (parameter) => {
|
|
||||||
this.addFrequency(parameter.value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new frequency to the subscriptionParameterList form array
|
|
||||||
*/
|
|
||||||
addFrequency(frequency): void {
|
|
||||||
this.subscriptionParameterList.push(
|
|
||||||
this.formGroup.group({
|
|
||||||
name: 'frequency',
|
|
||||||
value: frequency
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove frequency from subscriptionParameterList form array
|
|
||||||
*/
|
|
||||||
removeFrequency(frequency): void {
|
|
||||||
const index = this.subscriptionParameterList.controls.findIndex(el => el.value.value === frequency);
|
|
||||||
this.subscriptionParameterList.removeAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When user saves it will check if form is valid and send request to update subscription
|
|
||||||
*/
|
|
||||||
submit(): void {
|
|
||||||
this.submitted = true;
|
|
||||||
if (this.subscriptionForm.valid) {
|
|
||||||
if (this.subscriptionForm.value.id) {
|
|
||||||
this.updateForm(this.subscriptionForm.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends request to update a new subscription, refreshes the table of subscriptions and notifies about summary page
|
|
||||||
*/
|
|
||||||
updateForm(body): void {
|
|
||||||
this.subscriptionService.updateSubscription(body,this.eperson,this.dso.uuid).subscribe( (res) => {
|
|
||||||
this.reload.emit();
|
|
||||||
this.close.emit();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When close button is pressed emit function to close modal
|
|
||||||
*/
|
|
||||||
c(text): void {
|
|
||||||
this.close.emit(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if a specific frequency exists in the subscriptionParameterList
|
|
||||||
*/
|
|
||||||
getIsChecked(frequency): boolean {
|
|
||||||
return !!this.subscriptionForm.get('subscriptionParameterList').value.find(el => el.value === frequency.value);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
.alert{
|
|
||||||
font-weight: bold;
|
|
||||||
color:red;
|
|
||||||
}
|
|
||||||
|
|
||||||
// .modal-footer{
|
|
||||||
// justify-content: space-between;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.add-button{
|
|
||||||
padding: 0px 15px 15px 15px;
|
|
||||||
}
|
|
@@ -1,223 +0,0 @@
|
|||||||
import { ComponentFixture, ComponentFixtureAutoDetect, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { of as observableOf } from 'rxjs';
|
|
||||||
|
|
||||||
// Import modules
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
|
||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { DebugElement } from '@angular/core';
|
|
||||||
|
|
||||||
import { SubscriptionModalComponent } from './subscription-modal.component';
|
|
||||||
|
|
||||||
// Import mocks
|
|
||||||
import { TranslateLoaderMock } from '../../../mocks/translate-loader.mock';
|
|
||||||
import { findByEPersonAndDsoRes, findByEPersonAndDsoResEmpty } from '../../../testing/subscriptions-data.mock';
|
|
||||||
import { ItemInfo } from '../../../testing/relationships-mocks';
|
|
||||||
|
|
||||||
// Import utils
|
|
||||||
import { NotificationsService } from '../../../notifications/notifications.service';
|
|
||||||
import { SubscriptionService } from '../../subscription.service';
|
|
||||||
|
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../remote-data.utils';
|
|
||||||
|
|
||||||
|
|
||||||
describe('SubscriptionModalComponent', () => {
|
|
||||||
let component: SubscriptionModalComponent;
|
|
||||||
let fixture: ComponentFixture<SubscriptionModalComponent>;
|
|
||||||
let de: DebugElement;
|
|
||||||
|
|
||||||
let subscriptionServiceStub;
|
|
||||||
const notificationServiceStub = {
|
|
||||||
notificationWithAnchor() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
describe('when empty subscriptions', () => {
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
|
|
||||||
subscriptionServiceStub = jasmine.createSpyObj('SubscriptionService', {
|
|
||||||
getSubscriptionByPersonDSO: observableOf(findByEPersonAndDsoResEmpty),
|
|
||||||
createSubscription: createSuccessfulRemoteDataObject$({}),
|
|
||||||
updateSubscription: createSuccessfulRemoteDataObject$({}),
|
|
||||||
});
|
|
||||||
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
NgbModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
TranslateModule.forRoot({
|
|
||||||
loader: {
|
|
||||||
provide: TranslateLoader,
|
|
||||||
useClass: TranslateLoaderMock
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
declarations: [SubscriptionModalComponent],
|
|
||||||
providers: [
|
|
||||||
{ provide: ComponentFixtureAutoDetect, useValue: true },
|
|
||||||
{ provide: NotificationsService, useValue: notificationServiceStub },
|
|
||||||
{ provide: SubscriptionService, useValue: subscriptionServiceStub },
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(SubscriptionModalComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
component.ePersonId = 'testid123';
|
|
||||||
component.dso = ItemInfo.payload;
|
|
||||||
de = fixture.debugElement;
|
|
||||||
|
|
||||||
await fixture.whenStable();
|
|
||||||
await fixture.whenRenderingDone();
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be no table', () => {
|
|
||||||
expect(de.query(By.css('table'))).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show empty form', () => {
|
|
||||||
expect(de.query(By.css('form'))).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show form with empty checkboxes', () => {
|
|
||||||
expect(de.query(By.css('#checkbox-0'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
expect(de.query(By.css('#checkbox-1'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
expect(de.query(By.css('#checkbox-2'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('when we have subscriptions', () => {
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
|
|
||||||
subscriptionServiceStub = jasmine.createSpyObj('SubscriptionService', {
|
|
||||||
getSubscriptionByPersonDSO: observableOf(findByEPersonAndDsoRes),
|
|
||||||
createSubscription: createSuccessfulRemoteDataObject$({}),
|
|
||||||
updateSubscription: createSuccessfulRemoteDataObject$({}),
|
|
||||||
});
|
|
||||||
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
NgbModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
TranslateModule.forRoot({
|
|
||||||
loader: {
|
|
||||||
provide: TranslateLoader,
|
|
||||||
useClass: TranslateLoaderMock
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
declarations: [SubscriptionModalComponent],
|
|
||||||
providers: [
|
|
||||||
{ provide: ComponentFixtureAutoDetect, useValue: true },
|
|
||||||
{ provide: NotificationsService, useValue: notificationServiceStub },
|
|
||||||
{ provide: SubscriptionService, useValue: subscriptionServiceStub },
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(SubscriptionModalComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
component.ePersonId = 'testid123';
|
|
||||||
component.dso = ItemInfo.payload;
|
|
||||||
de = fixture.debugElement;
|
|
||||||
await fixture.whenStable();
|
|
||||||
await fixture.whenRenderingDone();
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render 2 subscriptions', () => {
|
|
||||||
expect(de.queryAll(By.css('tbody > tr')).length).toEqual(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show no form', () => {
|
|
||||||
expect(de.query(By.css('form'))).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have 2 edit buttons', () => {
|
|
||||||
expect(de.queryAll(By.css('.btn-outline-primary')).length).toEqual(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have 2 delete buttons', () => {
|
|
||||||
expect(de.queryAll(By.css('.btn-outline-danger')).length).toEqual(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('When creating new subscription', () => {
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
// add button click
|
|
||||||
const button = de.query(By.css('.btn-success')).nativeElement;
|
|
||||||
button.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should show form when add button click event', () => {
|
|
||||||
expect(de.query(By.css('form'))).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show form with empty checkboxes', () => {
|
|
||||||
expect(de.query(By.css('#checkbox-0'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
expect(de.query(By.css('#checkbox-1'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
expect(de.query(By.css('#checkbox-2'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call create request when submit click event', () => {
|
|
||||||
const checkbox = de.query(By.css('#checkbox-2')).nativeElement;
|
|
||||||
checkbox.click();
|
|
||||||
|
|
||||||
const button = de.queryAll(By.css('.btn-success'))[1].nativeElement;
|
|
||||||
button.click();
|
|
||||||
expect(subscriptionServiceStub.createSubscription).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
describe('When updating subscription', () => {
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
// edit button click
|
|
||||||
const button = de.query(By.css('.btn-outline-primary')).nativeElement;
|
|
||||||
button.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show form when edit button click event', () => {
|
|
||||||
expect(de.query(By.css('form'))).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show form with empty checkboxes', () => {
|
|
||||||
expect(de.query(By.css('#checkbox-0'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
expect(de.query(By.css('#checkbox-1'))?.nativeElement?.checked).toEqual(true);
|
|
||||||
expect(de.query(By.css('#checkbox-2'))?.nativeElement?.checked).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call update request when submit click event', () => {
|
|
||||||
const button = de.queryAll(By.css('.btn-success'))[1].nativeElement;
|
|
||||||
button.click();
|
|
||||||
expect(subscriptionServiceStub.updateSubscription).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
@@ -1,270 +0,0 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
|
||||||
|
|
||||||
import { Subscription } from '../../models/subscription.model';
|
|
||||||
|
|
||||||
import { BehaviorSubject, Observable, shareReplay } from 'rxjs';
|
|
||||||
|
|
||||||
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
|
||||||
|
|
||||||
import { SubscriptionService } from '../../subscription.service';
|
|
||||||
import { NotificationsService } from '../../../notifications/notifications.service';
|
|
||||||
|
|
||||||
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
|
||||||
|
|
||||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
|
||||||
|
|
||||||
import { map, switchMap, take, tap } from 'rxjs/operators';
|
|
||||||
import { RemoteData } from '../../../../core/data/remote-data';
|
|
||||||
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators';
|
|
||||||
import { AuthService } from '../../../../core/auth/auth.service';
|
|
||||||
import { NotificationType } from '../../../notifications/models/notification-type';
|
|
||||||
import { NotificationOptions } from '../../../notifications/models/notification-options.model';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-subscription-modal',
|
|
||||||
templateUrl: './subscription-modal.component.html',
|
|
||||||
styleUrls: ['./subscription-modal.component.scss']
|
|
||||||
})
|
|
||||||
export class SubscriptionModalComponent implements OnInit {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DSpaceObject of which to get the subscriptions
|
|
||||||
*/
|
|
||||||
@Input() dso: DSpaceObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of subscription for the dso object and eperson relation
|
|
||||||
*/
|
|
||||||
subscriptions: Subscription[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A boolean representing if a request operation is pending
|
|
||||||
* @type {BehaviorSubject<boolean>}
|
|
||||||
*/
|
|
||||||
public processing$ = new BehaviorSubject<boolean>(false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reactive form group that will be used to add subscriptions
|
|
||||||
*/
|
|
||||||
subscriptionForm: FormGroup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to show validation errors when user submits
|
|
||||||
*/
|
|
||||||
submitted = false;
|
|
||||||
|
|
||||||
ePersonId$: Observable<string>;
|
|
||||||
|
|
||||||
ePersonId: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Types of subscription to be shown on select
|
|
||||||
*/
|
|
||||||
subscriptionTypes = [ 'content', 'statistics' ];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frequencies to be shown as checkboxes
|
|
||||||
*/
|
|
||||||
frequencies = [ 'D', 'M', 'W' ];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private formBuilder: FormBuilder,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private notificationsService: NotificationsService,
|
|
||||||
private subscriptionService: SubscriptionService,
|
|
||||||
public activeModal: NgbActiveModal,
|
|
||||||
private authService: AuthService,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When component starts initialize starting functionality
|
|
||||||
*/
|
|
||||||
ngOnInit(): void {
|
|
||||||
|
|
||||||
this.ePersonId$ = this.authService.getAuthenticatedUserFromStore().pipe(
|
|
||||||
take(1),
|
|
||||||
map((ePerson) => ePerson.uuid),
|
|
||||||
tap((res) => {
|
|
||||||
this.ePersonId = res;
|
|
||||||
}),
|
|
||||||
shareReplay(),
|
|
||||||
);
|
|
||||||
|
|
||||||
this.subscriptionForm = this.formBuilder.group({});
|
|
||||||
|
|
||||||
for (let f of this.frequencies) {
|
|
||||||
this.subscriptionForm.addControl(f, this.formBuilder.control(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO iterate over subscription types
|
|
||||||
|
|
||||||
/*this.subscriptionForm = this.formBuilder.group({});
|
|
||||||
for (let t of this.subscriptionTypes) {
|
|
||||||
this.subscriptionForm.addControl(t, this.formBuilder.group({}));
|
|
||||||
for (let f of this.frequencies) {
|
|
||||||
this.subscriptionForm[t].addControl(f, this.formBuilder.control(false));
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
this.initSubscription();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get subscription for the eperson & dso object relation
|
|
||||||
* If no subscription start with an empty form
|
|
||||||
*/
|
|
||||||
initSubscription(): void {
|
|
||||||
this.processing$.next(true);
|
|
||||||
this.ePersonId$.pipe(
|
|
||||||
tap(console.log),
|
|
||||||
switchMap((ePersonId: string) => this.getSubscription(ePersonId, this.dso?.uuid)),
|
|
||||||
getFirstSucceededRemoteDataPayload(),
|
|
||||||
).subscribe({
|
|
||||||
next: (res: PaginatedList<Subscription>) => {
|
|
||||||
if (res.pageInfo.totalElements > 0) {
|
|
||||||
this.subscriptions = res.page;
|
|
||||||
|
|
||||||
// TODO loop over subscription types
|
|
||||||
// for (let type of this.subscriptionTypes) {
|
|
||||||
const type = 'content'; // TODO remove
|
|
||||||
const subscription = this.subscriptions.find((s) => s.subscriptionType === type);
|
|
||||||
// TODO manage multiple subscriptions with same type (there should be only one)
|
|
||||||
for (let parameter of subscription.subscriptionParameterList.filter((p) => p.name === 'frequency')) {
|
|
||||||
this.subscriptionForm.controls[parameter.value]?.setValue(true);
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
this.processing$.next(false);
|
|
||||||
},
|
|
||||||
error: err => {
|
|
||||||
this.processing$.next(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to get subscriptions based on the eperson & dso
|
|
||||||
*
|
|
||||||
* @param ePersonId Eperson that is logged in
|
|
||||||
* @param uuid DSpaceObject id that subscriptions are related to
|
|
||||||
*/
|
|
||||||
getSubscription(ePersonId: string, uuid: string): Observable<RemoteData<PaginatedList<Subscription>>> {
|
|
||||||
return this.subscriptionService.getSubscriptionByPersonDSO(ePersonId, uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
submit() {
|
|
||||||
|
|
||||||
// for (let type of this.subscriptionTypes) {
|
|
||||||
|
|
||||||
const type = 'content'; // TODO remove
|
|
||||||
|
|
||||||
const currentSubscription = this.subscriptions?.find((s) => s.subscriptionType === type);
|
|
||||||
|
|
||||||
const body = {
|
|
||||||
id: currentSubscription?.id,
|
|
||||||
type,
|
|
||||||
subscriptionParameterList: []
|
|
||||||
};
|
|
||||||
|
|
||||||
let someCheckboxSelected = false;
|
|
||||||
|
|
||||||
for (let frequency of this.frequencies) {
|
|
||||||
if (this.subscriptionForm.value[frequency]) { // TODO read the value for the type
|
|
||||||
someCheckboxSelected = true;
|
|
||||||
body.subscriptionParameterList.push(
|
|
||||||
{
|
|
||||||
name: 'frequency',
|
|
||||||
value: frequency,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentSubscription) {
|
|
||||||
const subscriptionsToBeRemobed = this.subscriptions?.filter(
|
|
||||||
(s) => s.subscriptionType === type && s.id !== currentSubscription.id
|
|
||||||
);
|
|
||||||
for (let s of subscriptionsToBeRemobed) {
|
|
||||||
this.subscriptionService.deleteSubscription(currentSubscription.id).pipe(
|
|
||||||
getFirstCompletedRemoteData(),
|
|
||||||
).subscribe((res) => {
|
|
||||||
if (res.hasSucceeded) {
|
|
||||||
console.warn(`An additional subscription with type=${type} and id=${s.id} has been removed`);
|
|
||||||
} else {
|
|
||||||
this.notifyFailure();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (currentSubscription && someCheckboxSelected) {
|
|
||||||
// Update the existing subscription
|
|
||||||
this.subscriptionService.updateSubscription(body, this.ePersonId, this.dso.uuid).pipe(
|
|
||||||
getFirstCompletedRemoteData(),
|
|
||||||
).subscribe((res) => {
|
|
||||||
if (res.hasSucceeded) {
|
|
||||||
this.notifySuccess();
|
|
||||||
this.activeModal.close();
|
|
||||||
} else {
|
|
||||||
this.notifyFailure();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (currentSubscription && !someCheckboxSelected) {
|
|
||||||
// Delete the existing subscription
|
|
||||||
this.subscriptionService.deleteSubscription(currentSubscription.id).subscribe(console.log);
|
|
||||||
// TODO handle notifications
|
|
||||||
} else if (someCheckboxSelected) {
|
|
||||||
// Create a new subscription
|
|
||||||
this.subscriptionService.createSubscription(body, this.ePersonId, this.dso.uuid).subscribe(console.log);
|
|
||||||
// TODO handle notifications
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this.subscriptionService.createSubscription(body, this.ePersonId, this.dso.uuid).subscribe((res) => {
|
|
||||||
// // this.refresh();
|
|
||||||
// // this.notify();
|
|
||||||
// // this.processing$.next(false);
|
|
||||||
// },
|
|
||||||
// err => {
|
|
||||||
// // this.processing$.next(false);
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a notification with the link to the subscription summary page
|
|
||||||
*/
|
|
||||||
notifySuccess(): void {
|
|
||||||
const options = new NotificationOptions();
|
|
||||||
options.timeOut = 0;
|
|
||||||
const link = '/subscriptions';
|
|
||||||
this.notificationsService.notificationWithAnchor(
|
|
||||||
NotificationType.Success,
|
|
||||||
options,
|
|
||||||
link,
|
|
||||||
'context-menu.actions.subscription.notification.here-text',
|
|
||||||
'context-menu.actions.subscription.notification.content',
|
|
||||||
'here'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyFailure() {
|
|
||||||
console.error('error');
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,11 +1,14 @@
|
|||||||
|
import { Observable } from 'rxjs';
|
||||||
import { autoserialize, deserialize, inheritSerialization } from 'cerialize';
|
import { autoserialize, deserialize, inheritSerialization } from 'cerialize';
|
||||||
import { typedObject } from '../../../core/cache/builders/build-decorators';
|
|
||||||
|
|
||||||
|
import { link, typedObject } from '../../../core/cache/builders/build-decorators';
|
||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import { HALLink } from '../../../core/shared/hal-link.model';
|
import { HALLink } from '../../../core/shared/hal-link.model';
|
||||||
import { SUBSCRIPTION } from './subscription.resource-type';
|
import { SUBSCRIPTION } from './subscription.resource-type';
|
||||||
import { EPerson } from '../../../core/eperson/models/eperson.model';
|
import { EPerson } from '../../../core/eperson/models/eperson.model';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { EPERSON } from '../../../core/eperson/models/eperson.resource-type';
|
||||||
|
import { DSPACE_OBJECT } from '../../../core/shared/dspace-object.resource-type';
|
||||||
|
|
||||||
@typedObject
|
@typedObject
|
||||||
@inheritSerialization(DSpaceObject)
|
@inheritSerialization(DSpaceObject)
|
||||||
@@ -40,14 +43,27 @@ export class Subscription extends DSpaceObject {
|
|||||||
dSpaceObject: HALLink;
|
dSpaceObject: HALLink;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logo for this Community
|
||||||
|
* Will be undefined unless the logo {@link HALLink} has been resolved.
|
||||||
|
*/
|
||||||
|
@link(EPERSON)
|
||||||
|
ePerson?: Observable<RemoteData<EPerson>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logo for this Community
|
||||||
|
* Will be undefined unless the logo {@link HALLink} has been resolved.
|
||||||
|
*/
|
||||||
|
@link(DSPACE_OBJECT)
|
||||||
|
dSpaceObject?: Observable<RemoteData<DSpaceObject>>;
|
||||||
/**
|
/**
|
||||||
* The embedded ePerson & dSpaceObject for this Subscription
|
* The embedded ePerson & dSpaceObject for this Subscription
|
||||||
*/
|
*/
|
||||||
@deserialize
|
/* @deserialize
|
||||||
_embedded: {
|
_embedded: {
|
||||||
ePerson: EPerson;
|
ePerson: EPerson;
|
||||||
dSpaceObject: DSpaceObject;
|
dSpaceObject: DSpaceObject;
|
||||||
};
|
};*/
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SubscriptionParameterList {
|
export interface SubscriptionParameterList {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<form [formGroup]="subscriptionForm" (ngSubmit)="submit()">
|
<form *ngIf="subscriptionForm" [formGroup]="subscriptionForm" (ngSubmit)="submit()" data-test="subscription-form">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title">{{'item.page.subscriptions.modal.title' | translate}}</h4>
|
<h4 class="modal-title">{{'item.page.subscriptions.modal.title' | translate}}</h4>
|
||||||
<button type="button" class="close" aria-label="Close" (click)="activeModal.close()">
|
<button type="button" class="close" aria-label="Close" (click)="activeModal.close()">
|
||||||
@@ -9,22 +9,23 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<fieldset class="form-group form-row">
|
<fieldset *ngFor="let subscriptionType of subscriptionForm?.controls | keyvalue" formGroupName="{{subscriptionType.key}}" class="form-group form-row">
|
||||||
|
|
||||||
<legend class="col-md-4 col-form-label float-md-left pt-0">
|
<legend class="col-md-4 col-form-label float-md-left pt-0">
|
||||||
{{ 'item.page.subscriptions.modal.new-subscription-form.type.content' | translate }}:
|
{{ 'item.page.subscriptions.modal.new-subscription-form.type.' + subscriptionType.key | translate }}:
|
||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
|
<input type="hidden" formControlName="subscriptionId" [value]="subscriptionType?.value?.controls['subscriptionId'].value" >
|
||||||
<div class="form-check" *ngFor="let frequency of subscriptionForm.controls | keyvalue">
|
<div class="form-check" formGroupName="frequencies" *ngFor="let frequency of subscriptionType?.value?.controls['frequencies'].controls | keyvalue">
|
||||||
<input type="checkbox" [id]="'checkbox-' + frequency" class="form-check-input" [formControlName]="frequency.key"/>
|
<input type="checkbox" [id]="'checkbox-' + frequency" class="form-check-input" [formControlName]="frequency.key"/>
|
||||||
<label class="form-check-label"
|
<label class="form-check-label"
|
||||||
[for]="'checkbox-' + frequency.key">{{ 'item.page.subscriptions.modal.new-subscription-form.frequency.' + frequency.key | translate }}</label>
|
[for]="'checkbox-' + frequency.key">{{ 'item.page.subscriptions.modal.new-subscription-form.frequency.' + frequency.key | translate }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<ds-alert *ngIf="!!submitted && subscriptionType?.value?.controls['frequencies'].errors?.required" [type]="'alert-danger'">
|
||||||
|
{{ 'context-menu.actions.subscription.frequency.required' | translate }}
|
||||||
|
</ds-alert>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
@@ -0,0 +1,194 @@
|
|||||||
|
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { NgbActiveModal, NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { SubscriptionModalComponent } from './subscription-modal.component';
|
||||||
|
import { TranslateLoaderMock } from '../../mocks/translate-loader.mock';
|
||||||
|
import { NotificationsService } from '../../notifications/notifications.service';
|
||||||
|
import { SubscriptionService } from '../subscription.service';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../../remote-data.utils';
|
||||||
|
import { Item } from '../../../core/shared/item.model';
|
||||||
|
import { AuthService } from '../../../core/auth/auth.service';
|
||||||
|
import { EPerson } from '../../../core/eperson/models/eperson.model';
|
||||||
|
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||||
|
import { buildPaginatedList } from '../../../core/data/paginated-list.model';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { subscriptionMock, subscriptionMock2 } from '../../testing/subscriptions-data.mock';
|
||||||
|
|
||||||
|
describe('SubscriptionModalComponent', () => {
|
||||||
|
let component: SubscriptionModalComponent;
|
||||||
|
let fixture: ComponentFixture<SubscriptionModalComponent>;
|
||||||
|
let de: DebugElement;
|
||||||
|
|
||||||
|
let subscriptionServiceStub;
|
||||||
|
const notificationServiceStub = {
|
||||||
|
notificationWithAnchor() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const emptyPageInfo = Object.assign(new PageInfo(), {
|
||||||
|
'elementsPerPage': 0,
|
||||||
|
'totalElements': 0
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const pageInfo = Object.assign(new PageInfo(), {
|
||||||
|
'elementsPerPage': 2,
|
||||||
|
'totalElements': 2
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockEperson = Object.assign(new EPerson(), {
|
||||||
|
id: 'fake-id',
|
||||||
|
uuid: 'fake-id',
|
||||||
|
_links: {
|
||||||
|
self: {
|
||||||
|
href: 'https://localhost:8000/eperson/fake-id'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockItem = Object.assign(new Item(), {
|
||||||
|
id: 'fake-id',
|
||||||
|
uuid: 'fake-id',
|
||||||
|
handle: 'fake/handle',
|
||||||
|
lastModified: '2018',
|
||||||
|
_links: {
|
||||||
|
self: {
|
||||||
|
href: 'https://localhost:8000/items/fake-id'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const authService = jasmine.createSpyObj('authService', {
|
||||||
|
getAuthenticatedUserFromStore: createSuccessfulRemoteDataObject$(mockEperson)
|
||||||
|
});
|
||||||
|
|
||||||
|
subscriptionServiceStub = jasmine.createSpyObj('SubscriptionService', {
|
||||||
|
getSubscriptionsByPersonDSO: jasmine.createSpy('getSubscriptionsByPersonDSO'),
|
||||||
|
createSubscription: createSuccessfulRemoteDataObject$({}),
|
||||||
|
updateSubscription: createSuccessfulRemoteDataObject$({}),
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(waitForAsync(() => {
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
NgbModalModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useClass: TranslateLoaderMock
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
declarations: [SubscriptionModalComponent],
|
||||||
|
providers: [
|
||||||
|
NgbActiveModal,
|
||||||
|
{ provide: AuthService, useValue: authService },
|
||||||
|
{ provide: NotificationsService, useValue: notificationServiceStub },
|
||||||
|
{ provide: SubscriptionService, useValue: subscriptionServiceStub },
|
||||||
|
],
|
||||||
|
schemas: [
|
||||||
|
NO_ERRORS_SCHEMA
|
||||||
|
]
|
||||||
|
}).compileComponents();
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('when no subscription is given', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(SubscriptionModalComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
component.dso = mockItem;
|
||||||
|
(component as any).subscriptionDefaultTypes = ['test1', 'test2']
|
||||||
|
de = fixture.debugElement;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and no subscriptions are present for the given dso', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
subscriptionServiceStub.getSubscriptionsByPersonDSO.and.returnValue(createSuccessfulRemoteDataObject$(buildPaginatedList(emptyPageInfo, [])));
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should init form properly', () => {
|
||||||
|
expect(de.query(By.css(' [data-test="subscription-form"]'))).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm.get('test1')).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm.get('test2')).toBeTruthy();
|
||||||
|
(component as any).frequencyDefaultValues.forEach((frequency) => {
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get(frequency)).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm.get('test2').get('frequencies').get(frequency)).toBeTruthy();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and subscriptions are present for the given dso', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
subscriptionServiceStub.getSubscriptionsByPersonDSO.and.returnValue(createSuccessfulRemoteDataObject$(buildPaginatedList(pageInfo, [subscriptionMock, subscriptionMock2])));
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should init form properly', () => {
|
||||||
|
expect(de.query(By.css(' [data-test="subscription-form"]'))).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm.get('test1')).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm.get('test2')).toBeTruthy();
|
||||||
|
(component as any).frequencyDefaultValues.forEach((frequency) => {
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get(frequency)).toBeTruthy();
|
||||||
|
|
||||||
|
expect(component.subscriptionForm.get('test2').get('frequencies').get(frequency)).toBeTruthy();
|
||||||
|
})
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get('D').value).toBeTrue();
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get('M').value).toBeTrue();
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get('W').value).toBeFalse();
|
||||||
|
|
||||||
|
expect(component.subscriptionForm.get('test2').get('frequencies').get('D').value).toBeTrue();
|
||||||
|
expect(component.subscriptionForm.get('test2').get('frequencies').get('M').value).toBeFalse();
|
||||||
|
expect(component.subscriptionForm.get('test2').get('frequencies').get('W').value).toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when no subscription is given', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(SubscriptionModalComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
component.dso = mockItem;
|
||||||
|
component.subscription = subscriptionMock as any;
|
||||||
|
(component as any).subscriptionDefaultTypes = ['test1', 'test2']
|
||||||
|
de = fixture.debugElement;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should init form properly', () => {
|
||||||
|
expect(de.query(By.css(' [data-test="subscription-form"]'))).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm).toBeTruthy();
|
||||||
|
expect(component.subscriptionForm.get('test1')).toBeTruthy();
|
||||||
|
(component as any).frequencyDefaultValues.forEach((frequency) => {
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get(frequency)).toBeTruthy();
|
||||||
|
})
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get('D').value).toBeTrue();
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get('M').value).toBeTrue();
|
||||||
|
expect(component.subscriptionForm.get('test1').get('frequencies').get('W').value).toBeFalse();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -0,0 +1,261 @@
|
|||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
|
|
||||||
|
|
||||||
|
import { BehaviorSubject, combineLatest, from, shareReplay } from 'rxjs';
|
||||||
|
import { map, mergeMap, take, tap } from 'rxjs/operators';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
|
import { Subscription } from '../models/subscription.model';
|
||||||
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
|
import { SubscriptionService } from '../subscription.service';
|
||||||
|
import { NotificationsService } from '../../notifications/notifications.service';
|
||||||
|
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||||
|
import { AuthService } from '../../../core/auth/auth.service';
|
||||||
|
import { isNotEmpty } from '../../empty.util';
|
||||||
|
import { findIndex } from 'lodash';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-subscription-modal',
|
||||||
|
templateUrl: './subscription-modal.component.html',
|
||||||
|
styleUrls: ['./subscription-modal.component.scss']
|
||||||
|
})
|
||||||
|
export class SubscriptionModalComponent implements OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DSpaceObject of which to get the subscriptions
|
||||||
|
*/
|
||||||
|
@Input() dso: DSpaceObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If given the subscription to edit by the form
|
||||||
|
*/
|
||||||
|
@Input() subscription: Subscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The eperson related to the subscription
|
||||||
|
*/
|
||||||
|
ePersonId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if a request operation is pending
|
||||||
|
* @type {BehaviorSubject<boolean>}
|
||||||
|
*/
|
||||||
|
public processing$ = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reactive form group that will be used to add/edit subscriptions
|
||||||
|
*/
|
||||||
|
subscriptionForm: FormGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to show validation errors when user submits
|
||||||
|
*/
|
||||||
|
submitted = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of subscription to be shown on select
|
||||||
|
*/
|
||||||
|
private subscriptionDefaultTypes = ['content', 'statistics'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frequencies to be shown as checkboxes
|
||||||
|
*/
|
||||||
|
private frequencyDefaultValues = ['D', 'M', 'W'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event emitted when a given subscription has been updated
|
||||||
|
*/
|
||||||
|
@Output() updateSubscription: EventEmitter<Subscription> = new EventEmitter<Subscription>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private modalService: NgbModal,
|
||||||
|
private notificationsService: NotificationsService,
|
||||||
|
private subscriptionService: SubscriptionService,
|
||||||
|
public activeModal: NgbActiveModal,
|
||||||
|
private authService: AuthService,
|
||||||
|
private translate: TranslateService,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When component starts initialize starting functionality
|
||||||
|
*/
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.authService.getAuthenticatedUserFromStore().pipe(
|
||||||
|
take(1),
|
||||||
|
map((ePerson) => ePerson.uuid),
|
||||||
|
shareReplay(),
|
||||||
|
).subscribe((ePersonId: string) => {
|
||||||
|
this.ePersonId = ePersonId;
|
||||||
|
if (isNotEmpty(this.subscription)) {
|
||||||
|
this.initFormByGivenSubscription();
|
||||||
|
} else {
|
||||||
|
this.initFormByAllSubscriptions();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initFormByAllSubscriptions(): void {
|
||||||
|
this.subscriptionForm = new FormGroup({});
|
||||||
|
for (let t of this.subscriptionDefaultTypes) {
|
||||||
|
const formGroup = new FormGroup({})
|
||||||
|
formGroup.addControl('subscriptionId', this.formBuilder.control(''));
|
||||||
|
formGroup.addControl('frequencies', this.formBuilder.group({}));
|
||||||
|
for (let f of this.frequencyDefaultValues) {
|
||||||
|
(formGroup.controls['frequencies'] as FormGroup).addControl(f, this.formBuilder.control(false));
|
||||||
|
}
|
||||||
|
this.subscriptionForm.addControl(t, formGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initFormDataBySubscriptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the subscription is passed start the form with the information of subscription
|
||||||
|
*/
|
||||||
|
initFormByGivenSubscription(): void {
|
||||||
|
const formGroup = new FormGroup({})
|
||||||
|
formGroup.addControl('subscriptionId', this.formBuilder.control(this.subscription.id));
|
||||||
|
formGroup.addControl('frequencies', this.formBuilder.group({}));
|
||||||
|
(formGroup.get('frequencies') as FormGroup).addValidators(Validators.required);
|
||||||
|
for (let f of this.frequencyDefaultValues) {
|
||||||
|
const value = findIndex(this.subscription.subscriptionParameterList, ['value', f]) !== -1;
|
||||||
|
(formGroup.controls['frequencies'] as FormGroup).addControl(f, this.formBuilder.control(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subscriptionForm = this.formBuilder.group({
|
||||||
|
[this.subscription.subscriptionType]: formGroup
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get subscription for the eperson & dso object relation
|
||||||
|
* If no subscription start with an empty form
|
||||||
|
*/
|
||||||
|
initFormDataBySubscriptions(): void {
|
||||||
|
this.processing$.next(true);
|
||||||
|
this.subscriptionService.getSubscriptionsByPersonDSO(this.ePersonId, this.dso?.uuid).pipe(
|
||||||
|
getFirstSucceededRemoteDataPayload(),
|
||||||
|
).subscribe({
|
||||||
|
next: (res: PaginatedList<Subscription>) => {
|
||||||
|
if (res.pageInfo.totalElements > 0) {
|
||||||
|
for (let subscription of res.page) {
|
||||||
|
const type = subscription.subscriptionType;
|
||||||
|
const subscriptionGroup: FormGroup = this.subscriptionForm.get(type) as FormGroup;
|
||||||
|
if (isNotEmpty(subscriptionGroup)) {
|
||||||
|
subscriptionGroup.controls['subscriptionId'].setValue(subscription.id);
|
||||||
|
for (let parameter of subscription.subscriptionParameterList.filter((p) => p.name === 'frequency')) {
|
||||||
|
(subscriptionGroup.controls['frequencies'] as FormGroup).controls[parameter.value]?.setValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.processing$.next(false);
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
this.processing$.next(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create/update subscriptions if needed
|
||||||
|
*/
|
||||||
|
submit() {
|
||||||
|
this.submitted = true;
|
||||||
|
const subscriptionTypes: string[] = Object.keys(this.subscriptionForm.controls);
|
||||||
|
const subscriptionsToBeCreated = [];
|
||||||
|
const subscriptionsToBeUpdated = [];
|
||||||
|
|
||||||
|
subscriptionTypes.forEach((subscriptionType: string) => {
|
||||||
|
const subscriptionGroup: FormGroup = this.subscriptionForm.controls[subscriptionType] as FormGroup;
|
||||||
|
if (subscriptionGroup.touched && subscriptionGroup.dirty) {
|
||||||
|
const body = this.createBody(
|
||||||
|
subscriptionGroup.controls['subscriptionId'].value,
|
||||||
|
subscriptionType,
|
||||||
|
subscriptionGroup.controls['frequencies'] as FormGroup
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isNotEmpty(body.id)) {
|
||||||
|
subscriptionsToBeUpdated.push(body);
|
||||||
|
} else if (isNotEmpty(body.subscriptionParameterList)) {
|
||||||
|
subscriptionsToBeCreated.push(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const toBeProcessed = [];
|
||||||
|
if (isNotEmpty(subscriptionsToBeCreated)) {
|
||||||
|
toBeProcessed.push(from(subscriptionsToBeCreated).pipe(
|
||||||
|
mergeMap((subscriptionBody) => {
|
||||||
|
return this.subscriptionService.createSubscription(subscriptionBody, this.ePersonId, this.dso.uuid).pipe(
|
||||||
|
getFirstCompletedRemoteData()
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
tap((res: RemoteData<Subscription>) => {
|
||||||
|
if (res.hasSucceeded) {
|
||||||
|
const msg = this.translate.instant('subscriptions.modal.create.success', { type: res.payload.subscriptionType });
|
||||||
|
this.notificationsService.success(null, msg);
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(null, this.translate.instant('subscriptions.modal.create.error'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotEmpty(subscriptionsToBeUpdated)) {
|
||||||
|
toBeProcessed.push(from(subscriptionsToBeUpdated).pipe(
|
||||||
|
mergeMap((subscriptionBody) => {
|
||||||
|
return this.subscriptionService.updateSubscription(subscriptionBody, this.ePersonId, this.dso.uuid).pipe(
|
||||||
|
getFirstCompletedRemoteData()
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
tap((res: RemoteData<Subscription>) => {
|
||||||
|
if (res.hasSucceeded) {
|
||||||
|
const msg = this.translate.instant('subscriptions.modal.update.success', { type: res.payload.subscriptionType });
|
||||||
|
this.notificationsService.success(null, msg);
|
||||||
|
if (isNotEmpty(this.subscription)) {
|
||||||
|
this.updateSubscription.emit(res.payload);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(null, this.translate.instant('subscriptions.modal.update.error'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
combineLatest([...toBeProcessed]).subscribe((res) => {
|
||||||
|
this.activeModal.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private createBody(subscriptionId: string, subscriptionType: string, frequencies: FormGroup): Partial<any> {
|
||||||
|
const body = {
|
||||||
|
id: (isNotEmpty(subscriptionId) ? subscriptionId : null),
|
||||||
|
type: subscriptionType,
|
||||||
|
subscriptionParameterList: []
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let frequency of this.frequencyDefaultValues) {
|
||||||
|
if (frequencies.value[frequency]) {
|
||||||
|
body.subscriptionParameterList.push(
|
||||||
|
{
|
||||||
|
name: 'frequency',
|
||||||
|
value: frequency,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -14,7 +14,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="subscription-actions">
|
<td class="subscription-actions">
|
||||||
<div class="btn-group edit-field">
|
<div class="btn-group edit-field">
|
||||||
<button (click)="$event.preventDefault();openSubscription(subscriptionModal);" class="btn btn-outline-primary btn-sm access-control-editEPersonButton" title="Edit">
|
<button (click)="$event.preventDefault();openSubscriptionModal();" class="btn btn-outline-primary btn-sm access-control-editEPersonButton" title="Edit">
|
||||||
<i class="fas fa-edit fa-fw"></i>
|
<i class="fas fa-edit fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
<button (click)="deleteSubscriptionPopup(subscription)" class="btn btn-outline-danger btn-sm access-control-deleteEPersonButton" title="Delete">
|
<button (click)="deleteSubscriptionPopup(subscription)" class="btn btn-outline-danger btn-sm access-control-deleteEPersonButton" title="Delete">
|
||||||
@@ -22,8 +22,3 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<ng-template #subscriptionModal let-c="close" let-d="dismiss">
|
|
||||||
<ds-subscription-edit-modal (reload)="reload.emit({})" (close)="c('cancel')" [subscription]="subscription" [dso]="dso" [eperson]="eperson"></ds-subscription-edit-modal>
|
|
||||||
</ng-template>
|
|
||||||
|
|
@@ -6,27 +6,27 @@ import { 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 { SharedModule } from '../../../shared.module';
|
import { SharedModule } from '../../shared.module';
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
|
||||||
import { SubscriptionViewComponent } from './subscription-view.component';
|
import { SubscriptionViewComponent } from './subscription-view.component';
|
||||||
|
|
||||||
// Import mocks
|
// Import mocks
|
||||||
import { TranslateLoaderMock } from '../../../mocks/translate-loader.mock';
|
import { TranslateLoaderMock } from '../../mocks/translate-loader.mock';
|
||||||
import { ItemInfo } from '../../../testing/relationships-mocks';
|
import { findByEPersonAndDsoResEmpty, subscriptionMock } from '../../testing/subscriptions-data.mock';
|
||||||
import { findByEPersonAndDsoResEmpty, subscription } from '../../../testing/subscriptions-data.mock';
|
|
||||||
|
|
||||||
// Import utils
|
// Import utils
|
||||||
import { NotificationsService } from '../../../notifications/notifications.service';
|
import { NotificationsService } from '../../notifications/notifications.service';
|
||||||
import { NotificationsServiceStub } from '../../../testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../testing/notifications-service.stub';
|
||||||
import { SubscriptionService } from '../../subscription.service';
|
import { SubscriptionService } from '../subscription.service';
|
||||||
import { Subscription } from '../../models/subscription.model';
|
import { Subscription } from '../models/subscription.model';
|
||||||
|
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../remote-data.utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../remote-data.utils';
|
||||||
|
import { Item } from '../../../core/shared/item.model';
|
||||||
|
import { ITEM } from '../../../core/shared/item.resource-type';
|
||||||
|
|
||||||
describe('SubscriptionViewComponent', () => {
|
describe('SubscriptionViewComponent', () => {
|
||||||
let component: SubscriptionViewComponent;
|
let component: SubscriptionViewComponent;
|
||||||
@@ -40,6 +40,19 @@ describe('SubscriptionViewComponent', () => {
|
|||||||
updateSubscription: createSuccessfulRemoteDataObject$({}),
|
updateSubscription: createSuccessfulRemoteDataObject$({}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const mockItem = Object.assign(new Item(), {
|
||||||
|
id: 'fake-id',
|
||||||
|
uuid: 'fake-id',
|
||||||
|
handle: 'fake/handle',
|
||||||
|
lastModified: '2018',
|
||||||
|
type: ITEM,
|
||||||
|
_links: {
|
||||||
|
self: {
|
||||||
|
href: 'https://localhost:8000/items/fake-id'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -70,8 +83,8 @@ describe('SubscriptionViewComponent', () => {
|
|||||||
fixture = TestBed.createComponent(SubscriptionViewComponent);
|
fixture = TestBed.createComponent(SubscriptionViewComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
component.eperson = 'testid123';
|
component.eperson = 'testid123';
|
||||||
component.dso = ItemInfo.payload;
|
component.dso = mockItem;
|
||||||
component.subscription = Object.assign(new Subscription(), subscription);
|
component.subscription = Object.assign(new Subscription(), subscriptionMock);
|
||||||
de = fixture.debugElement;
|
de = fixture.debugElement;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
@@ -1,13 +1,17 @@
|
|||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { Subscription } from '../../models/subscription.model';
|
import { Subscription } from '../models/subscription.model';
|
||||||
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
|
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { hasValue } from '../../../empty.util';
|
|
||||||
import { ConfirmationModalComponent } from '../../../confirmation-modal/confirmation-modal.component';
|
import { hasValue } from '../../empty.util';
|
||||||
import { SubscriptionService } from '../../subscription.service';
|
import { ConfirmationModalComponent } from '../../confirmation-modal/confirmation-modal.component';
|
||||||
|
import { SubscriptionService } from '../subscription.service';
|
||||||
|
import { getCommunityModuleRoute } from '../../../community-page/community-page-routing-paths';
|
||||||
|
import { getCollectionModuleRoute } from '../../../collection-page/collection-page-routing-paths';
|
||||||
|
import { getItemModuleRoute } from '../../../item-page/item-page-routing-paths';
|
||||||
|
import { SubscriptionModalComponent } from '../subscription-modal/subscription-modal.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
// eslint-disable-next-line @angular-eslint/component-selector
|
// eslint-disable-next-line @angular-eslint/component-selector
|
||||||
@@ -47,16 +51,6 @@ export class SubscriptionViewComponent {
|
|||||||
private subscriptionService: SubscriptionService,
|
private subscriptionService: SubscriptionService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open modal
|
|
||||||
*
|
|
||||||
* @param content
|
|
||||||
*/
|
|
||||||
public openSubscription(content: any) {
|
|
||||||
this.modalRef = this.modalService.open(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the prefix of the route to the dso object page ( e.g. "items")
|
* Return the prefix of the route to the dso object page ( e.g. "items")
|
||||||
*/
|
*/
|
||||||
@@ -64,13 +58,13 @@ export class SubscriptionViewComponent {
|
|||||||
let routePrefix;
|
let routePrefix;
|
||||||
switch (this.dso.type.toString()) {
|
switch (this.dso.type.toString()) {
|
||||||
case 'community':
|
case 'community':
|
||||||
routePrefix = '/communities';
|
routePrefix = getCommunityModuleRoute();
|
||||||
break;
|
break;
|
||||||
case 'collection':
|
case 'collection':
|
||||||
routePrefix = '/collections';
|
routePrefix = getCollectionModuleRoute();
|
||||||
break;
|
break;
|
||||||
case 'item':
|
case 'item':
|
||||||
routePrefix = '/items';
|
routePrefix = getItemModuleRoute();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return routePrefix;
|
return routePrefix;
|
||||||
@@ -99,4 +93,14 @@ export class SubscriptionViewComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public openSubscriptionModal() {
|
||||||
|
this.modalRef = this.modalService.open(SubscriptionModalComponent);
|
||||||
|
this.modalRef.componentInstance.dso = this.dso;
|
||||||
|
this.modalRef.componentInstance.subscription = this.subscription;
|
||||||
|
this.modalRef.componentInstance.updateSubscription.pipe(take(1)).subscribe((subscription: Subscription) => {
|
||||||
|
this.subscription = subscription;
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
@@ -70,7 +70,7 @@ export class SubscriptionService extends IdentifiableDataService<Subscription> {
|
|||||||
* @param eperson The eperson to search for
|
* @param eperson The eperson to search for
|
||||||
* @param uuid The uuid of the dsobjcet to search for
|
* @param uuid The uuid of the dsobjcet to search for
|
||||||
*/
|
*/
|
||||||
getSubscriptionByPersonDSO(eperson: string, uuid: string): Observable<RemoteData<PaginatedList<Subscription>>> {
|
getSubscriptionsByPersonDSO(eperson: string, uuid: string): Observable<RemoteData<PaginatedList<Subscription>>> {
|
||||||
|
|
||||||
const optionsWithObject = Object.assign(new FindListOptions(), {
|
const optionsWithObject = Object.assign(new FindListOptions(), {
|
||||||
searchParams: [
|
searchParams: [
|
||||||
@@ -160,7 +160,14 @@ export class SubscriptionService extends IdentifiableDataService<Subscription> {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.searchData.searchBy(this.findByEpersonLinkPath, optionsWithObject, true, true, followLink('dSpaceObject'), followLink('ePerson'));
|
// return this.searchData.searchBy(this.findByEpersonLinkPath, optionsWithObject, true, true, followLink('dSpaceObject'), followLink('ePerson'));
|
||||||
|
|
||||||
|
return this.getEndpoint().pipe(
|
||||||
|
map(href => `${href}/search/${this.findByEpersonLinkPath}`),
|
||||||
|
switchMap(href => this.findListByHref(href, optionsWithObject, true, true, followLink('dSpaceObject'), followLink('ePerson')))
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,16 +2,16 @@ import { NgModule } from '@angular/core';
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
import { SubscriptionViewComponent } from './components/subscription-view/subscription-view.component';
|
import { SubscriptionViewComponent } from './subscription-view/subscription-view.component';
|
||||||
import { SubscriptionModalComponent } from './components/subscription-modal/subscription-modal.component';
|
import { SubscriptionModalComponent } from './subscription-modal/subscription-modal.component';
|
||||||
import { SubscriptionEditModalComponent } from './components/subscription-edit-modal/subscription-edit-modal.component';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { SharedModule } from '../shared.module';
|
||||||
|
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
SubscriptionViewComponent,
|
SubscriptionViewComponent,
|
||||||
SubscriptionModalComponent,
|
SubscriptionModalComponent
|
||||||
SubscriptionEditModalComponent,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -20,12 +20,15 @@ const COMPONENTS = [
|
|||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
NgbModalModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
RouterModule
|
RouterModule,
|
||||||
|
SharedModule
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
...COMPONENTS
|
...COMPONENTS
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SubscriptionsModule { }
|
export class SubscriptionsModule {
|
||||||
|
}
|
||||||
|
@@ -4435,7 +4435,7 @@ export const findByEPersonAndDsoResEmpty = {
|
|||||||
'page': []
|
'page': []
|
||||||
};
|
};
|
||||||
|
|
||||||
export const subscription = {
|
export const subscriptionMock = {
|
||||||
'id': 21,
|
'id': 21,
|
||||||
'type': 'subscription',
|
'type': 'subscription',
|
||||||
'subscriptionParameterList': [
|
'subscriptionParameterList': [
|
||||||
@@ -4450,18 +4450,41 @@ export const subscription = {
|
|||||||
'value': 'M'
|
'value': 'M'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'subscriptionType': 'content',
|
'subscriptionType': 'test1',
|
||||||
'_links': {
|
'_links': {
|
||||||
'dSpaceObject': {
|
'dSpaceObject': {
|
||||||
'href': 'https://dspacecris7.4science.cloud/server/api/core/subscriptions/21/dSpaceObject'
|
'href': 'https://dspace/server/api/core/subscriptions/21/dSpaceObject'
|
||||||
},
|
},
|
||||||
'ePerson': {
|
'ePerson': {
|
||||||
'href': 'https://dspacecris7.4science.cloud/server/api/core/subscriptions/21/ePerson'
|
'href': 'https://dspace/server/api/core/subscriptions/21/ePerson'
|
||||||
},
|
},
|
||||||
'self': {
|
'self': {
|
||||||
'href': 'https://dspacecris7.4science.cloud/server/api/core/subscriptions/21'
|
'href': 'https://dspace/server/api/core/subscriptions/21'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const subscriptionMock2 = {
|
||||||
|
'id': 21,
|
||||||
|
'type': 'subscription',
|
||||||
|
'subscriptionParameterList': [
|
||||||
|
{
|
||||||
|
'id': 77,
|
||||||
|
'name': 'frequency',
|
||||||
|
'value': 'D'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'subscriptionType': 'test2',
|
||||||
|
'_links': {
|
||||||
|
'dSpaceObject': {
|
||||||
|
'href': 'https://dspacecris7.4science.cloud/server/api/core/subscriptions/21/dSpaceObject'
|
||||||
|
},
|
||||||
|
'ePerson': {
|
||||||
|
'href': 'https://dspacecris7.4science.cloud/server/api/core/subscriptions/21/ePerson'
|
||||||
|
},
|
||||||
|
'self': {
|
||||||
|
'href': 'https://dspacecris7.4science.cloud/server/api/core/subscriptions/21'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -4,13 +4,12 @@
|
|||||||
<h2>{{'subscriptions.title' | translate}}</h2>
|
<h2>{{'subscriptions.title' | translate}}</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12 m-40">
|
<div class="col-md-12 m-40">
|
||||||
<ds-loading *ngIf="loading$ | async"></ds-loading>
|
<ds-themed-loading *ngIf="loading$ | async"></ds-themed-loading>
|
||||||
<ng-container *ngVar="(subscriptions$ | async) as subscriptions">
|
<ng-container *ngVar="(subscriptions$ | async) as subscriptions">
|
||||||
|
|
||||||
<ds-pagination
|
<ds-pagination
|
||||||
*ngIf="subscriptions?.pageInfo?.totalElements > 0 && !(loading$ | async)"
|
*ngIf="subscriptions?.pageInfo?.totalElements > 0 && !(loading$ | async)"
|
||||||
[paginationOptions]="config"
|
[paginationOptions]="config"
|
||||||
[pageInfoState]="obs(subscriptions?.pageInfo)"
|
|
||||||
[collectionSize]="subscriptions?.pageInfo?.totalPages"
|
[collectionSize]="subscriptions?.pageInfo?.totalPages"
|
||||||
[hideGear]="true"
|
[hideGear]="true"
|
||||||
[hidePagerWhenSinglePage]="true">
|
[hidePagerWhenSinglePage]="true">
|
||||||
@@ -25,16 +24,20 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ds-subscription-view *ngFor="let subscription of subscriptions?.page" [eperson]="subscription?._embedded?.ePerson.id" [dso]="subscription?._embedded?.dSpaceObject" [subscription]="subscription" (reload)="refresh()">
|
<tr ds-subscription-view *ngFor="let subscription of subscriptions?.page"
|
||||||
|
[dso]="(subscription?.dSpaceObject | async)?.payload"
|
||||||
|
[eperson]="(subscription?.ePerson | async)?.payload?.id"
|
||||||
|
[subscription]="subscription"
|
||||||
|
(reload)="refresh()">
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</ds-pagination>
|
</ds-pagination>
|
||||||
|
|
||||||
<div *ngIf="subscriptions?.pageInfo?.totalElements == 0 && !(loading$ | async)">
|
<ds-alert *ngIf="subscriptions?.pageInfo?.totalElements == 0 && !(loading$ | async)" [type]="'alert-info'">
|
||||||
{{ 'subscriptions.table.empty.message' | translate }}
|
{{ 'subscriptions.table.empty.message' | translate }}
|
||||||
</div>
|
</ds-alert>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { BehaviorSubject, combineLatestWith, Observable, of, shareReplay, Subscription as rxSubscription } from 'rxjs';
|
|
||||||
import { combineLatest, map, switchMap, take, tap } from 'rxjs/operators';
|
import { BehaviorSubject, combineLatestWith, Observable, shareReplay } from 'rxjs';
|
||||||
|
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { Subscription } from '../shared/subscriptions/models/subscription.model';
|
import { Subscription } from '../shared/subscriptions/models/subscription.model';
|
||||||
import { buildPaginatedList, PaginatedList } from '../core/data/paginated-list.model';
|
import { buildPaginatedList, PaginatedList } from '../core/data/paginated-list.model';
|
||||||
import { SubscriptionService } from '../shared/subscriptions/subscription.service';
|
import { SubscriptionService } from '../shared/subscriptions/subscription.service';
|
||||||
@@ -16,7 +18,7 @@ import { getFirstSucceededRemoteDataPayload } from '../core/shared/operators';
|
|||||||
templateUrl: './subscriptions-page.component.html',
|
templateUrl: './subscriptions-page.component.html',
|
||||||
styleUrls: ['./subscriptions-page.component.scss']
|
styleUrls: ['./subscriptions-page.component.scss']
|
||||||
})
|
})
|
||||||
export class SubscriptionsPageComponent implements OnInit, OnDestroy {
|
export class SubscriptionsPageComponent implements OnInit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The subscriptions to show on this page, as an Observable list.
|
* The subscriptions to show on this page, as an Observable list.
|
||||||
@@ -33,11 +35,6 @@ export class SubscriptionsPageComponent implements OnInit, OnDestroy {
|
|||||||
currentPage: 1
|
currentPage: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscription to be unsubscribed
|
|
||||||
*/
|
|
||||||
sub: rxSubscription;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A boolean representing if is loading
|
* A boolean representing if is loading
|
||||||
*/
|
*/
|
||||||
@@ -69,7 +66,11 @@ export class SubscriptionsPageComponent implements OnInit, OnDestroy {
|
|||||||
this.ePersonId = ePersonId;
|
this.ePersonId = ePersonId;
|
||||||
}),*/
|
}),*/
|
||||||
);
|
);
|
||||||
const currentPagination$ = this.paginationService.getCurrentPagination(this.config.id, this.config).pipe(
|
this.retrieveSubscriptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private retrieveSubscriptions() {
|
||||||
|
this.paginationService.getCurrentPagination(this.config.id, this.config).pipe(
|
||||||
tap(console.log),
|
tap(console.log),
|
||||||
combineLatestWith(this.ePersonId$),
|
combineLatestWith(this.ePersonId$),
|
||||||
tap(() => {this.loading$.next(true);}),
|
tap(() => {this.loading$.next(true);}),
|
||||||
@@ -77,10 +78,12 @@ export class SubscriptionsPageComponent implements OnInit, OnDestroy {
|
|||||||
currentPage: currentPagination.currentPage,
|
currentPage: currentPagination.currentPage,
|
||||||
elementsPerPage: currentPagination.pageSize
|
elementsPerPage: currentPagination.pageSize
|
||||||
})),
|
})),
|
||||||
|
getFirstSucceededRemoteDataPayload(),
|
||||||
tap((x) => console.log('find', x)),
|
tap((x) => console.log('find', x)),
|
||||||
// getFirstSucceededRemoteDataPayload(),
|
// getFirstSucceededRemoteDataPayload(),
|
||||||
).subscribe({
|
).subscribe({
|
||||||
next: (res: any) => {
|
next: (res: any) => {
|
||||||
|
console.log('next',res);
|
||||||
this.subscriptions$.next(res);
|
this.subscriptions$.next(res);
|
||||||
this.loading$.next(false);
|
this.loading$.next(false);
|
||||||
},
|
},
|
||||||
@@ -89,41 +92,11 @@ export class SubscriptionsPageComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When an action is made and the information is changed refresh the information
|
* When an action is made and the information is changed refresh the information
|
||||||
*/
|
*/
|
||||||
refresh(): void {
|
refresh(): void {
|
||||||
/*this.paginationService.getCurrentPagination(this.config.id, this.config).pipe(
|
this.retrieveSubscriptions();
|
||||||
take(1),
|
|
||||||
switchMap((findListOptions) => {
|
|
||||||
this.loading$.next(true);
|
|
||||||
return this.subscriptionService.findByEPerson(this.ePersonId,{
|
|
||||||
currentPage: findListOptions.currentPage,
|
|
||||||
elementsPerPage: findListOptions.pageSize
|
|
||||||
});
|
|
||||||
}
|
|
||||||
)
|
|
||||||
).subscribe({
|
|
||||||
next: (res: any) => {
|
|
||||||
this.subscriptions$.next(res);
|
|
||||||
this.loading$.next(false);
|
|
||||||
},
|
|
||||||
error: () => {
|
|
||||||
this.loading$.next(false);
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribe from pagination subscription
|
|
||||||
*/
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this.sub.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
obs(v) {
|
|
||||||
return of(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1450,6 +1450,13 @@
|
|||||||
|
|
||||||
"confirmation-modal.delete-profile.confirm": "Delete",
|
"confirmation-modal.delete-profile.confirm": "Delete",
|
||||||
|
|
||||||
|
"confirmation-modal.delete-subscription.header": "Delete Subscription",
|
||||||
|
|
||||||
|
"confirmation-modal.delete-subscription.info": "Are you sure you want to delete subscription for \"{{ dsoName }}\"",
|
||||||
|
|
||||||
|
"confirmation-modal.delete-subscription.cancel": "Cancel",
|
||||||
|
|
||||||
|
"confirmation-modal.delete-subscription.confirm": "Delete",
|
||||||
|
|
||||||
"error.bitstream": "Error fetching bitstream",
|
"error.bitstream": "Error fetching bitstream",
|
||||||
|
|
||||||
@@ -4512,6 +4519,20 @@
|
|||||||
|
|
||||||
"subscriptions.frequency.W": "Weekly",
|
"subscriptions.frequency.W": "Weekly",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"subscriptions.modal.create.success": "Subscribed to {{ type }} successfully.",
|
||||||
|
|
||||||
|
"subscriptions.modal.delete.success": "Subscription deleted successfully",
|
||||||
|
|
||||||
|
"subscriptions.modal.update.success": "Subscription to {{ type }} updated successfully",
|
||||||
|
|
||||||
|
"subscriptions.modal.create.error": "An error occurs during the subscription creation",
|
||||||
|
|
||||||
|
"subscriptions.modal.delete.error": "An error occurs during the subscription delete",
|
||||||
|
|
||||||
|
"subscriptions.modal.update.error": "An error occurs during the subscription update",
|
||||||
|
|
||||||
"subscriptions.table.dso": "Subject",
|
"subscriptions.table.dso": "Subject",
|
||||||
|
|
||||||
"subscriptions.table.subscription_type": "Subscription Type",
|
"subscriptions.table.subscription_type": "Subscription Type",
|
||||||
|
Reference in New Issue
Block a user