Skip to content

Commit 7834594

Browse files
committed
Merge remote-tracking branch 'bitbucket4science/main-cris' into main-cris
2 parents 407d8ff + f8437c1 commit 7834594

37 files changed

Lines changed: 226 additions & 34 deletions

File tree

src/app/core/data/feature-authorization/feature-id.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ export enum FeatureID {
4141
EPersonForgotPassword = 'epersonForgotPassword',
4242
ShowClaimItem = 'showClaimItem',
4343
CanCorrectItem = 'canCorrectItem',
44+
CanViewInWorkflowSinceStatistics = 'canViewInWorkflowSinceStatistics',
4445
}

src/app/my-dspace-page/my-dspace-page.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
[selectable]="(currentConfiguration$ | async) === workflowType"
1414
[selectionConfig]="{ repeatable: true, listId: listId }"
1515
(deselectObject)="onDeselectObject($event)"
16-
(selectObject)="onSelectObject($event)">
16+
(selectObject)="onSelectObject($event)"
17+
[showWorkflowStatistics]="true">
1718
<!-- Using *ngIf breaks the projection, so we are using hidden instead -->
1819
<ds-my-dspace-bulk-action [hidden]="(currentConfiguration$ | async) !== workflowType"
1920
bulkActions

src/app/shared/object-collection/object-collection.component.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
[showPaginator]="showPaginator"
1313
[showThumbnails]="showThumbnails"
1414
[showCorrection]="showCorrection"
15+
[showWorkflowStatistics]="showWorkflowStatistics"
1516
(paginationChange)="onPaginationChange($event)"
1617
(pageChange)="onPageChange($event)"
1718
(pageSizeChange)="onPageSizeChange($event)"
@@ -43,6 +44,7 @@
4344
[showMetrics]="showMetrics"
4445
[showPaginator]="showPaginator"
4546
[showThumbnails]="showThumbnails"
47+
[showWorkflowStatistics]="showWorkflowStatistics"
4648
(paginationChange)="onPaginationChange($event)"
4749
(pageChange)="onPageChange($event)"
4850
(pageSizeChange)="onPageSizeChange($event)"
@@ -62,6 +64,7 @@
6264
[showMetrics]="showMetrics"
6365
[showPaginator]="showPaginator"
6466
[showThumbnails]="showThumbnails"
67+
[showWorkflowStatistics]="showWorkflowStatistics"
6568
(contentChange)="contentChange.emit($event)"
6669
*ngIf="(currentMode$ | async) === viewModeEnum.DetailedListElement">
6770
</ds-object-detail>

src/app/shared/object-collection/object-collection.component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ export class ObjectCollectionComponent implements OnInit {
154154
*/
155155
@Input() showCorrection = false;
156156

157+
/**
158+
* A boolean representing if to show workflow statistics
159+
*/
160+
@Input() showWorkflowStatistics;
161+
157162
/**
158163
* Whether or not to show an alert for hidden related items
159164
*/
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div *ngIf="canViewInWorkflowSinceStatistics$ | async" >
2+
<div *ngIf="canViewInWorkflowForDate$ | async">
3+
{{'mydspace.results.in-workflow-for' | translate}} {{inWorkflowFor$ | async}}
4+
</div>
5+
<div *ngIf="canViewInWorkflowSinceDate$ | async">
6+
{{'mydspace.results.in-workflow-since' | translate}} {{inWorkflowSince$ | async}}
7+
</div>
8+
</div>

src/app/shared/object-collection/shared/in-workflow-statistics/in-workflow-statistics.component.scss

Whitespace-only changes.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import {
2+
AsyncPipe,
3+
NgIf,
4+
} from '@angular/common';
5+
import {
6+
Component,
7+
Input,
8+
OnInit,
9+
} from '@angular/core';
10+
import { TranslateModule } from '@ngx-translate/core';
11+
import {
12+
differenceInDays,
13+
differenceInMilliseconds,
14+
parseISO,
15+
} from 'date-fns';
16+
import {
17+
BehaviorSubject,
18+
Observable,
19+
switchMap,
20+
} from 'rxjs';
21+
import {
22+
map,
23+
take,
24+
} from 'rxjs/operators';
25+
26+
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
27+
import { FeatureID } from '../../../../core/data/feature-authorization/feature-id';
28+
import { ItemDataService } from '../../../../core/data/item-data.service';
29+
import { Item } from '../../../../core/shared/item.model';
30+
import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
31+
import { hasValue } from '../../../empty.util';
32+
33+
@Component({
34+
selector: 'ds-in-workflow-statistics',
35+
templateUrl: './in-workflow-statistics.component.html',
36+
standalone: true,
37+
styleUrls: ['./in-workflow-statistics.component.scss'],
38+
imports: [
39+
TranslateModule,
40+
AsyncPipe,
41+
NgIf,
42+
],
43+
})
44+
export class InWorkflowStatisticsComponent implements OnInit {
45+
46+
@Input() item: Item;
47+
48+
canViewInWorkflowSinceStatistics$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
49+
canViewInWorkflowForDate$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
50+
canViewInWorkflowSinceDate$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
51+
inWorkflowFor$: BehaviorSubject<string> = new BehaviorSubject<string>(null);
52+
inWorkflowSince$: BehaviorSubject<string> = new BehaviorSubject<string>(null);
53+
54+
constructor(
55+
private authorizationService: AuthorizationDataService,
56+
private itemDataService: ItemDataService,
57+
) {
58+
}
59+
60+
ngOnInit(): void {
61+
this.canViewInWorkflowSinceStatistics().pipe(take(1))
62+
.subscribe((result: boolean) => {
63+
if (result) {
64+
this.initWorkflowDates();
65+
}
66+
this.canViewInWorkflowSinceStatistics$.next(result);
67+
});
68+
}
69+
70+
public canViewInWorkflowSinceStatistics(): Observable<boolean> {
71+
if (hasValue(this.item?.self)) {
72+
return this.isUserAuthorizedToViewItemInWorkflow(this.item.self);
73+
} else {
74+
// If self link has no value we fetch again the item from the rest.
75+
// Since at this stage the item has most likely already been fetched we will get it from the cache
76+
return this.itemDataService.findById(this.item.id).pipe(
77+
getFirstCompletedRemoteData(),
78+
map(data => data.payload.self),
79+
switchMap(selfLink => this.isUserAuthorizedToViewItemInWorkflow(selfLink)),
80+
);
81+
}
82+
}
83+
84+
public getDateForArchivedItem(itemStartDate: string, dateAccessioned: string) {
85+
const itemStartDateConverted: Date = parseISO(itemStartDate);
86+
const dateAccessionedConverted: Date = parseISO(dateAccessioned);
87+
const days: number = Math.max(0, Math.floor(differenceInDays(dateAccessionedConverted, itemStartDateConverted)));
88+
const remainingMilliseconds: number = differenceInMilliseconds(dateAccessionedConverted, itemStartDateConverted) - days * 24 * 60 * 60 * 1000;
89+
const hours: number = Math.max(0, Math.floor(remainingMilliseconds / (60 * 60 * 1000)));
90+
return `${days} d ${hours} h`;
91+
}
92+
93+
public getDateForItem(itemStartDate: string) {
94+
const itemStartDateConverted: Date = parseISO(itemStartDate);
95+
const days: number = Math.max(0, Math.floor(differenceInDays(Date.now(), itemStartDateConverted)));
96+
const remainingMilliseconds: number = differenceInMilliseconds(Date.now(), itemStartDateConverted) - days * 24 * 60 * 60 * 1000;
97+
const hours: number = Math.max(0, Math.floor(remainingMilliseconds / (60 * 60 * 1000)));
98+
return `${days} d ${hours} h`;
99+
}
100+
101+
initWorkflowDates(): void {
102+
if (this.item) {
103+
if (this.item.isArchived) {
104+
if (this.item.hasMetadata('dspace.workflow.startDateTime') && this.item.hasMetadata('dc.date.accessioned')) {
105+
this.canViewInWorkflowForDate$.next(true);
106+
this.inWorkflowFor$.next(
107+
this.getDateForArchivedItem(this.item.firstMetadataValue('dspace.workflow.startDateTime'), this.item.firstMetadataValue('dc.date.accessioned')),
108+
);
109+
}
110+
} else if (this.item.hasMetadata('dspace.workflow.startDateTime')) {
111+
this.canViewInWorkflowSinceDate$.next(true);
112+
this.inWorkflowSince$.next(
113+
this.getDateForItem(this.item.firstMetadataValue('dspace.workflow.startDateTime')),
114+
);
115+
}
116+
}
117+
}
118+
119+
private isUserAuthorizedToViewItemInWorkflow(selfLink: string): Observable<boolean> {
120+
return this.authorizationService.isAuthorized(FeatureID.CanViewInWorkflowSinceStatistics, selfLink);
121+
}
122+
}

src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ export class ListableObjectComponentLoaderComponent extends AbstractComponentLoa
8080
*/
8181
@Input() showCorrection = false;
8282

83+
/**
84+
* A boolean representing if to show workflow statistics
85+
*/
86+
@Input() showWorkflowStatistics: boolean;
87+
8388
/**
8489
* The value to display for this element
8590
*/
@@ -130,6 +135,7 @@ export class ListableObjectComponentLoaderComponent extends AbstractComponentLoa
130135
'showMetrics',
131136
'showThumbnails',
132137
'showCorrection',
138+
'showWorkflowStatistics',
133139
'context',
134140
'viewMode',
135141
'value',

src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ export class AbstractListableElementComponent<T extends ListableObject> {
6464
*/
6565
@Input() showThumbnails: boolean;
6666

67+
/**
68+
* A boolean representing if to show workflow statistics
69+
*/
70+
@Input() showWorkflowStatistics = false;
71+
6772
/**
6873
* The context we matched on to get this component
6974
*/

src/app/shared/object-detail/object-detail.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
[showLabel]="showLabel"
2424
[showMetrics]="showMetrics"
2525
[showThumbnails]="showThumbnails"
26+
[showWorkflowStatistics]="showWorkflowStatistics"
2627
(contentChange)="contentChange.emit($event)"></ds-listable-object-component-loader>
2728
</div>
2829
</div>

0 commit comments

Comments
 (0)