Skip to content

Commit c64bb60

Browse files
refactor(audit): streamline imports and enhance audit details mapping
Improves table loading, there was a persistent re-rendering of the table caused by the getEpersonName method call with | async subscription. ref: DSC-2753,CST-24919 # Conflicts: # src/app/audit-page/object-audit-overview/object-audit-overview.component.html # src/app/audit-page/object-audit-overview/object-audit-overview.component.ts # src/app/audit-page/overview/audit-overview.component.html # src/app/audit-page/overview/audit-overview.component.ts
1 parent 4ddefe4 commit c64bb60

5 files changed

Lines changed: 83 additions & 51 deletions

File tree

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ <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 audits = (auditsRD$ | async)?.payload;
9+
@if (audits) {
910
@if (audits.totalElements === 0) {
1011
<div>
1112
No audits found.
@@ -33,16 +34,22 @@ <h4 class="mt-4 mb-4">{{ object.name }} (<em>{{object.type}}</em>)</h4>
3334
<tr>
3435
<!-- <td><a [routerLink]="['/auditlogs/', audit.id]">{{audit.id}}</a></td> -->
3536
<td>{{ audit.eventType }}</td>
36-
<td *ngVar="(getEpersonName(audit) | async) as ePersonName">{{ePersonName}}</td>
37+
<td>
38+
@let epersonName = (audit?.epersonName | async);
39+
@if (epersonName) {
40+
<span>{{epersonName}}</span>
41+
} @else {
42+
<em>{{ 'audit.overview.table.eperson.anonymous' | translate }}</em>
43+
}
44+
</td>
3745
<td>{{ audit.timeStamp | date:dateFormat}}</td>
3846
<td>
3947
@if (object.id === audit.objectUUID) {
4048
<span>
4149
<!-- object.id === audit.objectUUID -->
42-
@if ((getOtherObject(audit, object.id) | async); as subject) {
43-
@if (subject) {
44-
{{ subject.name }} <em>({{ subject.type }})</em>
45-
}
50+
@let subject = (audit.subject | async);
51+
@if (subject) {
52+
{{ subject.name }} <em>({{ subject.type }})</em>
4653
}
4754
</span>
4855
}
@@ -62,7 +69,7 @@ <h4 class="mt-4 mb-4">{{ object.name }} (<em>{{object.type}}</em>)</h4>
6269
<a class="btn btn-light mt-3" [routerLink]="['/items', object.id]"><i class="fas fa-arrow-left"></i> Back to Item</a>
6370
<!-- <a class="btn btn-light mt-3" [routerLink]="'/auditlogs'">{{'audit.detail.back' | translate}}</a> -->
6471
}
65-
@if ((auditsRD$ | async)?.statusCode === 404) {
72+
@if (audits?.statusCode === 404) {
6673
<h4 class="mt-4 mb-4">{{'audit.object.overview.disabled.message' | translate}}</h4>
6774
}
6875
}

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.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,21 @@ import {
77
OnInit,
88
} from '@angular/core';
99
import { RouterLink } from '@angular/router';
10+
import { getFirstCompletedRemoteData } from '@core/shared/operators';
1011
import { TranslateModule } from '@ngx-translate/core';
1112
import {
1213
combineLatest,
1314
Observable,
1415
} from 'rxjs';
15-
import { mergeMap } from 'rxjs/operators';
16+
import {
17+
map,
18+
mergeMap,
19+
} from 'rxjs/operators';
1620

17-
import { AuditDataService } from '../../core/audit/audit-data.service';
18-
import { Audit } from '../../core/audit/model/audit.model';
21+
import {
22+
AuditDataService,
23+
AuditDetails,
24+
} from '../../core/audit/audit-data.service';
1925
import { SortDirection } from '../../core/cache/models/sort-options.model';
2026
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
2127
import { FeatureID } from '../../core/data/feature-authorization/feature-id';
@@ -25,7 +31,6 @@ import { RemoteData } from '../../core/data/remote-data';
2531
import { PaginationService } from '../../core/pagination/pagination.service';
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
}

src/app/core/audit/audit-data.service.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,19 @@ import { RemoteData } from '../data/remote-data';
3131
import { RequestService } from '../data/request.service';
3232
import { EPerson } from '../eperson/models/eperson.model';
3333
import { HALEndpointService } from '../shared/hal-endpoint.service';
34-
import {
35-
getFirstSucceededRemoteDataPayload,
36-
getFirstSucceededRemoteDataWithNotEmptyPayload,
37-
} from '../shared/operators';
34+
import { getFirstSucceededRemoteDataPayload } from '../shared/operators';
3835
import { Audit } from './model/audit.model';
3936

4037
export const AUDIT_PERSON_NOT_AVAILABLE = 'n/a';
4138

4239
export const AUDIT_FIND_BY_OBJECT_SEARCH_METHOD = 'findByObject';
4340

41+
export type AuditDetails = Audit & {
42+
epersonName: Observable<string>,
43+
subject: Observable<any>
44+
};
45+
46+
4447
@Injectable({ providedIn: 'root' })
4548
export class AuditDataService extends IdentifiableDataService<Audit>{
4649

@@ -120,7 +123,7 @@ export class AuditDataService extends IdentifiableDataService<Audit>{
120123

121124
// TODO to be reviewed when https://github.com/DSpace/dspace-angular/issues/644 will be resolved
122125
return audit.eperson.pipe(
123-
getFirstSucceededRemoteDataWithNotEmptyPayload(),
126+
getFirstSucceededRemoteDataPayload(),
124127
map((eperson: EPerson) => this.dsoNameService.getName(eperson)),
125128
startWith(AUDIT_PERSON_NOT_AVAILABLE));
126129
}
@@ -156,4 +159,24 @@ export class AuditDataService extends IdentifiableDataService<Audit>{
156159
}
157160
}
158161

162+
mapToAuditDetails(rdAudit: RemoteData<PaginatedList<Audit>>): RemoteData<PaginatedList<AuditDetails>> {
163+
return Object.assign(
164+
rdAudit,
165+
{
166+
payload: Object.assign(rdAudit?.payload, {
167+
page: (rdAudit?.payload?.page || [])?.map(
168+
(audit) => {
169+
return Object.assign(
170+
audit, {
171+
epersonName: this.getEpersonName(audit),
172+
subject: this.getOtherObject(audit, audit.objectUUID),
173+
});
174+
},
175+
),
176+
},
177+
),
178+
},
179+
);
180+
}
181+
159182
}

0 commit comments

Comments
 (0)