Merge branch CST-5249_suggestion of https://github.com/4Science/DSpace into CST-11299

This commit is contained in:
Francesco Bacchelli
2023-08-22 11:16:30 +02:00
parent f31d4d5276
commit 9b556fd703
27 changed files with 193 additions and 62 deletions

View File

@@ -161,6 +161,7 @@ export class RemoteDataBuildService {
} else { } else {
// in case the elements of the paginated list were already filled in, because they're UnCacheableObjects // in case the elements of the paginated list were already filled in, because they're UnCacheableObjects
paginatedList.page = paginatedList.page paginatedList.page = paginatedList.page
.filter((obj: any) => obj != null)
.map((obj: any) => this.plainObjectToInstance<T>(obj)) .map((obj: any) => this.plainObjectToInstance<T>(obj))
.map((obj: any) => .map((obj: any) =>
this.linkService.resolveLinks(obj, ...pageLink.linksToFollow) this.linkService.resolveLinks(obj, ...pageLink.linksToFollow)

View File

@@ -185,6 +185,8 @@ import { FlatBrowseDefinition } from './shared/flat-browse-definition.model';
import { ValueListBrowseDefinition } from './shared/value-list-browse-definition.model'; import { ValueListBrowseDefinition } from './shared/value-list-browse-definition.model';
import { NonHierarchicalBrowseDefinition } from './shared/non-hierarchical-browse-definition'; import { NonHierarchicalBrowseDefinition } from './shared/non-hierarchical-browse-definition';
import { BulkAccessConditionOptions } from './config/models/bulk-access-condition-options.model'; import { BulkAccessConditionOptions } from './config/models/bulk-access-condition-options.model';
import { SuggestionTarget } from './suggestion-notifications/reciter-suggestions/models/suggestion-target.model';
import { SuggestionSource } from './suggestion-notifications/reciter-suggestions/models/suggestion-source.model';
/** /**
* When not in production, endpoint responses can be mocked for testing purposes * When not in production, endpoint responses can be mocked for testing purposes
@@ -386,7 +388,9 @@ export const models =
IdentifierData, IdentifierData,
Subscription, Subscription,
ItemRequest, ItemRequest,
BulkAccessConditionOptions BulkAccessConditionOptions,
SuggestionTarget,
SuggestionSource
]; ];
@NgModule({ @NgModule({

View File

@@ -1,21 +1,5 @@
import { ResourceType } from '../../../shared/resource-type'; import { ResourceType } from '../../../shared/resource-type';
/**
* The resource type for the Suggestion Target object
*
* Needs to be in a separate file to prevent circular
* dependencies in webpack.
*/
export const SUGGESTION_TARGET = new ResourceType('suggestiontarget');
/**
* The resource type for the Suggestion Source object
*
* Needs to be in a separate file to prevent circular
* dependencies in webpack.
*/
export const SUGGESTION_SOURCE = new ResourceType('suggestionsource');
/** /**
* The resource type for the Suggestion object * The resource type for the Suggestion object
* *

View File

@@ -0,0 +1,9 @@
import { ResourceType } from '../../../shared/resource-type';
/**
* The resource type for the Suggestion Source object
*
* Needs to be in a separate file to prevent circular
* dependencies in webpack.
*/
export const SUGGESTION_SOURCE = new ResourceType('suggestionsource');

View File

@@ -1,6 +1,6 @@
import { autoserialize, deserialize } from 'cerialize'; import { autoserialize, deserialize } from 'cerialize';
import { SUGGESTION_SOURCE } from './suggestion-objects.resource-type'; import { SUGGESTION_SOURCE } from './suggestion-source-object.resource-type';
import { excludeFromEquals } from '../../../utilities/equals.decorators'; import { excludeFromEquals } from '../../../utilities/equals.decorators';
import { ResourceType } from '../../../shared/resource-type'; import { ResourceType } from '../../../shared/resource-type';
import { HALLink } from '../../../shared/hal-link.model'; import { HALLink } from '../../../shared/hal-link.model';

View File

@@ -0,0 +1,9 @@
import { ResourceType } from '../../../shared/resource-type';
/**
* The resource type for the Suggestion Target object
*
* Needs to be in a separate file to prevent circular
* dependencies in webpack.
*/
export const SUGGESTION_TARGET = new ResourceType('suggestiontarget');

View File

@@ -2,7 +2,7 @@ import { autoserialize, deserialize } from 'cerialize';
import { CacheableObject } from '../../../cache/cacheable-object.model'; import { CacheableObject } from '../../../cache/cacheable-object.model';
import { SUGGESTION_TARGET } from './suggestion-objects.resource-type'; import { SUGGESTION_TARGET } from './suggestion-target-object.resource-type';
import { excludeFromEquals } from '../../../utilities/equals.decorators'; import { excludeFromEquals } from '../../../utilities/equals.decorators';
import { ResourceType } from '../../../shared/resource-type'; import { ResourceType } from '../../../shared/resource-type';
import { HALLink } from '../../../shared/hal-link.model'; import { HALLink } from '../../../shared/hal-link.model';

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { dataService } from '../../../data/base/data-service.decorator'; import { dataService } from '../../../data/base/data-service.decorator';
import { SUGGESTION_SOURCE } from '../models/suggestion-objects.resource-type'; import { SUGGESTION_SOURCE } from '../models/suggestion-source-object.resource-type';
import { IdentifiableDataService } from '../../../data/base/identifiable-data.service'; import { IdentifiableDataService } from '../../../data/base/identifiable-data.service';
import { SuggestionSource } from '../models/suggestion-source.model'; import { SuggestionSource } from '../models/suggestion-source.model';
import { FindAllData, FindAllDataImpl } from '../../../data/base/find-all-data'; import { FindAllData, FindAllDataImpl } from '../../../data/base/find-all-data';

View File

@@ -168,8 +168,8 @@ export class SuggestionsDataService {
...linksToFollow: FollowLinkConfig<SuggestionTarget>[] ...linksToFollow: FollowLinkConfig<SuggestionTarget>[]
): Observable<RemoteData<PaginatedList<SuggestionTarget>>> { ): Observable<RemoteData<PaginatedList<SuggestionTarget>>> {
options.searchParams = [new RequestParam('target', userId)]; options.searchParams = [new RequestParam('target', userId)];
//return this.suggestionTargetsDataService.getTargetsByUser(this.searchFindByTargetMethod, options, ...linksToFollow);
return this.suggestionTargetsDataService.getTargetsByUser(this.searchFindByTargetMethod, options, ...linksToFollow); return this.suggestionTargetsDataService.getTargetsByUser(userId, options, ...linksToFollow);
} }
/** /**

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { dataService } from '../../../data/base/data-service.decorator'; import { dataService } from '../../../data/base/data-service.decorator';
import { SUGGESTION_TARGET } from '../models/suggestion-objects.resource-type';
import { IdentifiableDataService } from '../../../data/base/identifiable-data.service'; import { IdentifiableDataService } from '../../../data/base/identifiable-data.service';
import { SuggestionTarget } from '../models/suggestion-target.model'; import { SuggestionTarget } from '../models/suggestion-target.model';
import { FindAllData, FindAllDataImpl } from '../../../data/base/find-all-data'; import { FindAllData, FindAllDataImpl } from '../../../data/base/find-all-data';
@@ -20,6 +20,7 @@ import { Observable } from 'rxjs/internal/Observable';
import { RequestParam } from '../../../cache/models/request-param.model'; import { RequestParam } from '../../../cache/models/request-param.model';
import { SearchData, SearchDataImpl } from '../../../data/base/search-data'; import { SearchData, SearchDataImpl } from '../../../data/base/search-data';
import { DefaultChangeAnalyzer } from '../../../data/default-change-analyzer.service'; import { DefaultChangeAnalyzer } from '../../../data/default-change-analyzer.service';
import { SUGGESTION_TARGET } from '../models/suggestion-target-object.resource-type';
@Injectable() @Injectable()
@dataService(SUGGESTION_TARGET) @dataService(SUGGESTION_TARGET)

View File

@@ -7,3 +7,4 @@
<ds-themed-top-level-community-list></ds-themed-top-level-community-list> <ds-themed-top-level-community-list></ds-themed-top-level-community-list>
<ds-recent-item-list *ngIf="recentSubmissionspageSize>0"></ds-recent-item-list> <ds-recent-item-list *ngIf="recentSubmissionspageSize>0"></ds-recent-item-list>
</div> </div>
<ds-suggestions-popup></ds-suggestions-popup>

View File

@@ -13,6 +13,7 @@ import { RecentItemListComponent } from './recent-item-list/recent-item-list.com
import { JournalEntitiesModule } from '../entity-groups/journal-entities/journal-entities.module'; import { JournalEntitiesModule } from '../entity-groups/journal-entities/journal-entities.module';
import { ResearchEntitiesModule } from '../entity-groups/research-entities/research-entities.module'; import { ResearchEntitiesModule } from '../entity-groups/research-entities/research-entities.module';
import { ThemedTopLevelCommunityListComponent } from './top-level-community-list/themed-top-level-community-list.component'; import { ThemedTopLevelCommunityListComponent } from './top-level-community-list/themed-top-level-community-list.component';
import { SuggestionNotificationsModule } from '../suggestion-notifications/suggestion-notifications.module';
const DECLARATIONS = [ const DECLARATIONS = [
HomePageComponent, HomePageComponent,
@@ -31,7 +32,8 @@ const DECLARATIONS = [
JournalEntitiesModule.withEntryComponents(), JournalEntitiesModule.withEntryComponents(),
ResearchEntitiesModule.withEntryComponents(), ResearchEntitiesModule.withEntryComponents(),
HomePageRoutingModule, HomePageRoutingModule,
StatisticsModule.forRoot() StatisticsModule.forRoot(),
SuggestionNotificationsModule
], ],
declarations: [ declarations: [
...DECLARATIONS, ...DECLARATIONS,

View File

@@ -47,6 +47,7 @@ import {
import { import {
ExportBatchSelectorComponent ExportBatchSelectorComponent
} from './shared/dso-selector/modal-wrappers/export-batch-selector/export-batch-selector.component'; } from './shared/dso-selector/modal-wrappers/export-batch-selector/export-batch-selector.component';
import { NOTIFICATIONS_RECITER_SUGGESTION_PATH } from './admin/admin-notifications/admin-notifications-routing-paths';
/** /**
* Creates all of the app's menus * Creates all of the app's menus
@@ -555,6 +556,17 @@ export class MenuResolver implements Resolve<boolean> {
link: '/admin/notifications/quality-assurance' link: '/admin/notifications/quality-assurance'
} as LinkMenuItemModel, } as LinkMenuItemModel,
}, },
{
id: 'notifications_reciter',
parentID: 'notifications',
active: false,
visible: authorized,
model: {
type: MenuItemType.LINK,
text: 'menu.section.notifications_reciter',
link: '/admin/notifications/' + NOTIFICATIONS_RECITER_SUGGESTION_PATH
} as LinkMenuItemModel,
},
/* Admin Search */ /* Admin Search */
{ {
id: 'admin_search', id: 'admin_search',

View File

@@ -1,5 +1,6 @@
<div class="container"> <div class="container">
<ds-my-dspace-new-submission *dsShowOnlyForRole="[roleTypeEnum.Submitter]"></ds-my-dspace-new-submission> <ds-my-dspace-new-submission *dsShowOnlyForRole="[roleTypeEnum.Submitter]"></ds-my-dspace-new-submission>
<ds-suggestions-notification></ds-suggestions-notification>
</div> </div>
<ds-themed-search *ngIf="configuration && context" <ds-themed-search *ngIf="configuration && context"

View File

@@ -15,6 +15,7 @@ import { MyDSpaceNewExternalDropdownComponent } from './my-dspace-new-submission
import { ThemedMyDSpacePageComponent } from './themed-my-dspace-page.component'; import { ThemedMyDSpacePageComponent } from './themed-my-dspace-page.component';
import { SearchModule } from '../shared/search/search.module'; import { SearchModule } from '../shared/search/search.module';
import { UploadModule } from '../shared/upload/upload.module'; import { UploadModule } from '../shared/upload/upload.module';
import { SuggestionNotificationsModule } from '../suggestion-notifications/suggestion-notifications.module';
const DECLARATIONS = [ const DECLARATIONS = [
MyDSpacePageComponent, MyDSpacePageComponent,
@@ -33,6 +34,7 @@ const DECLARATIONS = [
MyDspacePageRoutingModule, MyDspacePageRoutingModule,
MyDspaceSearchModule.withEntryComponents(), MyDspaceSearchModule.withEntryComponents(),
UploadModule, UploadModule,
SuggestionNotificationsModule,
], ],
declarations: DECLARATIONS, declarations: DECLARATIONS,
providers: [ providers: [

View File

@@ -8,6 +8,7 @@
<div class="mb-4"> <div class="mb-4">
<ds-profile-page-researcher-form [user]="user" ></ds-profile-page-researcher-form> <ds-profile-page-researcher-form [user]="user" ></ds-profile-page-researcher-form>
</div> </div>
<ds-suggestions-notification></ds-suggestions-notification>
</div> </div>
</div> </div>
</ng-container> </ng-container>

View File

@@ -12,6 +12,7 @@ import { ThemedProfilePageComponent } from './themed-profile-page.component';
import { FormModule } from '../shared/form/form.module'; import { FormModule } from '../shared/form/form.module';
import { UiSwitchModule } from 'ngx-ui-switch'; import { UiSwitchModule } from 'ngx-ui-switch';
import { ProfileClaimItemModalComponent } from './profile-claim-item-modal/profile-claim-item-modal.component'; import { ProfileClaimItemModalComponent } from './profile-claim-item-modal/profile-claim-item-modal.component';
import { SuggestionNotificationsModule } from '../suggestion-notifications/suggestion-notifications.module';
@NgModule({ @NgModule({
@@ -20,7 +21,8 @@ import { ProfileClaimItemModalComponent } from './profile-claim-item-modal/profi
CommonModule, CommonModule,
SharedModule, SharedModule,
FormModule, FormModule,
UiSwitchModule UiSwitchModule,
SuggestionNotificationsModule
], ],
exports: [ exports: [
ProfilePageComponent, ProfilePageComponent,

View File

@@ -1,4 +1,4 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router'; import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';
import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
@@ -29,6 +29,11 @@ export abstract class DSOSelectorModalWrapperComponent implements OnInit {
*/ */
@Input() dsoRD: RemoteData<DSpaceObject>; @Input() dsoRD: RemoteData<DSpaceObject>;
/**
* Representing if component should emit value of selected entries or navigate
*/
@Input() emitOnly = false;
/** /**
* Optional header to display above the selection list * Optional header to display above the selection list
* Supports i18n keys * Supports i18n keys
@@ -50,6 +55,11 @@ export abstract class DSOSelectorModalWrapperComponent implements OnInit {
*/ */
action: SelectorActionType; action: SelectorActionType;
/**
* Event emitted when a DSO entry is selected if emitOnly is set to true
*/
@Output() select: EventEmitter<DSpaceObject> = new EventEmitter<DSpaceObject>();
/** /**
* Default DSO ordering * Default DSO ordering
*/ */
@@ -93,8 +103,12 @@ export abstract class DSOSelectorModalWrapperComponent implements OnInit {
*/ */
selectObject(dso: DSpaceObject) { selectObject(dso: DSpaceObject) {
this.close(); this.close();
if (this.emitOnly) {
this.select.emit(dso);
} else {
this.navigate(dso); this.navigate(dso);
} }
}
/** /**
* Navigate to a page based on the DSpaceObject provided * Navigate to a page based on the DSpaceObject provided

View File

@@ -27,7 +27,7 @@ export function reciterSuggestionTargetStateSelector(): MemoizedSelector<Suggest
/** /**
* Returns the Reciter Suggestion Targets list. * Returns the Reciter Suggestion Targets list.
* @function reciterSuggestionTargetObjectSelector * @function reciterSuggestionTargetObjectSelector
* @return {OpenaireReciterSuggestionTarget[]} * @return {SuggestionTarget[]}
*/ */
export function reciterSuggestionTargetObjectSelector(): MemoizedSelector<SuggestionNotificationsState, SuggestionTarget[]> { export function reciterSuggestionTargetObjectSelector(): MemoizedSelector<SuggestionNotificationsState, SuggestionTarget[]> {
return subStateSelector<SuggestionNotificationsState, SuggestionTarget[]>(reciterSuggestionTargetStateSelector(), 'targets'); return subStateSelector<SuggestionNotificationsState, SuggestionTarget[]>(reciterSuggestionTargetStateSelector(), 'targets');
@@ -47,7 +47,7 @@ export const isReciterSuggestionTargetLoadedSelector = createSelector(_getRecite
* @function isDeduplicationSetsProcessingSelector * @function isDeduplicationSetsProcessingSelector
* @return {boolean} * @return {boolean}
*/ */
export const isreciterSuggestionTargetProcessingSelector = createSelector(_getReciterSuggestionTargetState, export const isReciterSuggestionTargetProcessingSelector = createSelector(_getReciterSuggestionTargetState,
(state: SuggestionNotificationsState) => state.suggestionTarget.processing (state: SuggestionNotificationsState) => state.suggestionTarget.processing
); );
@@ -56,7 +56,7 @@ export const isreciterSuggestionTargetProcessingSelector = createSelector(_getRe
* @function getreciterSuggestionTargetTotalPagesSelector * @function getreciterSuggestionTargetTotalPagesSelector
* @return {number} * @return {number}
*/ */
export const getreciterSuggestionTargetTotalPagesSelector = createSelector(_getReciterSuggestionTargetState, export const getReciterSuggestionTargetTotalPagesSelector = createSelector(_getReciterSuggestionTargetState,
(state: SuggestionNotificationsState) => state.suggestionTarget.totalPages (state: SuggestionNotificationsState) => state.suggestionTarget.totalPages
); );
@@ -65,7 +65,7 @@ export const getreciterSuggestionTargetTotalPagesSelector = createSelector(_getR
* @function getreciterSuggestionTargetCurrentPageSelector * @function getreciterSuggestionTargetCurrentPageSelector
* @return {number} * @return {number}
*/ */
export const getreciterSuggestionTargetCurrentPageSelector = createSelector(_getReciterSuggestionTargetState, export const getReciterSuggestionTargetCurrentPageSelector = createSelector(_getReciterSuggestionTargetState,
(state: SuggestionNotificationsState) => state.suggestionTarget.currentPage (state: SuggestionNotificationsState) => state.suggestionTarget.currentPage
); );
@@ -74,7 +74,7 @@ export const getreciterSuggestionTargetCurrentPageSelector = createSelector(_get
* @function getreciterSuggestionTargetTotalsSelector * @function getreciterSuggestionTargetTotalsSelector
* @return {number} * @return {number}
*/ */
export const getreciterSuggestionTargetTotalsSelector = createSelector(_getReciterSuggestionTargetState, export const getReciterSuggestionTargetTotalsSelector = createSelector(_getReciterSuggestionTargetState,
(state: SuggestionNotificationsState) => state.suggestionTarget.totalElements (state: SuggestionNotificationsState) => state.suggestionTarget.totalElements
); );

View File

@@ -136,6 +136,7 @@ export class SuggestionTargetsComponent implements OnInit {
distinctUntilChanged(), distinctUntilChanged(),
take(1) take(1)
).subscribe((options: PaginationComponentOptions) => { ).subscribe((options: PaginationComponentOptions) => {
console.log('HELLO suggestion called!', options);
this.suggestionTargetsStateService.dispatchRetrieveReciterSuggestionTargets( this.suggestionTargetsStateService.dispatchRetrieveReciterSuggestionTargets(
this.source, this.source,
options.pageSize, options.pageSize,

View File

@@ -62,7 +62,7 @@ export class SuggestionTargetsEffects {
/** /**
* Fetch the current user suggestion * Fetch the current user suggestion
*/ */
refreshUserTargets$ = createEffect(() => this.actions$.pipe( RefreshUserSuggestionsAction = createEffect(() => this.actions$.pipe(
ofType(SuggestionTargetActionTypes.REFRESH_USER_SUGGESTIONS), ofType(SuggestionTargetActionTypes.REFRESH_USER_SUGGESTIONS),
switchMap((action: RefreshUserSuggestionsAction) => { switchMap((action: RefreshUserSuggestionsAction) => {
return this.store$.select((state: any) => state.core.auth.userId) return this.store$.select((state: any) => state.core.auth.userId)

View File

@@ -7,10 +7,10 @@ import { map } from 'rxjs/operators';
import { import {
getCurrentUserSuggestionTargetsSelector, getCurrentUserSuggestionTargetsSelector,
getCurrentUserSuggestionTargetsVisitedSelector, getCurrentUserSuggestionTargetsVisitedSelector,
getreciterSuggestionTargetCurrentPageSelector, getReciterSuggestionTargetCurrentPageSelector,
getreciterSuggestionTargetTotalsSelector, getReciterSuggestionTargetTotalsSelector,
isReciterSuggestionTargetLoadedSelector, isReciterSuggestionTargetLoadedSelector,
isreciterSuggestionTargetProcessingSelector, isReciterSuggestionTargetProcessingSelector,
reciterSuggestionTargetObjectSelector reciterSuggestionTargetObjectSelector
} from '../selectors'; } from '../selectors';
import { SuggestionTarget } from '../../../core/suggestion-notifications/reciter-suggestions/models/suggestion-target.model'; import { SuggestionTarget } from '../../../core/suggestion-notifications/reciter-suggestions/models/suggestion-target.model';
@@ -74,7 +74,7 @@ export class SuggestionTargetsStateService {
* 'true' if there are operations running on the targets (ex.: a REST call), 'false' otherwise. * 'true' if there are operations running on the targets (ex.: a REST call), 'false' otherwise.
*/ */
public isReciterSuggestionTargetsProcessing(): Observable<boolean> { public isReciterSuggestionTargetsProcessing(): Observable<boolean> {
return this.store.pipe(select(isreciterSuggestionTargetProcessingSelector)); return this.store.pipe(select(isReciterSuggestionTargetProcessingSelector));
} }
/** /**
@@ -84,7 +84,7 @@ export class SuggestionTargetsStateService {
* The number of the Reciter Suggestion Targets pages. * The number of the Reciter Suggestion Targets pages.
*/ */
public getReciterSuggestionTargetsTotalPages(): Observable<number> { public getReciterSuggestionTargetsTotalPages(): Observable<number> {
return this.store.pipe(select(getreciterSuggestionTargetTotalsSelector)); return this.store.pipe(select(getReciterSuggestionTargetTotalsSelector));
} }
/** /**
@@ -94,7 +94,7 @@ export class SuggestionTargetsStateService {
* The number of the current Reciter Suggestion Targets page. * The number of the current Reciter Suggestion Targets page.
*/ */
public getReciterSuggestionTargetsCurrentPage(): Observable<number> { public getReciterSuggestionTargetsCurrentPage(): Observable<number> {
return this.store.pipe(select(getreciterSuggestionTargetCurrentPageSelector)); return this.store.pipe(select(getReciterSuggestionTargetCurrentPageSelector));
} }
/** /**
@@ -104,7 +104,7 @@ export class SuggestionTargetsStateService {
* The number of the Reciter Suggestion Targets. * The number of the Reciter Suggestion Targets.
*/ */
public getReciterSuggestionTargetsTotals(): Observable<number> { public getReciterSuggestionTargetsTotals(): Observable<number> {
return this.store.pipe(select(getreciterSuggestionTargetTotalsSelector)); return this.store.pipe(select(getReciterSuggestionTargetTotalsSelector));
} }
/** /**

View File

@@ -31,6 +31,8 @@ export class SuggestionsPopupComponent implements OnInit, OnDestroy {
} }
public initializePopup() { public initializePopup() {
console.log('POPUP INIT dispatchRefreshUserSuggestionsAction');
this.reciterSuggestionStateService.dispatchRefreshUserSuggestionsAction();
const notifier = new Subject(); const notifier = new Subject();
this.subscription = combineLatest([ this.subscription = combineLatest([
this.reciterSuggestionStateService.getCurrentUserSuggestionTargets(), this.reciterSuggestionStateService.getCurrentUserSuggestionTargets(),

View File

@@ -49,7 +49,9 @@ export class SuggestionsService {
/** /**
* Initialize the service variables. * Initialize the service variables.
* @param {AuthService} authService * @param {AuthService} authService
* @param {ResearcherProfileService} researcherProfileService * @param {ResearcherProfileDataService} researcherProfileService
* @param {SuggestionSourceDataService} suggestionSourceDataService
* @param {SuggestionTargetDataService} suggestionTargetDataService
* @param {SuggestionsDataService} suggestionsDataService * @param {SuggestionsDataService} suggestionsDataService
*/ */
constructor( constructor(

View File

@@ -40,6 +40,15 @@ import {
} from './reciter-suggestions/suggestions-notification/suggestions-notification.component'; } from './reciter-suggestions/suggestions-notification/suggestions-notification.component';
import { SuggestionsService } from './reciter-suggestions/suggestions.service'; import { SuggestionsService } from './reciter-suggestions/suggestions.service';
import { SuggestionsDataService } from '../core/suggestion-notifications/reciter-suggestions/suggestions-data.service'; import { SuggestionsDataService } from '../core/suggestion-notifications/reciter-suggestions/suggestions-data.service';
import {
SuggestionSourceDataService
} from '../core/suggestion-notifications/reciter-suggestions/source/suggestion-source-data.service';
import {
SuggestionTargetDataService
} from '../core/suggestion-notifications/reciter-suggestions/target/suggestion-target-data.service';
import {
SuggestionTargetsStateService
} from './reciter-suggestions/suggestion-targets/suggestion-targets.state.service';
const MODULES = [ const MODULES = [
CommonModule, CommonModule,
@@ -77,6 +86,9 @@ const PROVIDERS = [
QualityAssuranceSourceDataService, QualityAssuranceSourceDataService,
QualityAssuranceEventDataService, QualityAssuranceEventDataService,
SuggestionsService, SuggestionsService,
SuggestionSourceDataService,
SuggestionTargetDataService,
SuggestionTargetsStateService,
SuggestionsDataService SuggestionsDataService
]; ];

View File

@@ -24,6 +24,10 @@
"404.page-not-found": "page not found", "404.page-not-found": "page not found",
"admin.notifications.recitersuggestion.breadcrumbs": "Suggestions",
"admin.notifications.recitersuggestion.page.title": "Suggestions",
"error-page.description.401": "unauthorized", "error-page.description.401": "unauthorized",
"error-page.description.403": "forbidden", "error-page.description.403": "forbidden",
@@ -3052,6 +3056,12 @@
"mydspace.view-btn": "View", "mydspace.view-btn": "View",
"mydspace.import": "Import",
"mydspace.notification.suggestion": "We found <b>{{count}} publications</b><br> in the {{source}} that seems to be related to your profile.<br> Please <a href='/suggestions/{{suggestionId}}'>review the suggestions</a>",
"mydspace.notification.suggestion.page": "We found <b>{{count}} {{type}}</b> in the {{source}} that seems to be related to your profile. Please <a href='/suggestions/{{suggestionId}}'>review the suggestions.</a>",
"nav.browse.header": "All of DSpace", "nav.browse.header": "All of DSpace",
"nav.community-browse.header": "By Community", "nav.community-browse.header": "By Community",
@@ -3514,6 +3524,64 @@
"media-viewer.playlist": "Playlist", "media-viewer.playlist": "Playlist",
"reciter.suggestion.loading": "Loading ...",
"reciter.suggestion.title": "Suggestions",
"reciter.suggestion.targets.description": "Below you can see all the suggestions ",
"reciter.suggestion.targets": "Current Suggestions",
"reciter.suggestion.table.name": "Researcher Name",
"reciter.suggestion.table.actions": "Actions",
"reciter.suggestion.button.review": "Review {{ total }} suggestion(s)",
"reciter.suggestion.noTargets": "No target found.",
"reciter.suggestion.target.error.service.retrieve": "An error occurred while loading the Suggestion targets",
"reciter.suggestion.evidence.type": "Type",
"reciter.suggestion.evidence.score": "Score",
"reciter.suggestion.evidence.notes": "Notes",
"reciter.suggestion.approveAndImport": "Approve & import",
"reciter.suggestion.approveAndImport.success": "The suggestion has been imported successfully. <a href='/workspaceitems/{{workspaceItemId}}/edit'>View.</a>",
"reciter.suggestion.approveAndImport.bulk": "Approve & import Selected",
"reciter.suggestion.approveAndImport.bulk.success": "{{ count }} suggestions have been imported successfully ",
"reciter.suggestion.approveAndImport.bulk.error": "{{ count }} suggestions haven't been imported due to unexpected server errors",
"reciter.suggestion.notMine": "Not mine",
"reciter.suggestion.notMine.success": "The suggestion has been discarded",
"reciter.suggestion.notMine.bulk": "Not mine Selected",
"reciter.suggestion.notMine.bulk.success": "{{ count }} suggestions have been discarded ",
"reciter.suggestion.notMine.bulk.error": "{{ count }} suggestions haven't been discarded due to unexpected server errors",
"reciter.suggestion.seeEvidence": "See evidence",
"reciter.suggestion.hideEvidence": "Hide evidence",
"reciter.suggestion.suggestionFor": "Suggestion for",
"reciter.suggestion.source.oaire": "OpenAIRE Graph",
"reciter.suggestion.from.source": "from the ",
"reciter.suggestion.totalScore": "Total Score",
"reciter.suggestion.type.oaire": "OpenAIRE",
"register-email.title": "New user registration", "register-email.title": "New user registration",
"register-page.create-profile.header": "Create Profile", "register-page.create-profile.header": "Create Profile",

View File

@@ -156,6 +156,8 @@ import { ItemStatusComponent } from './app/item-page/edit-item-page/item-status/
import { EditBitstreamPageComponent } from './app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component'; import { EditBitstreamPageComponent } from './app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component';
import { FormModule } from '../../app/shared/form/form.module'; import { FormModule } from '../../app/shared/form/form.module';
import { RequestCopyModule } from 'src/app/request-copy/request-copy.module'; import { RequestCopyModule } from 'src/app/request-copy/request-copy.module';
import { SuggestionNotificationsModule } from '../../app/suggestion-notifications/suggestion-notifications.module';
const DECLARATIONS = [ const DECLARATIONS = [
FileSectionComponent, FileSectionComponent,
@@ -299,6 +301,7 @@ const DECLARATIONS = [
NgxGalleryModule, NgxGalleryModule,
FormModule, FormModule,
RequestCopyModule, RequestCopyModule,
SuggestionNotificationsModule
], ],
declarations: DECLARATIONS, declarations: DECLARATIONS,
exports: [ exports: [