Skip to content

Commit f39a6d6

Browse files
Merged in task/dspace-cris-2025_02_x/DSC-2753 (pull request DSpace#4133)
Task/dspace cris 2025 02 x/DSC-2753 Approved-by: Fapohunda, Adamo
2 parents 155fc91 + fd8da14 commit f39a6d6

File tree

7 files changed

+153
-68
lines changed

7 files changed

+153
-68
lines changed

src/app/audit-page/object-audit-overview/object-audit-overview.component.html

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ <h2 class="flex-grow-1">{{'audit.object.overview.title' | translate}}</h2>
55

66
@if (object) {
77
<h4 class="mt-4 mb-4">{{ object.name }} (<em>{{object.type}}</em>)</h4>
8-
@if ((auditsRD$ | async)?.payload; as audits) {
8+
@let auditRD = (auditsRD$ | async);
9+
@let audits = auditRD?.payload;
10+
@if (audits) {
911
@if (audits.totalElements === 0) {
1012
<div>
1113
No audits found.
@@ -29,22 +31,25 @@ <h4 class="mt-4 mb-4">{{ object.name }} (<em>{{object.type}}</em>)</h4>
2931
</tr>
3032
</thead>
3133
<tbody>
32-
@for (audit of audits.page; track audit) {
34+
@for (audit of audits.page; track audit.id) {
3335
<tr>
3436
<!-- <td><a [routerLink]="['/auditlogs/', audit.id]">{{audit.id}}</a></td> -->
3537
<td>{{ audit.eventType }}</td>
36-
<td *ngVar="(getEpersonName(audit) | async) as ePersonName">{{ePersonName}}</td>
38+
<td>
39+
@let epersonName = (audit?.epersonName | async);
40+
@if (epersonName) {
41+
<span>{{epersonName}}</span>
42+
} @else {
43+
<em>{{ 'audit.overview.table.eperson.anonymous' | translate }}</em>
44+
}
45+
</td>
3746
<td>{{ audit.timeStamp | date:dateFormat}}</td>
3847
<td>
3948
@if (object.id === audit.objectUUID) {
40-
<span>
41-
<!-- object.id === audit.objectUUID -->
42-
@if ((getOtherObject(audit, object.id) | async); as subject) {
43-
@if (subject) {
44-
{{ subject.name }} <em>({{ subject.type }})</em>
45-
}
46-
}
47-
</span>
49+
@let subject = $any(audit.subject | async);
50+
@if (subject) {
51+
<span>{{ subject?.name }} <em>({{ subject?.type }})</em></span>
52+
}
4853
}
4954
@if (object.id === audit.subjectUUID) {
5055
<span>
@@ -62,7 +67,7 @@ <h4 class="mt-4 mb-4">{{ object.name }} (<em>{{object.type}}</em>)</h4>
6267
<a class="btn btn-light mt-3" [routerLink]="['/items', object.id]"><i class="fas fa-arrow-left"></i> Back to Item</a>
6368
<!-- <a class="btn btn-light mt-3" [routerLink]="'/auditlogs'">{{'audit.detail.back' | translate}}</a> -->
6469
}
65-
@if ((auditsRD$ | async)?.statusCode === 404) {
70+
@if (auditRD?.statusCode === 404) {
6671
<h4 class="mt-4 mb-4">{{'audit.object.overview.disabled.message' | translate}}</h4>
6772
}
6873
}

src/app/audit-page/object-audit-overview/object-audit-overview.component.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ import {
2626
} from 'rxjs/operators';
2727

2828
import { COLLECTION_PAGE_LINKS_TO_FOLLOW } from '../../collection-page/collection-page.resolver';
29-
import { AuditDataService } from '../../core/audit/audit-data.service';
30-
import { Audit } from '../../core/audit/model/audit.model';
29+
import {
30+
AuditDataService,
31+
AuditDetails,
32+
} from '../../core/audit/audit-data.service';
3133
import { AuthService } from '../../core/auth/auth.service';
3234
import { SortDirection } from '../../core/cache/models/sort-options.model';
3335
import { CollectionDataService } from '../../core/data/collection-data.service';
@@ -44,7 +46,6 @@ import { Item } from '../../core/shared/item.model';
4446
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
4547
import { PaginationComponent } from '../../shared/pagination/pagination.component';
4648
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
47-
import { VarDirective } from '../../shared/utils/var.directive';
4849

4950
/**
5051
* Component displaying a list of all audit about a object in a paginated table
@@ -58,7 +59,6 @@ import { VarDirective } from '../../shared/utils/var.directive';
5859
PaginationComponent,
5960
RouterLink,
6061
TranslateModule,
61-
VarDirective,
6262
],
6363
})
6464
export class ObjectAuditOverviewComponent implements OnInit {
@@ -71,7 +71,7 @@ export class ObjectAuditOverviewComponent implements OnInit {
7171
/**
7272
* List of all audits
7373
*/
74-
auditsRD$: Observable<RemoteData<PaginatedList<Audit>>>;
74+
auditsRD$: Observable<RemoteData<PaginatedList<AuditDetails>>>;
7575

7676
/**
7777
* The current pagination configuration for the page used by the FindAll method
@@ -143,9 +143,13 @@ export class ObjectAuditOverviewComponent implements OnInit {
143143

144144

145145
this.auditsRD$ = combineLatest([isAdmin$, config$, this.owningCollection$, parentCommunity$]).pipe(
146-
mergeMap(([isAdmin, config, owningCollection, parentCommunity]) => {
146+
mergeMap(([isAdmin, config, owningCollection, parentCommunity]) => {
147147
if (isAdmin) {
148-
return this.auditService.findByObject(this.object.id, config, owningCollection.id, parentCommunity.id);
148+
return this.auditService.findByObject(this.object.id, config, owningCollection.id, parentCommunity.id)
149+
.pipe(
150+
getFirstCompletedRemoteData(),
151+
map(data => this.auditService.mapToAuditDetails(data)),
152+
);
149153
}
150154

151155
return of(null);
@@ -166,16 +170,5 @@ export class ObjectAuditOverviewComponent implements OnInit {
166170
);
167171
}
168172

169-
/**
170-
* Get the name of an EPerson by ID
171-
* @param audit Audit object
172-
*/
173-
getEpersonName(audit: Audit): Observable<string> {
174-
return this.auditService.getEpersonName(audit);
175-
}
176-
177-
getOtherObject(audit: Audit, contextObjectId: string): Observable<any> {
178-
return this.auditService.getOtherObject(audit, contextObjectId);
179-
}
180173

181174
}

src/app/audit-page/overview/audit-overview.component.html

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@
33
<h2 class="flex-grow-1">{{'audit.overview.title' | translate}}</h2>
44
</div>
55

6-
@if (isAdmin$ | async) {
7-
@if ((auditsRD$ | async)?.payload?.totalElements === 0) {
6+
@let isAdmin = (isAdmin$ | async);
7+
@if (isAdmin) {
8+
@let audits = (auditsRD$ | async)?.payload;
9+
@if (audits?.totalElements === 0) {
810
<div>
911
No audits found.
1012
</div>
1113
}
12-
@if ((auditsRD$ | async)?.payload?.totalElements > 0) {
14+
@if (audits?.totalElements > 0) {
1315
<ds-pagination
1416
[paginationOptions]="pageConfig"
15-
[collectionSize]="(auditsRD$ | async)?.payload?.totalElements"
17+
[collectionSize]="audits?.totalElements"
1618
[hideGear]="true"
1719
[hidePagerWhenSinglePage]="true">
1820
<div class="table-responsive">
@@ -30,7 +32,8 @@ <h2 class="flex-grow-1">{{'audit.overview.title' | translate}}</h2>
3032
</tr>
3133
</thead>
3234
<tbody>
33-
@for (audit of (auditsRD$ | async)?.payload?.page; track audit) {
35+
@for (audit of audits?.page; track audit.id) {
36+
@let epersonName = (audit.epersonName | async);
3437
<tr>
3538
<td><a [routerLink]="['/auditlogs/', audit.id]">{{audit.id}}</a></td>
3639
<td>{{ audit.eventType }}</td>
@@ -40,7 +43,13 @@ <h2 class="flex-grow-1">{{'audit.overview.title' | translate}}</h2>
4043
<td>{{ audit.objectType }}</td>
4144
<td>{{ audit.subjectUUID }}</td>
4245
<td>{{ audit.subjectType }}</td>
43-
<td *ngVar="(getEpersonName(audit) | async) as ePersonName">{{ePersonName}}</td>
46+
<td>
47+
@if (epersonName) {
48+
<span>{{epersonName}}</span>
49+
} @else {
50+
<span><em>{{ 'audit.overview.table.eperson.anonymous' | translate }}</em></span>
51+
}
52+
</td>
4453
<td>{{ audit.timeStamp | date:dateFormat}}</td>
4554
</tr>
4655
}

src/app/audit-page/overview/audit-overview.component.spec.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { NO_ERRORS_SCHEMA } from '@angular/core';
22
import {
33
ComponentFixture,
4+
fakeAsync,
45
TestBed,
56
waitForAsync,
67
} from '@angular/core/testing';
@@ -9,34 +10,49 @@ import { RouterTestingModule } from '@angular/router/testing';
910
import { TranslateModule } from '@ngx-translate/core';
1011
import { of } from 'rxjs';
1112

12-
import { AuditDataService } from '../../core/audit/audit-data.service';
13+
import {
14+
AuditDataService,
15+
AuditDetails,
16+
} from '../../core/audit/audit-data.service';
1317
import { Audit } from '../../core/audit/model/audit.model';
1418
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
1519
import { PaginationService } from '../../core/pagination/pagination.service';
1620
import { PaginationComponent } from '../../shared/pagination/pagination.component';
17-
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
18-
import { AuditMock } from '../../shared/testing/audit.mock';
21+
import {
22+
createSuccessfulRemoteDataObject,
23+
createSuccessfulRemoteDataObject$,
24+
} from '../../shared/remote-data.utils';
25+
import {
26+
AuditDetailsMock,
27+
AuditMock,
28+
} from '../../shared/testing/audit.mock';
1929
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
2030
import { createPaginatedList } from '../../shared/testing/utils.test';
2131
import { VarDirective } from '../../shared/utils/var.directive';
2232
import { AuditOverviewComponent } from './audit-overview.component';
2333

24-
describe('AuditOverviewComponent', () => {
34+
fdescribe('AuditOverviewComponent', () => {
2535
let component: AuditOverviewComponent;
2636
let fixture: ComponentFixture<AuditOverviewComponent>;
2737

2838
let auditService: AuditDataService;
2939
let authorizationService: any;
3040
let audits: Audit[];
41+
let auditDetails: AuditDetails[];
3142
const paginationService = new PaginationServiceStub();
3243

3344
function init() {
34-
audits = [ AuditMock, AuditMock, AuditMock ];
35-
auditService = jasmine.createSpyObj('processService', {
45+
audits = [AuditMock, AuditMock, AuditMock];
46+
auditDetails = [AuditDetailsMock, AuditDetailsMock, AuditDetailsMock];
47+
auditService = jasmine.createSpyObj('auditService', {
3648
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(audits)),
3749
getEpersonName: of('Eperson Name'),
50+
mapToAuditDetails: createSuccessfulRemoteDataObject(createPaginatedList(auditDetails)),
51+
});
52+
53+
authorizationService = jasmine.createSpyObj('authorizationService', {
54+
isAuthorized: jasmine.createSpy('isAuthorized'),
3855
});
39-
authorizationService = jasmine.createSpyObj('authorizationService', ['isAuthorized']);
4056
}
4157

4258
beforeEach(waitForAsync(() => {
@@ -54,13 +70,13 @@ describe('AuditOverviewComponent', () => {
5470

5571
describe('if the current user is an admin', () => {
5672

57-
beforeEach(() => {
58-
authorizationService.isAuthorized.and.callFake(() => of(true));
73+
beforeEach(fakeAsync(() => {
74+
authorizationService.isAuthorized.and.returnValue(of(true));
5975

6076
fixture = TestBed.createComponent(AuditOverviewComponent);
6177
component = fixture.componentInstance;
6278
fixture.detectChanges();
63-
});
79+
}));
6480

6581
describe('table structure', () => {
6682
let rowElements;
@@ -118,7 +134,7 @@ describe('AuditOverviewComponent', () => {
118134
it('should display the eperson name in the seventh column', () => {
119135
rowElements.forEach((rowElement, index) => {
120136
const el = rowElement.query(By.css('td:nth-child(7)')).nativeElement;
121-
expect(el.textContent).toContain('Eperson Name');
137+
expect(el.textContent).toContain('Eperson Test');
122138
});
123139
});
124140

src/app/audit-page/overview/audit-overview.component.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,25 @@ import {
1212
combineLatest,
1313
Observable,
1414
} from 'rxjs';
15-
import { mergeMap } from 'rxjs/operators';
15+
import {
16+
map,
17+
mergeMap,
18+
} from 'rxjs/operators';
1619

17-
import { AuditDataService } from '../../core/audit/audit-data.service';
18-
import { Audit } from '../../core/audit/model/audit.model';
20+
import {
21+
AuditDataService,
22+
AuditDetails,
23+
} from '../../core/audit/audit-data.service';
1924
import { SortDirection } from '../../core/cache/models/sort-options.model';
2025
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
2126
import { FeatureID } from '../../core/data/feature-authorization/feature-id';
2227
import { FindListOptions } from '../../core/data/find-list-options.model';
2328
import { PaginatedList } from '../../core/data/paginated-list.model';
2429
import { RemoteData } from '../../core/data/remote-data';
2530
import { PaginationService } from '../../core/pagination/pagination.service';
31+
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
2632
import { PaginationComponent } from '../../shared/pagination/pagination.component';
2733
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
28-
import { VarDirective } from '../../shared/utils/var.directive';
2934

3035
/**
3136
* Component displaying a list of all audit in a paginated table
@@ -39,15 +44,14 @@ import { VarDirective } from '../../shared/utils/var.directive';
3944
PaginationComponent,
4045
RouterLink,
4146
TranslateModule,
42-
VarDirective,
4347
],
4448
})
4549
export class AuditOverviewComponent implements OnInit {
4650

4751
/**
4852
* List of all audits
4953
*/
50-
auditsRD$: Observable<RemoteData<PaginatedList<Audit>>>;
54+
auditsRD$: Observable<RemoteData<PaginatedList<AuditDetails>>>;
5155

5256
/**
5357
* Whether user is admin
@@ -101,7 +105,11 @@ export class AuditOverviewComponent implements OnInit {
101105
this.auditsRD$ = combineLatest([this.isAdmin$, config$]).pipe(
102106
mergeMap(([isAdmin, config]) => {
103107
if (isAdmin) {
104-
return this.auditService.findAll(config);
108+
return this.auditService.findAll(config)
109+
.pipe(
110+
getFirstCompletedRemoteData(),
111+
map(data => this.auditService.mapToAuditDetails(data)),
112+
);
105113
}
106114
}),
107115
);
@@ -111,12 +119,4 @@ export class AuditOverviewComponent implements OnInit {
111119
return this.authorizationService.isAuthorized(FeatureID.AdministratorOf, undefined, undefined);
112120
}
113121

114-
/**
115-
* Get the name of an EPerson by ID
116-
* @param audit Audit object
117-
*/
118-
getEpersonName(audit: Audit): Observable<string> {
119-
return this.auditService.getEpersonName(audit);
120-
}
121-
122122
}

0 commit comments

Comments
 (0)