diff --git a/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-data.reslover.ts b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-data.reslover.ts new file mode 100644 index 0000000000..114f5f7df1 --- /dev/null +++ b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-data.reslover.ts @@ -0,0 +1,45 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot, Router } from '@angular/router'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { NotificationsBrokerSourceObject } from '../../../core/notifications/broker/models/notifications-broker-source.model'; +import { NotificationsBrokerSourceService } from '../../../notifications/broker/source/notifications-broker-source.service'; +/** + * This class represents a resolver that retrieve the route data before the route is activated. + */ +@Injectable() +export class SourceDataResolver implements Resolve> { + /** + * Initialize the effect class variables. + * @param {NotificationsBrokerSourceService} notificationsBrokerSourceService + */ + constructor( + private notificationsBrokerSourceService: NotificationsBrokerSourceService, + private router: Router + ) { } + /** + * Method for resolving the parameters in the current route. + * @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot + * @param {RouterStateSnapshot} state The current RouterStateSnapshot + * @returns Observable + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { + return this.notificationsBrokerSourceService.getSources(5,0).pipe( + map((sources: PaginatedList) => { + if (sources.page.length === 1) { + this.router.navigate([this.getResolvedUrl(route) + '/' + sources.page[0].id]); + } + return sources.page; + })); + } + + /** + * + * @param route url path + * @returns url path + */ + getResolvedUrl(route: ActivatedRouteSnapshot): string { + return route.pathFromRoot.map(v => v.url.map(segment => segment.toString()).join('/')).join('/'); + } +} diff --git a/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page-resolver.service.ts b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page-resolver.service.ts new file mode 100644 index 0000000000..8450e20c3c --- /dev/null +++ b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page-resolver.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; + +/** + * Interface for the route parameters. + */ +export interface AdminNotificationsBrokerSourcePageParams { + pageId?: string; + pageSize?: number; + currentPage?: number; +} + +/** + * This class represents a resolver that retrieve the route data before the route is activated. + */ +@Injectable() +export class AdminNotificationsBrokerSourcePageResolver implements Resolve { + + /** + * Method for resolving the parameters in the current route. + * @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot + * @param {RouterStateSnapshot} state The current RouterStateSnapshot + * @returns AdminNotificationsBrokerSourcePageParams Emits the route parameters + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): AdminNotificationsBrokerSourcePageParams { + return { + pageId: route.queryParams.pageId, + pageSize: parseInt(route.queryParams.pageSize, 10), + currentPage: parseInt(route.queryParams.page, 10) + }; + } +} diff --git a/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.html b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.html new file mode 100644 index 0000000000..57f635d5da --- /dev/null +++ b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.html @@ -0,0 +1 @@ + diff --git a/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.spec.ts b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.spec.ts new file mode 100644 index 0000000000..c4a3611c58 --- /dev/null +++ b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminNotificationsBrokerSourcePageComponent } from './admin-notifications-broker-source-page.component'; + +describe('AdminNotificationsBrokerSourcePageComponent', () => { + let component: AdminNotificationsBrokerSourcePageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AdminNotificationsBrokerSourcePageComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AdminNotificationsBrokerSourcePageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.ts b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.ts new file mode 100644 index 0000000000..1ec0894827 --- /dev/null +++ b/src/app/admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component.ts @@ -0,0 +1,7 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'ds-admin-notifications-broker-source-page-component', + templateUrl: './admin-notifications-broker-source-page.component.html', +}) +export class AdminNotificationsBrokerSourcePageComponent {} diff --git a/src/app/admin/admin-notifications/admin-notifications-routing.module.ts b/src/app/admin/admin-notifications/admin-notifications-routing.module.ts index f1f46ca4f1..4e5997e203 100644 --- a/src/app/admin/admin-notifications/admin-notifications-routing.module.ts +++ b/src/app/admin/admin-notifications/admin-notifications-routing.module.ts @@ -9,13 +9,16 @@ import { AdminNotificationsBrokerTopicsPageComponent } from './admin-notificatio import { AdminNotificationsBrokerEventsPageComponent } from './admin-notifications-broker-events-page/admin-notifications-broker-events-page.component'; import { AdminNotificationsBrokerTopicsPageResolver } from './admin-notifications-broker-topics-page/admin-notifications-broker-topics-page-resolver.service'; import { AdminNotificationsBrokerEventsPageResolver } from './admin-notifications-broker-events-page/admin-notifications-broker-events-page.resolver'; +import { AdminNotificationsBrokerSourcePageComponent } from './admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component'; +import { AdminNotificationsBrokerSourcePageResolver } from './admin-notifications-broker-source-page-component/admin-notifications-broker-source-page-resolver.service'; +import { SourceDataResolver } from './admin-notifications-broker-source-page-component/admin-notifications-broker-source-data.reslover'; @NgModule({ imports: [ RouterModule.forChild([ { canActivate: [ AuthenticatedGuard ], - path: `${NOTIFICATIONS_EDIT_PATH}`, + path: `${NOTIFICATIONS_EDIT_PATH}/:sourceId`, component: AdminNotificationsBrokerTopicsPageComponent, pathMatch: 'full', resolve: { @@ -30,7 +33,23 @@ import { AdminNotificationsBrokerEventsPageResolver } from './admin-notification }, { canActivate: [ AuthenticatedGuard ], - path: `${NOTIFICATIONS_EDIT_PATH}/:id`, + path: `${NOTIFICATIONS_EDIT_PATH}`, + component: AdminNotificationsBrokerSourcePageComponent, + pathMatch: 'full', + resolve: { + breadcrumb: I18nBreadcrumbResolver, + openaireBrokerSourceParams: AdminNotificationsBrokerSourcePageResolver, + sourceData: SourceDataResolver + }, + data: { + title: 'admin.notifications.source.breadcrumbs', + breadcrumbKey: 'admin.notifications.source', + showBreadcrumbsFluid: false + } + }, + { + canActivate: [ AuthenticatedGuard ], + path: `${NOTIFICATIONS_EDIT_PATH}/:sourceId/:topicId`, component: AdminNotificationsBrokerEventsPageComponent, pathMatch: 'full', resolve: { @@ -48,8 +67,10 @@ import { AdminNotificationsBrokerEventsPageResolver } from './admin-notification providers: [ I18nBreadcrumbResolver, I18nBreadcrumbsService, + SourceDataResolver, AdminNotificationsBrokerTopicsPageResolver, - AdminNotificationsBrokerEventsPageResolver + AdminNotificationsBrokerEventsPageResolver, + AdminNotificationsBrokerSourcePageResolver ] }) /** diff --git a/src/app/admin/admin-notifications/admin-notifications.module.ts b/src/app/admin/admin-notifications/admin-notifications.module.ts index 350e9de800..6351498dc5 100644 --- a/src/app/admin/admin-notifications/admin-notifications.module.ts +++ b/src/app/admin/admin-notifications/admin-notifications.module.ts @@ -6,6 +6,7 @@ import { AdminNotificationsRoutingModule } from './admin-notifications-routing.m import { AdminNotificationsBrokerTopicsPageComponent } from './admin-notifications-broker-topics-page/admin-notifications-broker-topics-page.component'; import { AdminNotificationsBrokerEventsPageComponent } from './admin-notifications-broker-events-page/admin-notifications-broker-events-page.component'; import { NotificationsModule } from '../../notifications/notifications.module'; +import { AdminNotificationsBrokerSourcePageComponent } from './admin-notifications-broker-source-page-component/admin-notifications-broker-source-page.component'; @NgModule({ imports: [ @@ -17,7 +18,8 @@ import { NotificationsModule } from '../../notifications/notifications.module'; ], declarations: [ AdminNotificationsBrokerTopicsPageComponent, - AdminNotificationsBrokerEventsPageComponent + AdminNotificationsBrokerEventsPageComponent, + AdminNotificationsBrokerSourcePageComponent ], entryComponents: [] }) diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index f5a959592f..31b405e31c 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -164,6 +164,7 @@ import { GroupDataService } from './eperson/group-data.service'; import { SubmissionAccessesModel } from './config/models/config-submission-accesses.model'; import { NotificationsBrokerTopicObject } from './notifications/broker/models/notifications-broker-topic.model'; import { NotificationsBrokerEventObject } from './notifications/broker/models/notifications-broker-event.model'; +import { NotificationsBrokerSourceObject } from './notifications/broker/models/notifications-broker-source.model'; /** * When not in production, endpoint responses can be mocked for testing purposes @@ -349,7 +350,8 @@ export const models = NotificationsBrokerEventObject, Root, SearchConfig, - SubmissionAccessesModel + SubmissionAccessesModel, + NotificationsBrokerSourceObject ]; @NgModule({ diff --git a/src/app/core/notifications/broker/models/notifications-broker-event.model.ts b/src/app/core/notifications/broker/models/notifications-broker-event.model.ts index ed73168e6d..4df326f325 100644 --- a/src/app/core/notifications/broker/models/notifications-broker-event.model.ts +++ b/src/app/core/notifications/broker/models/notifications-broker-event.model.ts @@ -20,7 +20,7 @@ export interface NotificationsBrokerEventMessageObject { /** * The interface representing the Notifications Broker event message */ -export interface OpenaireBrokerEventMessageObject{ +export interface OpenaireBrokerEventMessageObject { /** * The type of 'value' */ diff --git a/src/app/core/notifications/broker/models/notifications-broker-source-object.resource-type.ts b/src/app/core/notifications/broker/models/notifications-broker-source-object.resource-type.ts new file mode 100644 index 0000000000..e3d10dc5ab --- /dev/null +++ b/src/app/core/notifications/broker/models/notifications-broker-source-object.resource-type.ts @@ -0,0 +1,9 @@ +import { ResourceType } from '../../../shared/resource-type'; + +/** + * The resource type for the Notifications Broker source + * + * Needs to be in a separate file to prevent circular + * dependencies in webpack. + */ +export const NOTIFICATIONS_BROKER_SOURCE_OBJECT = new ResourceType('nbsource'); diff --git a/src/app/core/notifications/broker/models/notifications-broker-source.model.ts b/src/app/core/notifications/broker/models/notifications-broker-source.model.ts new file mode 100644 index 0000000000..3f18c3affb --- /dev/null +++ b/src/app/core/notifications/broker/models/notifications-broker-source.model.ts @@ -0,0 +1,52 @@ +import { autoserialize, deserialize } from 'cerialize'; + +import { CacheableObject } from '../../../cache/object-cache.reducer'; +import { excludeFromEquals } from '../../../utilities/equals.decorators'; +import { ResourceType } from '../../../shared/resource-type'; +import { HALLink } from '../../../shared/hal-link.model'; +import { typedObject } from '../../../cache/builders/build-decorators'; +import { NOTIFICATIONS_BROKER_SOURCE_OBJECT } from './notifications-broker-source-object.resource-type'; + +/** + * The interface representing the Notifications Broker source model + */ +@typedObject +export class NotificationsBrokerSourceObject implements CacheableObject { + /** + * A string representing the kind of object, e.g. community, item, … + */ + static type = NOTIFICATIONS_BROKER_SOURCE_OBJECT; + + /** + * The Notifications Broker source id + */ + @autoserialize + id: string; + + /** + * The date of the last udate from Notifications + */ + @autoserialize + lastEvent: string; + + /** + * The total number of suggestions provided by Notifications for this source + */ + @autoserialize + totalEvents: number; + + /** + * The type of this ConfigObject + */ + @excludeFromEquals + @autoserialize + type: ResourceType; + + /** + * The links to all related resources returned by the rest api. + */ + @deserialize + _links: { + self: HALLink, + }; +} diff --git a/src/app/core/notifications/broker/source/notifications-broker-source-rest.service.ts b/src/app/core/notifications/broker/source/notifications-broker-source-rest.service.ts new file mode 100644 index 0000000000..ebbbe995d1 --- /dev/null +++ b/src/app/core/notifications/broker/source/notifications-broker-source-rest.service.ts @@ -0,0 +1,133 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Store } from '@ngrx/store'; + +import { Observable } from 'rxjs'; +import { mergeMap, take } from 'rxjs/operators'; + +import { CoreState } from '../../../core.reducers'; +import { HALEndpointService } from '../../../shared/hal-endpoint.service'; +import { NotificationsService } from '../../../../shared/notifications/notifications.service'; +import { RemoteDataBuildService } from '../../../cache/builders/remote-data-build.service'; +import { ObjectCacheService } from '../../../cache/object-cache.service'; +import { dataService } from '../../../cache/builders/build-decorators'; +import { RequestService } from '../../../data/request.service'; +import { FindListOptions } from '../../../data/request.models'; +import { DataService } from '../../../data/data.service'; +import { ChangeAnalyzer } from '../../../data/change-analyzer'; +import { DefaultChangeAnalyzer } from '../../../data/default-change-analyzer.service'; +import { RemoteData } from '../../../data/remote-data'; +import { NotificationsBrokerSourceObject } from '../models/notifications-broker-source.model'; +import { NOTIFICATIONS_BROKER_SOURCE_OBJECT } from '../models/notifications-broker-source-object.resource-type'; +import { FollowLinkConfig } from '../../../../shared/utils/follow-link-config.model'; +import { PaginatedList } from '../../../data/paginated-list.model'; + +/* tslint:disable:max-classes-per-file */ + +/** + * A private DataService implementation to delegate specific methods to. + */ +class DataServiceImpl extends DataService { + /** + * The REST endpoint. + */ + protected linkPath = 'nbsources'; + + /** + * Initialize service variables + * @param {RequestService} requestService + * @param {RemoteDataBuildService} rdbService + * @param {Store} store + * @param {ObjectCacheService} objectCache + * @param {HALEndpointService} halService + * @param {NotificationsService} notificationsService + * @param {HttpClient} http + * @param {ChangeAnalyzer} comparator + */ + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected store: Store, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + protected http: HttpClient, + protected comparator: ChangeAnalyzer) { + super(); + } +} + +/** + * The service handling all Notifications Broker source REST requests. + */ +@Injectable() +@dataService(NOTIFICATIONS_BROKER_SOURCE_OBJECT) +export class NotificationsBrokerSourceRestService { + /** + * A private DataService implementation to delegate specific methods to. + */ + private dataService: DataServiceImpl; + + /** + * Initialize service variables + * @param {RequestService} requestService + * @param {RemoteDataBuildService} rdbService + * @param {ObjectCacheService} objectCache + * @param {HALEndpointService} halService + * @param {NotificationsService} notificationsService + * @param {HttpClient} http + * @param {DefaultChangeAnalyzer} comparator + */ + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + protected http: HttpClient, + protected comparator: DefaultChangeAnalyzer) { + this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator); + } + + /** + * Return the list of Notifications Broker source. + * + * @param options + * Find list options object. + * @param linksToFollow + * List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved. + * @return Observable>> + * The list of Notifications Broker source. + */ + public getSources(options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.dataService.getBrowseEndpoint(options, 'nbsources').pipe( + take(1), + mergeMap((href: string) => this.dataService.findAllByHref(href, options, true, true, ...linksToFollow)), + ); + } + + /** + * Clear FindAll source requests from cache + */ + public clearFindAllSourceRequests() { + this.requestService.setStaleByHrefSubstring('nbsources'); + } + + /** + * Return a single Notifications Broker source. + * + * @param id + * The Notifications Broker source id + * @param linksToFollow + * List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved. + * @return Observable> + * The Notifications Broker source. + */ + public getSource(id: string, ...linksToFollow: FollowLinkConfig[]): Observable> { + const options = {}; + return this.dataService.getBrowseEndpoint(options, 'nbsources').pipe( + take(1), + mergeMap((href: string) => this.dataService.findByHref(href + '/' + id, true, true, ...linksToFollow)) + ); + } +} diff --git a/src/app/notifications/broker/events/notifications-broker-events.component.ts b/src/app/notifications/broker/events/notifications-broker-events.component.ts index b416664fca..7639554c55 100644 --- a/src/app/notifications/broker/events/notifications-broker-events.component.ts +++ b/src/app/notifications/broker/events/notifications-broker-events.component.ts @@ -135,7 +135,7 @@ export class NotificationsBrokerEventsComponent implements OnInit { this.isEventPageLoading.next(true); this.activatedRoute.paramMap.pipe( - map((params) => params.get('id')), + map((params) => params.get('topicId')), take(1) ).subscribe((id: string) => { const regEx = /!/g; diff --git a/src/app/notifications/broker/source/notifications-broker-source.actions.ts b/src/app/notifications/broker/source/notifications-broker-source.actions.ts new file mode 100644 index 0000000000..a3fd9240c8 --- /dev/null +++ b/src/app/notifications/broker/source/notifications-broker-source.actions.ts @@ -0,0 +1,99 @@ +import { Action } from '@ngrx/store'; +import { type } from '../../../shared/ngrx/type'; +import { NotificationsBrokerSourceObject } from '../../../core/notifications/broker/models/notifications-broker-source.model'; + +/** + * For each action type in an action group, make a simple + * enum object for all of this group's action types. + * + * The 'type' utility function coerces strings into string + * literal types and runs a simple check to guarantee all + * action types in the application are unique. + */ +export const NotificationsBrokerSourceActionTypes = { + ADD_SOURCE: type('dspace/integration/notifications/broker/ADD_SOURCE'), + RETRIEVE_ALL_SOURCE: type('dspace/integration/notifications/broker/RETRIEVE_ALL_SOURCE'), + RETRIEVE_ALL_SOURCE_ERROR: type('dspace/integration/notifications/broker/RETRIEVE_ALL_SOURCE_ERROR'), +}; + +/* tslint:disable:max-classes-per-file */ + +/** + * An ngrx action to retrieve all the Notifications Broker source. + */ +export class RetrieveAllSourceAction implements Action { + type = NotificationsBrokerSourceActionTypes.RETRIEVE_ALL_SOURCE; + payload: { + elementsPerPage: number; + currentPage: number; + }; + + /** + * Create a new RetrieveAllSourceAction. + * + * @param elementsPerPage + * the number of source per page + * @param currentPage + * The page number to retrieve + */ + constructor(elementsPerPage: number, currentPage: number) { + this.payload = { + elementsPerPage, + currentPage + }; + } +} + +/** + * An ngrx action for retrieving 'all Notifications Broker source' error. + */ +export class RetrieveAllSourceErrorAction implements Action { + type = NotificationsBrokerSourceActionTypes.RETRIEVE_ALL_SOURCE_ERROR; +} + +/** + * An ngrx action to load the Notifications Broker source objects. + * Called by the ??? effect. + */ +export class AddSourceAction implements Action { + type = NotificationsBrokerSourceActionTypes.ADD_SOURCE; + payload: { + source: NotificationsBrokerSourceObject[]; + totalPages: number; + currentPage: number; + totalElements: number; + }; + + /** + * Create a new AddSourceAction. + * + * @param source + * the list of source + * @param totalPages + * the total available pages of source + * @param currentPage + * the current page + * @param totalElements + * the total available Notifications Broker source + */ + constructor(source: NotificationsBrokerSourceObject[], totalPages: number, currentPage: number, totalElements: number) { + this.payload = { + source, + totalPages, + currentPage, + totalElements + }; + } + +} + +/* tslint:enable:max-classes-per-file */ + +/** + * Export a type alias of all actions in this action group + * so that reducers can easily compose action types. + */ +export type NotificationsBrokerSourceActions + = RetrieveAllSourceAction + |RetrieveAllSourceErrorAction + |AddSourceAction; diff --git a/src/app/notifications/broker/source/notifications-broker-source.component.html b/src/app/notifications/broker/source/notifications-broker-source.component.html new file mode 100644 index 0000000000..a7e1e52748 --- /dev/null +++ b/src/app/notifications/broker/source/notifications-broker-source.component.html @@ -0,0 +1,58 @@ +
+
+
+

{{'notifications.broker.title'| translate}}

+

{{'notifications.broker.source.description'| translate}}

+
+
+
+
+

{{'notifications.broker.source'| translate}}

+ + + + + + + +
+ + + + + + + + + + + + + + + +
{{'notifications.broker.table.source' | translate}}{{'notifications.broker.table.last-event' | translate}}{{'notifications.broker.table.actions' | translate}}
{{sourceElement.id}}{{sourceElement.lastEvent}} +
+ +
+
+
+
+
+
+
+
+ diff --git a/src/app/notifications/broker/source/notifications-broker-source.component.scss b/src/app/notifications/broker/source/notifications-broker-source.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/notifications/broker/source/notifications-broker-source.component.spec.ts b/src/app/notifications/broker/source/notifications-broker-source.component.spec.ts new file mode 100644 index 0000000000..7d18c726c5 --- /dev/null +++ b/src/app/notifications/broker/source/notifications-broker-source.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NotificationsBrokerSourceComponent } from './notifications-broker-source.component'; + +describe('NotificationsBrokerSourceComponent', () => { + let component: NotificationsBrokerSourceComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ NotificationsBrokerSourceComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NotificationsBrokerSourceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/notifications/broker/source/notifications-broker-source.component.ts b/src/app/notifications/broker/source/notifications-broker-source.component.ts new file mode 100644 index 0000000000..070e03f396 --- /dev/null +++ b/src/app/notifications/broker/source/notifications-broker-source.component.ts @@ -0,0 +1,139 @@ +import { Component, OnInit } from '@angular/core'; +import { PaginationService } from '../../../core/pagination/pagination.service'; +import { Observable, Subscription } from 'rxjs'; +import { distinctUntilChanged, take } from 'rxjs/operators'; +import { SortOptions } from '../../../core/cache/models/sort-options.model'; +import { NotificationsBrokerSourceObject } from '../../../core/notifications/broker/models/notifications-broker-source.model'; +import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; +import { NotificationsStateService } from '../../notifications-state.service'; +import { AdminNotificationsBrokerSourcePageParams } from '../../../admin/admin-notifications/admin-notifications-broker-source-page-component/admin-notifications-broker-source-page-resolver.service'; +import { hasValue } from '../../../shared/empty.util'; + +@Component({ + selector: 'ds-notifications-broker-source', + templateUrl: './notifications-broker-source.component.html', + styleUrls: ['./notifications-broker-source.component.scss'] +}) +export class NotificationsBrokerSourceComponent implements OnInit { + + /** + * The pagination system configuration for HTML listing. + * @type {PaginationComponentOptions} + */ + public paginationConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), { + id: 'btp', + pageSize: 10, + pageSizeOptions: [5, 10, 20, 40, 60] + }); + /** + * The Notifications Broker source list sort options. + * @type {SortOptions} + */ + public paginationSortConfig: SortOptions; + /** + * The Notifications Broker source list. + */ + public sources$: Observable; + /** + * The total number of Notifications Broker sources. + */ + public totalElements$: Observable; + /** + * Array to track all the component subscriptions. Useful to unsubscribe them with 'onDestroy'. + * @type {Array} + */ + protected subs: Subscription[] = []; + + /** + * Initialize the component variables. + * @param {PaginationService} paginationService + * @param {NotificationsStateService} notificationsStateService + */ + constructor( + private paginationService: PaginationService, + private notificationsStateService: NotificationsStateService, + ) { } + + /** + * Component initialization. + */ + ngOnInit(): void { + this.sources$ = this.notificationsStateService.getNotificationsBrokerSource(); + this.totalElements$ = this.notificationsStateService.getNotificationsBrokerSourceTotals(); + } + + /** + * First Notifications Broker source loading after view initialization. + */ + ngAfterViewInit(): void { + this.subs.push( + this.notificationsStateService.isNotificationsBrokerSourceLoaded().pipe( + take(1) + ).subscribe(() => { + this.getNotificationsBrokerSource(); + }) + ); + } + + /** + * Returns the information about the loading status of the Notifications Broker source (if it's running or not). + * + * @return Observable + * 'true' if the source are loading, 'false' otherwise. + */ + public isSourceLoading(): Observable { + return this.notificationsStateService.isNotificationsBrokerSourceLoading(); + } + + /** + * Returns the information about the processing status of the Notifications Broker source (if it's running or not). + * + * @return Observable + * 'true' if there are operations running on the source (ex.: a REST call), 'false' otherwise. + */ + public isSourceProcessing(): Observable { + return this.notificationsStateService.isNotificationsBrokerSourceProcessing(); + } + + /** + * Dispatch the Notifications Broker source retrival. + */ + public getNotificationsBrokerSource(): void { + this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig).pipe( + distinctUntilChanged(), + ).subscribe((options: PaginationComponentOptions) => { + this.notificationsStateService.dispatchRetrieveNotificationsBrokerSource( + options.pageSize, + options.currentPage + ); + }); + } + + /** + * Update pagination Config from route params + * + * @param eventsRouteParams + */ + protected updatePaginationFromRouteParams(eventsRouteParams: AdminNotificationsBrokerSourcePageParams) { + if (eventsRouteParams.currentPage) { + this.paginationConfig.currentPage = eventsRouteParams.currentPage; + } + if (eventsRouteParams.pageSize) { + if (this.paginationConfig.pageSizeOptions.includes(eventsRouteParams.pageSize)) { + this.paginationConfig.pageSize = eventsRouteParams.pageSize; + } else { + this.paginationConfig.pageSize = this.paginationConfig.pageSizeOptions[0]; + } + } + } + + /** + * Unsubscribe from all subscriptions. + */ + ngOnDestroy(): void { + this.subs + .filter((sub) => hasValue(sub)) + .forEach((sub) => sub.unsubscribe()); + } + +} diff --git a/src/app/notifications/broker/source/notifications-broker-source.effects.ts b/src/app/notifications/broker/source/notifications-broker-source.effects.ts new file mode 100644 index 0000000000..bd8b3f00cd --- /dev/null +++ b/src/app/notifications/broker/source/notifications-broker-source.effects.ts @@ -0,0 +1,87 @@ +import { Injectable } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { TranslateService } from '@ngx-translate/core'; +import { catchError, map, switchMap, tap, withLatestFrom } from 'rxjs/operators'; +import { of as observableOf } from 'rxjs'; +import { + AddSourceAction, + NotificationsBrokerSourceActionTypes, + RetrieveAllSourceAction, + RetrieveAllSourceErrorAction, +} from './notifications-broker-source.actions'; + +import { NotificationsBrokerSourceObject } from '../../../core/notifications/broker/models/notifications-broker-source.model'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { NotificationsBrokerSourceService } from './notifications-broker-source.service'; +import { NotificationsService } from '../../../shared/notifications/notifications.service'; +import { NotificationsBrokerSourceRestService } from '../../../core/notifications/broker/source/notifications-broker-source-rest.service'; + +/** + * Provides effect methods for the Notifications Broker source actions. + */ +@Injectable() +export class NotificationsBrokerSourceEffects { + + /** + * Retrieve all Notifications Broker source managing pagination and errors. + */ + @Effect() retrieveAllSource$ = this.actions$.pipe( + ofType(NotificationsBrokerSourceActionTypes.RETRIEVE_ALL_SOURCE), + withLatestFrom(this.store$), + switchMap(([action, currentState]: [RetrieveAllSourceAction, any]) => { + return this.notificationsBrokerSourceService.getSources( + action.payload.elementsPerPage, + action.payload.currentPage + ).pipe( + map((sources: PaginatedList) => + new AddSourceAction(sources.page, sources.totalPages, sources.currentPage, sources.totalElements) + ), + catchError((error: Error) => { + if (error) { + console.error(error.message); + } + return observableOf(new RetrieveAllSourceErrorAction()); + }) + ); + }) + ); + + /** + * Show a notification on error. + */ + @Effect({ dispatch: false }) retrieveAllSourceErrorAction$ = this.actions$.pipe( + ofType(NotificationsBrokerSourceActionTypes.RETRIEVE_ALL_SOURCE_ERROR), + tap(() => { + this.notificationsService.error(null, this.translate.get('notifications.broker.source.error.service.retrieve')); + }) + ); + + /** + * Clear find all source requests from cache. + */ + @Effect({ dispatch: false }) addSourceAction$ = this.actions$.pipe( + ofType(NotificationsBrokerSourceActionTypes.ADD_SOURCE), + tap(() => { + this.notificationsBrokerSourceDataService.clearFindAllSourceRequests(); + }) + ); + + /** + * Initialize the effect class variables. + * @param {Actions} actions$ + * @param {Store} store$ + * @param {TranslateService} translate + * @param {NotificationsService} notificationsService + * @param {NotificationsBrokerSourceService} notificationsBrokerSourceService + * @param {NotificationsBrokerSourceRestService} notificationsBrokerSourceDataService + */ + constructor( + private actions$: Actions, + private store$: Store, + private translate: TranslateService, + private notificationsService: NotificationsService, + private notificationsBrokerSourceService: NotificationsBrokerSourceService, + private notificationsBrokerSourceDataService: NotificationsBrokerSourceRestService + ) { } +} diff --git a/src/app/notifications/broker/source/notifications-broker-source.reducer.ts b/src/app/notifications/broker/source/notifications-broker-source.reducer.ts new file mode 100644 index 0000000000..5395796380 --- /dev/null +++ b/src/app/notifications/broker/source/notifications-broker-source.reducer.ts @@ -0,0 +1,72 @@ +import { NotificationsBrokerSourceObject } from '../../../core/notifications/broker/models/notifications-broker-source.model'; +import { NotificationsBrokerSourceActionTypes, NotificationsBrokerSourceActions } from './notifications-broker-source.actions'; + +/** + * The interface representing the Notifications Broker source state. + */ +export interface NotificationsBrokerSourceState { + source: NotificationsBrokerSourceObject[]; + processing: boolean; + loaded: boolean; + totalPages: number; + currentPage: number; + totalElements: number; +} + +/** + * Used for the Notifications Broker source state initialization. + */ +const notificationsBrokerSourceInitialState: NotificationsBrokerSourceState = { + source: [], + processing: false, + loaded: false, + totalPages: 0, + currentPage: 0, + totalElements: 0 +}; + +/** + * The Notifications Broker Source Reducer + * + * @param state + * the current state initialized with notificationsBrokerSourceInitialState + * @param action + * the action to perform on the state + * @return NotificationsBrokerSourceState + * the new state + */ +export function notificationsBrokerSourceReducer(state = notificationsBrokerSourceInitialState, action: NotificationsBrokerSourceActions): NotificationsBrokerSourceState { + switch (action.type) { + case NotificationsBrokerSourceActionTypes.RETRIEVE_ALL_SOURCE: { + return Object.assign({}, state, { + source: [], + processing: true + }); + } + + case NotificationsBrokerSourceActionTypes.ADD_SOURCE: { + return Object.assign({}, state, { + source: action.payload.source, + processing: false, + loaded: true, + totalPages: action.payload.totalPages, + currentPage: state.currentPage, + totalElements: action.payload.totalElements + }); + } + + case NotificationsBrokerSourceActionTypes.RETRIEVE_ALL_SOURCE_ERROR: { + return Object.assign({}, state, { + processing: false, + loaded: true, + totalPages: 0, + currentPage: 0, + totalElements: 0 + }); + } + + default: { + return state; + } + } +} diff --git a/src/app/notifications/broker/source/notifications-broker-source.service.ts b/src/app/notifications/broker/source/notifications-broker-source.service.ts new file mode 100644 index 0000000000..e80643049c --- /dev/null +++ b/src/app/notifications/broker/source/notifications-broker-source.service.ts @@ -0,0 +1,55 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { find, map } from 'rxjs/operators'; +import { NotificationsBrokerSourceRestService } from '../../../core/notifications/broker/source/notifications-broker-source-rest.service'; +import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; +import { FindListOptions } from '../../../core/data/request.models'; +import { RemoteData } from '../../../core/data/remote-data'; +import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { NotificationsBrokerSourceObject } from '../../../core/notifications/broker/models/notifications-broker-source.model'; + +/** + * The service handling all Notifications Broker source requests to the REST service. + */ +@Injectable() +export class NotificationsBrokerSourceService { + + /** + * Initialize the service variables. + * @param {NotificationsBrokerSourceRestService} notificationsBrokerSourceRestService + */ + constructor( + private notificationsBrokerSourceRestService: NotificationsBrokerSourceRestService + ) { } + + /** + * Return the list of Notifications Broker source managing pagination and errors. + * + * @param elementsPerPage + * The number of the source per page + * @param currentPage + * The page number to retrieve + * @return Observable> + * The list of Notifications Broker source. + */ + public getSources(elementsPerPage, currentPage): Observable> { + const sortOptions = new SortOptions('name', SortDirection.ASC); + + const findListOptions: FindListOptions = { + elementsPerPage: elementsPerPage, + currentPage: currentPage, + sort: sortOptions + }; + + return this.notificationsBrokerSourceRestService.getSources(findListOptions).pipe( + find((rd: RemoteData>) => !rd.isResponsePending), + map((rd: RemoteData>) => { + if (rd.hasSucceeded) { + return rd.payload; + } else { + throw new Error('Can\'t retrieve Notifications Broker source from the Broker source REST service'); + } + }) + ); + } +} diff --git a/src/app/notifications/broker/topics/notifications-broker-topics.component.html b/src/app/notifications/broker/topics/notifications-broker-topics.component.html index 02371a8a6b..8b27778ee9 100644 --- a/src/app/notifications/broker/topics/notifications-broker-topics.component.html +++ b/src/app/notifications/broker/topics/notifications-broker-topics.component.html @@ -2,7 +2,7 @@

{{'notifications.broker.title'| translate}}

-

{{'notifications.broker.topics.description'| translate}}

+

{{'notifications.broker.topics.description'| translate:{source: sourceId} }}

diff --git a/src/app/notifications/broker/topics/notifications-broker-topics.component.ts b/src/app/notifications/broker/topics/notifications-broker-topics.component.ts index 3bedf6b9d0..f33d3c2fb1 100644 --- a/src/app/notifications/broker/topics/notifications-broker-topics.component.ts +++ b/src/app/notifications/broker/topics/notifications-broker-topics.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; -import { distinctUntilChanged, take } from 'rxjs/operators'; +import { distinctUntilChanged, map, take } from 'rxjs/operators'; import { SortOptions } from '../../../core/cache/models/sort-options.model'; import { NotificationsBrokerTopicObject } from '../../../core/notifications/broker/models/notifications-broker-topic.model'; @@ -10,6 +10,8 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio import { NotificationsStateService } from '../../notifications-state.service'; import { AdminNotificationsBrokerTopicsPageParams } from '../../../admin/admin-notifications/admin-notifications-broker-topics-page/admin-notifications-broker-topics-page-resolver.service'; import { PaginationService } from '../../../core/pagination/pagination.service'; +import { ActivatedRoute } from '@angular/router'; +import { NotificationsBrokerTopicsService } from './notifications-broker-topics.service'; /** * Component to display the Notifications Broker topic list. @@ -48,6 +50,12 @@ export class NotificationsBrokerTopicsComponent implements OnInit { */ protected subs: Subscription[] = []; + /** + * This property represents a sourceId which is used to retrive a topic + * @type {string} + */ + public sourceId: string; + /** * Initialize the component variables. * @param {PaginationService} paginationService @@ -55,8 +63,18 @@ export class NotificationsBrokerTopicsComponent implements OnInit { */ constructor( private paginationService: PaginationService, + private activatedRoute: ActivatedRoute, private notificationsStateService: NotificationsStateService, - ) { } + private notificationsBrokerTopicsService: NotificationsBrokerTopicsService + ) { + this.activatedRoute.paramMap.pipe( + map((params) => params.get('sourceId')), + take(1) + ).subscribe((id: string) => { + this.sourceId = id; + this.notificationsBrokerTopicsService.setSourceId(this.sourceId); + }); + } /** * Component initialization. diff --git a/src/app/notifications/broker/topics/notifications-broker-topics.service.ts b/src/app/notifications/broker/topics/notifications-broker-topics.service.ts index b04229e0d9..80c52a70a9 100644 --- a/src/app/notifications/broker/topics/notifications-broker-topics.service.ts +++ b/src/app/notifications/broker/topics/notifications-broker-topics.service.ts @@ -7,6 +7,7 @@ import { FindListOptions } from '../../../core/data/request.models'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; import { NotificationsBrokerTopicObject } from '../../../core/notifications/broker/models/notifications-broker-topic.model'; +import { RequestParam } from '../../../core/cache/models/request-param.model'; /** * The service handling all Notifications Broker topic requests to the REST service. @@ -22,6 +23,11 @@ export class NotificationsBrokerTopicsService { private notificationsBrokerTopicRestService: NotificationsBrokerTopicRestService ) { } + /** + * sourceId used to get topics + */ + sourceId: string; + /** * Return the list of Notifications Broker topics managing pagination and errors. * @@ -38,7 +44,8 @@ export class NotificationsBrokerTopicsService { const findListOptions: FindListOptions = { elementsPerPage: elementsPerPage, currentPage: currentPage, - sort: sortOptions + sort: sortOptions, + searchParams: [new RequestParam('source', this.sourceId)] }; return this.notificationsBrokerTopicRestService.getTopics(findListOptions).pipe( @@ -52,4 +59,12 @@ export class NotificationsBrokerTopicsService { }) ); } + + /** + * set sourceId which is used to get topics + * @param sourceId string + */ + setSourceId(sourceId: string) { + this.sourceId = sourceId; + } } diff --git a/src/app/notifications/notifications-state.service.ts b/src/app/notifications/notifications-state.service.ts index c81c924465..cbee503acd 100644 --- a/src/app/notifications/notifications-state.service.ts +++ b/src/app/notifications/notifications-state.service.ts @@ -8,11 +8,19 @@ import { getNotificationsBrokerTopicsTotalsSelector, isNotificationsBrokerTopicsLoadedSelector, notificationsBrokerTopicsObjectSelector, - isNotificationsBrokerTopicsProcessingSelector + isNotificationsBrokerTopicsProcessingSelector, + notificationsBrokerSourceObjectSelector, + isNotificationsBrokerSourceLoadedSelector, + isNotificationsBrokerSourceProcessingSelector, + getNotificationsBrokerSourceTotalPagesSelector, + getNotificationsBrokerSourceCurrentPageSelector, + getNotificationsBrokerSourceTotalsSelector } from './selectors'; import { NotificationsBrokerTopicObject } from '../core/notifications/broker/models/notifications-broker-topic.model'; import { NotificationsState } from './notifications.reducer'; import { RetrieveAllTopicsAction } from './broker/topics/notifications-broker-topics.actions'; +import { NotificationsBrokerSourceObject } from '../core/notifications/broker/models/notifications-broker-source.model'; +import { RetrieveAllSourceAction } from './broker/source/notifications-broker-source.actions'; /** * The service handling the Notifications State. @@ -113,4 +121,92 @@ export class NotificationsStateService { public dispatchRetrieveNotificationsBrokerTopics(elementsPerPage: number, currentPage: number): void { this.store.dispatch(new RetrieveAllTopicsAction(elementsPerPage, currentPage)); } + + // Notifications Broker source + // -------------------------------------------------------------------------- + + /** + * Returns the list of Notifications Broker source from the state. + * + * @return Observable + * The list of Notifications Broker source. + */ + public getNotificationsBrokerSource(): Observable { + return this.store.pipe(select(notificationsBrokerSourceObjectSelector())); + } + + /** + * Returns the information about the loading status of the Notifications Broker source (if it's running or not). + * + * @return Observable + * 'true' if the source are loading, 'false' otherwise. + */ + public isNotificationsBrokerSourceLoading(): Observable { + return this.store.pipe( + select(isNotificationsBrokerSourceLoadedSelector), + map((loaded: boolean) => !loaded) + ); + } + + /** + * Returns the information about the loading status of the Notifications Broker source (whether or not they were loaded). + * + * @return Observable + * 'true' if the source are loaded, 'false' otherwise. + */ + public isNotificationsBrokerSourceLoaded(): Observable { + return this.store.pipe(select(isNotificationsBrokerSourceLoadedSelector)); + } + + /** + * Returns the information about the processing status of the Notifications Broker source (if it's running or not). + * + * @return Observable + * 'true' if there are operations running on the source (ex.: a REST call), 'false' otherwise. + */ + public isNotificationsBrokerSourceProcessing(): Observable { + return this.store.pipe(select(isNotificationsBrokerSourceProcessingSelector)); + } + + /** + * Returns, from the state, the total available pages of the Notifications Broker source. + * + * @return Observable + * The number of the Notifications Broker source pages. + */ + public getNotificationsBrokerSourceTotalPages(): Observable { + return this.store.pipe(select(getNotificationsBrokerSourceTotalPagesSelector)); + } + + /** + * Returns the current page of the Notifications Broker source, from the state. + * + * @return Observable + * The number of the current Notifications Broker source page. + */ + public getNotificationsBrokerSourceCurrentPage(): Observable { + return this.store.pipe(select(getNotificationsBrokerSourceCurrentPageSelector)); + } + + /** + * Returns the total number of the Notifications Broker source. + * + * @return Observable + * The number of the Notifications Broker source. + */ + public getNotificationsBrokerSourceTotals(): Observable { + return this.store.pipe(select(getNotificationsBrokerSourceTotalsSelector)); + } + + /** + * Dispatch a request to change the Notifications Broker source state, retrieving the source from the server. + * + * @param elementsPerPage + * The number of the source per page. + * @param currentPage + * The number of the current page. + */ + public dispatchRetrieveNotificationsBrokerSource(elementsPerPage: number, currentPage: number): void { + this.store.dispatch(new RetrieveAllSourceAction(elementsPerPage, currentPage)); + } } diff --git a/src/app/notifications/notifications.effects.ts b/src/app/notifications/notifications.effects.ts index cbc76a5b3e..39ecded797 100644 --- a/src/app/notifications/notifications.effects.ts +++ b/src/app/notifications/notifications.effects.ts @@ -1,5 +1,7 @@ +import { NotificationsBrokerSourceEffects } from './broker/source/notifications-broker-source.effects'; import { NotificationsBrokerTopicsEffects } from './broker/topics/notifications-broker-topics.effects'; export const notificationsEffects = [ - NotificationsBrokerTopicsEffects + NotificationsBrokerTopicsEffects, + NotificationsBrokerSourceEffects ]; diff --git a/src/app/notifications/notifications.module.ts b/src/app/notifications/notifications.module.ts index 4b0ba3cfd1..63224fdd81 100644 --- a/src/app/notifications/notifications.module.ts +++ b/src/app/notifications/notifications.module.ts @@ -17,6 +17,9 @@ import { NotificationsBrokerEventRestService } from '../core/notifications/broke import { ProjectEntryImportModalComponent } from './broker/project-entry-import-modal/project-entry-import-modal.component'; import { TranslateModule } from '@ngx-translate/core'; import { SearchModule } from '../shared/search/search.module'; +import { NotificationsBrokerSourceComponent } from './broker/source/notifications-broker-source.component'; +import { NotificationsBrokerSourceService } from './broker/source/notifications-broker-source.service'; +import { NotificationsBrokerSourceRestService } from '../core/notifications/broker/source/notifications-broker-source-rest.service'; const MODULES = [ CommonModule, @@ -29,7 +32,8 @@ const MODULES = [ const COMPONENTS = [ NotificationsBrokerTopicsComponent, - NotificationsBrokerEventsComponent + NotificationsBrokerEventsComponent, + NotificationsBrokerSourceComponent ]; const DIRECTIVES = [ ]; @@ -41,7 +45,9 @@ const ENTRY_COMPONENTS = [ const PROVIDERS = [ NotificationsStateService, NotificationsBrokerTopicsService, + NotificationsBrokerSourceService, NotificationsBrokerTopicRestService, + NotificationsBrokerSourceRestService, NotificationsBrokerEventRestService ]; diff --git a/src/app/notifications/notifications.reducer.ts b/src/app/notifications/notifications.reducer.ts index b3dc54d524..27bebbea20 100644 --- a/src/app/notifications/notifications.reducer.ts +++ b/src/app/notifications/notifications.reducer.ts @@ -1,5 +1,5 @@ import { ActionReducerMap, createFeatureSelector } from '@ngrx/store'; - +import { notificationsBrokerSourceReducer, NotificationsBrokerSourceState } from './broker/source/notifications-broker-source.reducer'; import { notificationsBrokerTopicsReducer, NotificationsBrokerTopicState, } from './broker/topics/notifications-broker-topics.reducer'; /** @@ -7,10 +7,12 @@ import { notificationsBrokerTopicsReducer, NotificationsBrokerTopicState, } from */ export interface NotificationsState { 'brokerTopic': NotificationsBrokerTopicState; + 'brokerSource': NotificationsBrokerSourceState; } export const notificationsReducers: ActionReducerMap = { brokerTopic: notificationsBrokerTopicsReducer, + brokerSource: notificationsBrokerSourceReducer }; export const notificationsSelector = createFeatureSelector('notifications'); diff --git a/src/app/notifications/selectors.ts b/src/app/notifications/selectors.ts index 7474aa3adc..0436a35eb3 100644 --- a/src/app/notifications/selectors.ts +++ b/src/app/notifications/selectors.ts @@ -3,6 +3,8 @@ import { subStateSelector } from '../shared/selector.util'; import { notificationsSelector, NotificationsState } from './notifications.reducer'; import { NotificationsBrokerTopicObject } from '../core/notifications/broker/models/notifications-broker-topic.model'; import { NotificationsBrokerTopicState } from './broker/topics/notifications-broker-topics.reducer'; +import { NotificationsBrokerSourceState } from './broker/source/notifications-broker-source.reducer'; +import { NotificationsBrokerSourceObject } from '../core/notifications/broker/models/notifications-broker-source.model'; /** * Returns the Notifications state. @@ -77,3 +79,69 @@ export const getNotificationsBrokerTopicsCurrentPageSelector = createSelector(_g export const getNotificationsBrokerTopicsTotalsSelector = createSelector(_getNotificationsState, (state: NotificationsState) => state.brokerTopic.totalElements ); + +// Notifications Broker source +// ---------------------------------------------------------------------------- + +/** + * Returns the Notifications Broker source State. + * @function notificationsBrokerSourceStateSelector + * @return {NotificationsBrokerSourceState} + */ + export function notificationsBrokerSourceStateSelector(): MemoizedSelector { + return subStateSelector(notificationsSelector, 'brokerSource'); +} + +/** + * Returns the Notifications Broker source list. + * @function notificationsBrokerSourceObjectSelector + * @return {NotificationsBrokerSourceObject[]} + */ +export function notificationsBrokerSourceObjectSelector(): MemoizedSelector { + return subStateSelector(notificationsBrokerSourceStateSelector(), 'source'); +} + +/** + * Returns true if the Notifications Broker source are loaded. + * @function isNotificationsBrokerSourceLoadedSelector + * @return {boolean} + */ +export const isNotificationsBrokerSourceLoadedSelector = createSelector(_getNotificationsState, + (state: NotificationsState) => state.brokerSource.loaded +); + +/** + * Returns true if the deduplication sets are processing. + * @function isDeduplicationSetsProcessingSelector + * @return {boolean} + */ +export const isNotificationsBrokerSourceProcessingSelector = createSelector(_getNotificationsState, + (state: NotificationsState) => state.brokerSource.processing +); + +/** + * Returns the total available pages of Notifications Broker source. + * @function getNotificationsBrokerSourceTotalPagesSelector + * @return {number} + */ +export const getNotificationsBrokerSourceTotalPagesSelector = createSelector(_getNotificationsState, + (state: NotificationsState) => state.brokerSource.totalPages +); + +/** + * Returns the current page of Notifications Broker source. + * @function getNotificationsBrokerSourceCurrentPageSelector + * @return {number} + */ +export const getNotificationsBrokerSourceCurrentPageSelector = createSelector(_getNotificationsState, + (state: NotificationsState) => state.brokerSource.currentPage +); + +/** + * Returns the total number of Notifications Broker source. + * @function getNotificationsBrokerSourceTotalsSelector + * @return {number} + */ +export const getNotificationsBrokerSourceTotalsSelector = createSelector(_getNotificationsState, + (state: NotificationsState) => state.brokerSource.totalElements +); diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 674254e605..e04792273b 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -487,6 +487,8 @@ "admin.notifications.broker.page.title": "Notifications Broker", + "admin.notifications.source.breadcrumbs": "Notifications Source", + "admin.search.breadcrumbs": "Administrative Search", "admin.search.collection.edit": "Edit", @@ -2713,14 +2715,20 @@ "none.listelement.badge": "Item", - "notifications.broker.title": "{{source}} Broker", + "notifications.broker.title": "Broker Title", "notifications.broker.topics.description": "Below you can see all the topics received from the subscriptions to {{source}}.", + "notifications.broker.source.description": "Below you can see all the sources.", + "notifications.broker.topics": "Current Topics", + "notifications.broker.source": "Current Sources", + "notifications.broker.table.topic": "Topic", + "notifications.broker.table.source": "Source", + "notifications.broker.table.last-event": "Last Event", "notifications.broker.table.actions": "Actions", @@ -2729,10 +2737,14 @@ "notifications.broker.noTopics": "No topics found.", + "notifications.broker.noSource": "No sources found.", + "notifications.events.title": "{{source}} Broker Suggestions", "notifications.broker.topic.error.service.retrieve": "An error occurred while loading the Notifications Broker topics", + "notifications.broker.source.error.service.retrieve": "An error occurred while loading the Notifications Broker source", + "notifications.broker.events.description": "Below the list of all the suggestions, received from {{source}}, for the selected topic.", "notifications.broker.loading": "Loading ...",