[CST-12109] fix of text messages / source image

This commit is contained in:
Alisa Ismailati
2024-02-23 15:03:52 +01:00
parent 6c73a2e3a8
commit e7579b7bf5
11 changed files with 58 additions and 84 deletions

View File

@@ -109,7 +109,7 @@ describe('ItemAlertsComponent', () => {
}); });
}); });
it('should return true when user is not an admin and there is at least one correction with topic REQUEST_REINSTATE', fakeAsync(() => { it('should return true when user is not an admin and there is at least one correction with topic REQUEST_REINSTATE', fakeAsync((done) => {
const isAdmin = false; const isAdmin = false;
const correction = [{ topic: 'REQUEST_REINSTATE' }]; const correction = [{ topic: 'REQUEST_REINSTATE' }];
authorizationService.isAuthorized.and.returnValue(of(isAdmin)); authorizationService.isAuthorized.and.returnValue(of(isAdmin));
@@ -119,6 +119,7 @@ describe('ItemAlertsComponent', () => {
tick(); tick();
result$.subscribe((result) => { result$.subscribe((result) => {
expect(result).toBeTrue(); expect(result).toBeTrue();
done();
}); });
})); }));
}); });

View File

@@ -1,24 +1,21 @@
<ng-container *ngIf="(sources$ | async) as sources"> <ng-container *ngIf="(sources$ | async) as sources">
<ng-container *ngFor="let source of sources"> <ng-container *ngFor="let source of sources">
<div class="alert alert-info d-flex flex-row" *ngIf="source.totalEvents > 0"> <div class="alert alert-info d-flex flex-row" *ngIf="source.totalEvents > 0">
<div class="col-2">
<img class="source-logo"
src="assets/images/qa-{{(source.id | dsSplit: ':')[0]}}-logo.png"
alt="{{source.id}} logo"
onerror="this.src='assets/images/dspace-logo.svg'">
</div>
<div class="w-100 d-flex justify-content-between"> <div class="w-100 d-flex justify-content-between">
<div class="pl-4 align-self-center"> <div class="pl-4 align-self-center">
<ng-container *ngIf="this.item.isArchived; else reinstate"> {{'item.qa-event-notification.check.notification-info' | translate : {num: source.totalEvents } }}
<span>
{{
(isAdmin$ | async) ? ('qa-event-notification.check.notification-withdrawn.admin' | translate : { source: (source.id | dsSplit: ':')[0], num: source.totalEvents })
: ('qa-event-notification.check.notification-withdrawn.user' | translate : { num: source.totalEvents })
}}
</span>
</ng-container>
<ng-template #reinstate>
{{ 'qa-event-notification.check.notification-reinstate' | translate: { num: source.totalEvents } }}
</ng-template>
</div> </div>
<button [routerLink]="[ getQualityAssuranceRoute(), (source.id | dsSplit: ':')[0], 'target', item.id]" <button [routerLink]="[ getQualityAssuranceRoute(), (source.id | dsSplit: ':')[0], 'target', item.id]"
[queryParams]="{ forward: true }" [queryParams]="{ forward: true }"
class="btn btn-primary align-self-center">{{ this.item.isArchived ? ('qa-event-notification-undo-withdrawn.check.button' | translate) class="btn btn-primary align-self-center">
: ('qa-event-notification-undo-reinstate.check.button' | translate) }}</button> {{'item.qa-event-notification-info.check.button' | translate}}
</button>
</div> </div>
</div> </div>
</ng-container> </ng-container>

View File

@@ -13,7 +13,6 @@ import { RemoteDataBuildService } from '../../../core/cache/builders/remote-data
import { provideMockStore } from '@ngrx/store/testing'; import { provideMockStore } from '@ngrx/store/testing';
import { HALEndpointService } from '../../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../../core/shared/hal-endpoint.service';
import { HALEndpointServiceStub } from '../../../shared/testing/hal-endpoint-service.stub'; import { HALEndpointServiceStub } from '../../../shared/testing/hal-endpoint-service.stub';
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { SplitPipe } from 'src/app/shared/utils/split.pipe'; import { SplitPipe } from 'src/app/shared/utils/split.pipe';
@@ -22,7 +21,6 @@ describe('QaEventNotificationComponent', () => {
let component: QaEventNotificationComponent; let component: QaEventNotificationComponent;
let fixture: ComponentFixture<QaEventNotificationComponent>; let fixture: ComponentFixture<QaEventNotificationComponent>;
let qualityAssuranceSourceDataServiceStub: any; let qualityAssuranceSourceDataServiceStub: any;
let authorizationService: AuthorizationDataService;
const obj = Object.assign(new QualityAssuranceSourceObject(), { const obj = Object.assign(new QualityAssuranceSourceObject(), {
id: 'sourceName:target', id: 'sourceName:target',
@@ -34,9 +32,6 @@ describe('QaEventNotificationComponent', () => {
const objPL = createSuccessfulRemoteDataObject$(createPaginatedList([obj])); const objPL = createSuccessfulRemoteDataObject$(createPaginatedList([obj]));
const item = Object.assign({ uuid: '1234' }); const item = Object.assign({ uuid: '1234' });
beforeEach(async () => { beforeEach(async () => {
authorizationService = jasmine.createSpyObj('authorizationService', {
isAuthorized: of(true)
});
qualityAssuranceSourceDataServiceStub = { qualityAssuranceSourceDataServiceStub = {
getSourcesByTarget: () => objPL getSourcesByTarget: () => objPL
@@ -49,7 +44,6 @@ describe('QaEventNotificationComponent', () => {
{ provide: RequestService, useValue: {} }, { provide: RequestService, useValue: {} },
{ provide: NotificationsService, useValue: {} }, { provide: NotificationsService, useValue: {} },
{ provide: HALEndpointService, useValue: new HALEndpointServiceStub('test') }, { provide: HALEndpointService, useValue: new HALEndpointServiceStub('test') },
{ provide: AuthorizationDataService, useValue: authorizationService },
ObjectCacheService, ObjectCacheService,
RemoteDataBuildService, RemoteDataBuildService,
provideMockStore({}) provideMockStore({})

View File

@@ -9,9 +9,7 @@ import { QualityAssuranceSourceObject } from '../../../core/notifications/qa/mod
import { catchError, map } from 'rxjs/operators'; import { catchError, map } from 'rxjs/operators';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { getNotificatioQualityAssuranceRoute } from '../../../admin/admin-routing-paths'; import { getNotificatioQualityAssuranceRoute } from '../../../admin/admin-routing-paths';
import { PaginatedList } from 'src/app/core/data/paginated-list.model'; import { PaginatedList } from '../../../core/data/paginated-list.model';
import { AuthorizationDataService } from 'src/app/core/data/feature-authorization/authorization-data.service';
import { FeatureID } from 'src/app/core/data/feature-authorization/feature-id';
@Component({ @Component({
selector: 'ds-qa-event-notification', selector: 'ds-qa-event-notification',
@@ -33,17 +31,10 @@ export class QaEventNotificationComponent implements OnChanges {
* An observable that emits an array of QualityAssuranceSourceObject. * An observable that emits an array of QualityAssuranceSourceObject.
*/ */
sources$: Observable<QualityAssuranceSourceObject[]>; sources$: Observable<QualityAssuranceSourceObject[]>;
/**
* An observable that emits a boolean representing whether the current user is an admin.
*/
isAdmin$: Observable<boolean>;
constructor( constructor(
private qualityAssuranceSourceDataService: QualityAssuranceSourceDataService, private qualityAssuranceSourceDataService: QualityAssuranceSourceDataService,
private authService: AuthorizationDataService, ) {}
) {
this.isAdmin$ = this.authService.isAuthorized(FeatureID.AdministratorOf);
}
/** /**
* Detect changes to the item input and update the sources$ observable. * Detect changes to the item input and update the sources$ observable.

View File

@@ -171,7 +171,8 @@ export class MenuResolver implements Resolve<boolean> {
this.authorizationService.isAuthorized(FeatureID.AdministratorOf), this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
this.authorizationService.isAuthorized(FeatureID.CanSubmit), this.authorizationService.isAuthorized(FeatureID.CanSubmit),
this.authorizationService.isAuthorized(FeatureID.CanEditItem), this.authorizationService.isAuthorized(FeatureID.CanEditItem),
]).subscribe(([isCollectionAdmin, isCommunityAdmin, isSiteAdmin, canSubmit, canEditItem]) => { this.authorizationService.isAuthorized(FeatureID.CanSeeQA)
]).subscribe(([isCollectionAdmin, isCommunityAdmin, isSiteAdmin, canSubmit, canEditItem, canSeeQa]) => {
const newSubMenuList = [ const newSubMenuList = [
{ {
id: 'new_community', id: 'new_community',
@@ -362,6 +363,40 @@ export class MenuResolver implements Resolve<boolean> {
icon: 'heartbeat', icon: 'heartbeat',
index: 11 index: 11
}, },
/* Notifications */
{
id: 'notifications',
active: false,
visible: canSeeQa || isSiteAdmin,
model: {
type: MenuItemType.TEXT,
text: 'menu.section.notifications'
} as TextMenuItemModel,
icon: 'bell',
index: 4
},
{
id: 'notifications_quality-assurance',
parentID: 'notifications',
active: false,
visible: canSeeQa,
model: {
type: MenuItemType.LINK,
text: 'menu.section.quality-assurance',
link: '/notifications/quality-assurance'
} as LinkMenuItemModel,
},
{
id: 'notifications_publication-claim',
parentID: 'notifications',
active: false,
visible: isSiteAdmin,
model: {
type: MenuItemType.LINK,
text: 'menu.section.notifications_publication-claim',
link: '/notifications/' + PUBLICATION_CLAIMS_PATH
} as LinkMenuItemModel,
},
]; ];
menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, Object.assign(menuSection, { menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, Object.assign(menuSection, {
shouldPersistOnRouteChange: true shouldPersistOnRouteChange: true
@@ -531,46 +566,9 @@ export class MenuResolver implements Resolve<boolean> {
* Create menu sections dependent on whether or not the current user is a site administrator * Create menu sections dependent on whether or not the current user is a site administrator
*/ */
createSiteAdministratorMenuSections() { createSiteAdministratorMenuSections() {
combineLatest([ this.authorizationService.isAuthorized(FeatureID.AdministratorOf)
this.authorizationService.isAuthorized(FeatureID.AdministratorOf), .subscribe((authorized) => {
this.authorizationService.isAuthorized(FeatureID.CanSeeQA)
])
.subscribe(([authorized, canSeeQA]) => {
const menuList = [ const menuList = [
/* Notifications */
{
id: 'notifications',
active: false,
visible: authorized && canSeeQA,
model: {
type: MenuItemType.TEXT,
text: 'menu.section.notifications'
} as TextMenuItemModel,
icon: 'bell',
index: 4
},
{
id: 'notifications_quality-assurance',
parentID: 'notifications',
active: false,
visible: authorized,
model: {
type: MenuItemType.LINK,
text: 'menu.section.quality-assurance',
link: '/notifications/quality-assurance'
} as LinkMenuItemModel,
},
{
id: 'notifications_publication-claim',
parentID: 'notifications',
active: false,
visible: authorized,
model: {
type: MenuItemType.LINK,
text: 'menu.section.notifications_publication-claim',
link: '/admin/notifications/' + PUBLICATION_CLAIMS_PATH
} as LinkMenuItemModel,
},
/* Admin Search */ /* Admin Search */
{ {
id: 'admin_search', id: 'admin_search',

View File

@@ -1,7 +1,7 @@
<div class="container"> <div class="container">
<ds-suggestions-notification></ds-suggestions-notification>
<ds-my-dspace-qa-events-notifications></ds-my-dspace-qa-events-notifications> <ds-my-dspace-qa-events-notifications></ds-my-dspace-qa-events-notifications>
<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

@@ -18,6 +18,7 @@
</div> </div>
<button <button
[routerLink]="[getQualityAssuranceRoute(), source.id]" [routerLink]="[getQualityAssuranceRoute(), source.id]"
[queryParams]="{ forward: true }"
class="btn btn-primary align-self-center" class="btn btn-primary align-self-center"
> >
{{ "mydspace.qa-event-notification-info.check.button" | translate }} {{ "mydspace.qa-event-notification-info.check.button" | translate }}

View File

@@ -1,6 +1,7 @@
.source-logo { .source-logo {
max-height: var(--ds-header-logo-height); max-height: var(--ds-header-logo-height);
} }
.sections-gap { .sections-gap {
gap: 1rem; gap: 1rem;
} }

View File

@@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { QualityAssuranceSourceDataService } from '../../core/notifications/qa/source/quality-assurance-source-data.service'; import { QualityAssuranceSourceDataService } from '../../core/notifications/qa/source/quality-assurance-source-data.service';
import { getFirstCompletedRemoteData, getPaginatedListPayload, getRemoteDataPayload } from '../../core/shared/operators'; import { getFirstCompletedRemoteData, getPaginatedListPayload, getRemoteDataPayload } from '../../core/shared/operators';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { QualityAssuranceSourceObject } from 'src/app/core/notifications/qa/models/quality-assurance-source.model'; import { QualityAssuranceSourceObject } from './../../core/notifications/qa/models/quality-assurance-source.model';
import { getNotificatioQualityAssuranceRoute } from '../../admin/admin-routing-paths'; import { getNotificatioQualityAssuranceRoute } from '../../admin/admin-routing-paths';
@Component({ @Component({
@@ -16,6 +16,7 @@ export class MyDspaceQaEventsNotificationsComponent implements OnInit {
* An Observable that emits an array of QualityAssuranceSourceObject. * An Observable that emits an array of QualityAssuranceSourceObject.
*/ */
sources$: Observable<QualityAssuranceSourceObject[]> = of([]); sources$: Observable<QualityAssuranceSourceObject[]> = of([]);
constructor(private qualityAssuranceSourceDataService: QualityAssuranceSourceDataService) { } constructor(private qualityAssuranceSourceDataService: QualityAssuranceSourceDataService) { }
ngOnInit(): void { ngOnInit(): void {

View File

@@ -2702,7 +2702,7 @@
"qa-withdrown.modal.form.summary.placeholder": "Enter the reason for the withdrawal", "qa-withdrown.modal.form.summary.placeholder": "Enter the reason for the withdrawal",
"qa-reinstate.modal.form.summary.placeholder": "Enter the reason for the reinstate", "qa-reinstate.modal.form.summary.placeholder": "Enter the reason for the reinstatement",
"item.version.create.modal.submitted.header": "Creating new version...", "item.version.create.modal.submitted.header": "Creating new version...",
@@ -2712,16 +2712,6 @@
"correction-type.manage-relation.action.notification.withdrawn": "Withdraw request sent.", "correction-type.manage-relation.action.notification.withdrawn": "Withdraw request sent.",
"qa-event-notification.check.notification-withdrawn.user": "There are {{num}} items pending review(s) to check.",
"qa-event-notification.check.notification-withdrawn.admin": "There are {{num}} {{source}} feedback(s) pending.",
"qa-event-notification.check.notification-reinstate": "There are {{num}} pending reinstatement(s) pending for this item.",
"qa-event-notification-undo-withdrawn.check.button": "Check",
"qa-event-notification-undo-reinstate.check.button": "Check",
"item.version.create.modal.submitted.text": "The new version is being created. This may take some time if the item has a lot of relationships.", "item.version.create.modal.submitted.text": "The new version is being created. This may take some time if the item has a lot of relationships.",
"item.version.create.notification.success": "New version has been created with version number {{version}}", "item.version.create.notification.success": "New version has been created with version number {{version}}",

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB