Skip to content

Commit 0b69053

Browse files
committed
Merge tag 'dspace-cris-2023.02.00' into ux-plus
Release DSpace-CRIS 7 2023.02.00
2 parents 18efeb8 + d4fb35e commit 0b69053

24 files changed

Lines changed: 244 additions & 232 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dspace-angular",
3-
"version": "2023.02.00-SNAPSHOT",
3+
"version": "2023.02.00",
44
"scripts": {
55
"ng": "ng",
66
"config:watch": "nodemon",

src/app/breadcrumbs/breadcrumbs.component.html

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,11 @@
1010
</nav>
1111

1212
<ng-template #breadcrumb let-text="text" let-url="url">
13-
<li class="breadcrumb-item" *ngVar="(text | translate) as label">
14-
<div class="breadcrumb-item-limiter">
15-
<a [routerLink]="url" class="text-truncate"
16-
[ngbTooltip]="label | dsBreadcrumbTooltip"
17-
placement="bottom"
18-
>{{label | dsTruncateText}}</a>
19-
</div>
20-
</li>
13+
<li class="breadcrumb-item"><div class="breadcrumb-item-limiter"><a [routerLink]="url" class="text-truncate" [ngbTooltip]="text | translate" placement="bottom" >{{text | translate}}</a></div></li>
2114
</ng-template>
2215

2316
<ng-template #activeBreadcrumb let-text="text">
24-
<li class="breadcrumb-item active" aria-current="page" *ngVar="(text | translate) as label">
25-
<div class="breadcrumb-item-limiter">
26-
<div class="text-truncate"
27-
[ngbTooltip]="label | dsBreadcrumbTooltip"
28-
placement="bottom"
29-
>{{label | dsTruncateText}}</div>
30-
</div>
31-
</li>
17+
<li class="breadcrumb-item active" aria-current="page"><div class="breadcrumb-item-limiter"><div class="text-truncate">{{text | translate}}</div></div></li>
3218
</ng-template>
3319
</ng-container>
3420

src/app/breadcrumbs/breadcrumbs.component.spec.ts

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,22 @@ import { TranslateLoaderMock } from '../shared/testing/translate-loader.mock';
1010
import { RouterTestingModule } from '@angular/router/testing';
1111
import { of as observableOf } from 'rxjs';
1212
import { DebugElement } from '@angular/core';
13-
import { BreadcrumbTooltipPipe } from './breadcrumb/breadcrumb-tooltip.pipe';
14-
import { TruncateBreadcrumbItemCharactersPipe } from './breadcrumb/truncate-breadcrumb-item-characters.pipe';
15-
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
1613

1714
describe('BreadcrumbsComponent', () => {
1815
let component: BreadcrumbsComponent;
1916
let fixture: ComponentFixture<BreadcrumbsComponent>;
2017
let breadcrumbsServiceMock: BreadcrumbsService;
21-
let truncateTextPipe: TruncateBreadcrumbItemCharactersPipe;
2218

2319
const expectBreadcrumb = (listItem: DebugElement, text: string, url: string) => {
2420
const anchor = listItem.query(By.css('a'));
25-
const truncatedText = truncateTextPipe.transform(text);
21+
2622
if (url == null) {
2723
expect(anchor).toBeNull();
28-
// remove leading whitespace characters
29-
const textWithoutSpaces = listItem.nativeElement.innerHTML.trimStart().replace(/^\s+/, '');
30-
expect(textWithoutSpaces).toEqual(truncatedText);
24+
expect(listItem.nativeElement.innerHTML).toEqual(text);
3125
} else {
3226
expect(anchor).toBeInstanceOf(DebugElement);
3327
expect(anchor.attributes.href).toEqual(url);
34-
// remove leading whitespace characters
35-
const textWithoutSpaces = anchor.nativeElement.innerHTML.trimStart().replace(/^\s+/, '');
36-
expect(textWithoutSpaces).toEqual(truncatedText);
28+
expect(anchor.nativeElement.innerHTML).toEqual(text);
3729
}
3830
};
3931

@@ -43,7 +35,6 @@ describe('BreadcrumbsComponent', () => {
4335
// NOTE: a root breadcrumb is automatically rendered
4436
new Breadcrumb('bc 1', 'example.com'),
4537
new Breadcrumb('bc 2', 'another.com'),
46-
new Breadcrumb('breadcrumb to be truncated', 'truncated.com'),
4738
]),
4839
showBreadcrumbs$: observableOf(true),
4940
} as BreadcrumbsService;
@@ -52,11 +43,8 @@ describe('BreadcrumbsComponent', () => {
5243
declarations: [
5344
BreadcrumbsComponent,
5445
VarDirective,
55-
BreadcrumbTooltipPipe,
56-
TruncateBreadcrumbItemCharactersPipe,
5746
],
5847
imports: [
59-
NgbTooltipModule,
6048
RouterTestingModule.withRoutes([]),
6149
TranslateModule.forRoot({
6250
loader: {
@@ -67,12 +55,10 @@ describe('BreadcrumbsComponent', () => {
6755
],
6856
providers: [
6957
{ provide: BreadcrumbsService, useValue: breadcrumbsServiceMock },
70-
{ provide: TruncateBreadcrumbItemCharactersPipe, useClass: TruncateBreadcrumbItemCharactersPipe },
7158
],
7259
}).compileComponents();
7360

7461
fixture = TestBed.createComponent(BreadcrumbsComponent);
75-
truncateTextPipe = TestBed.inject(TruncateBreadcrumbItemCharactersPipe);
7662
component = fixture.componentInstance;
7763
fixture.detectChanges();
7864
}));
@@ -81,35 +67,12 @@ describe('BreadcrumbsComponent', () => {
8167
expect(component).toBeTruthy();
8268
});
8369

84-
it('should render the breadcrumbs accordingly', () => {
70+
it('should render the breadcrumbs', () => {
8571
const breadcrumbs = fixture.debugElement.queryAll(By.css('.breadcrumb-item'));
86-
expect(breadcrumbs.length).toBe(4);
72+
expect(breadcrumbs.length).toBe(3);
8773
expectBreadcrumb(breadcrumbs[0], 'home.breadcrumbs', '/');
8874
expectBreadcrumb(breadcrumbs[1], 'bc 1', '/example.com');
8975
expectBreadcrumb(breadcrumbs[2].query(By.css('.text-truncate')), 'bc 2', null);
90-
expectBreadcrumb(breadcrumbs[3].query(By.css('.text-truncate')), 'breadcrumb...', null);
91-
});
92-
93-
it('should show tooltip only for truncated text', () => {
94-
const breadcrumbs = fixture.debugElement.queryAll(By.css('.breadcrumb-item .text-truncate'));
95-
expect(breadcrumbs.length).toBe(4);
96-
97-
const truncatable = breadcrumbs[3];
98-
truncatable.triggerEventHandler('mouseenter', null);
99-
fixture.detectChanges();
100-
let tooltip = truncatable.parent.query(By.css('div.tooltip-inner'));
101-
expect(tooltip).not.toBeNull();
102-
expect(tooltip.nativeElement.innerText).toBe('breadcrumb to be truncated');
103-
truncatable.triggerEventHandler('mouseleave', null);
104-
fixture.detectChanges();
105-
106-
const notTruncatable = breadcrumbs[2];
107-
notTruncatable.triggerEventHandler('mouseenter', null);
108-
fixture.detectChanges();
109-
const tooltip2 = notTruncatable.parent.query(By.css('div.tooltip-inner'));
110-
expect(tooltip2).toBeNull();
111-
notTruncatable.triggerEventHandler('mouseleave', null);
112-
fixture.detectChanges();
11376
});
11477

11578
});

src/app/openaire/openaire.module.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ const MODULES = [
5151
CoreModule.forRoot(),
5252
StoreModule.forFeature('openaire', openaireReducers, storeModuleConfig as StoreConfig<OpenaireState, Action>),
5353
EffectsModule.forFeature(openaireEffects),
54-
TranslateModule
54+
TranslateModule,
55+
SearchModule
5556
];
5657

5758
const COMPONENTS = [
@@ -86,7 +87,6 @@ const PROVIDERS = [
8687
@NgModule({
8788
imports: [
8889
...MODULES,
89-
SearchModule
9090
],
9191
declarations: [
9292
...COMPONENTS,
@@ -96,9 +96,6 @@ const PROVIDERS = [
9696
providers: [
9797
...PROVIDERS
9898
],
99-
entryComponents: [
100-
...ENTRY_COMPONENTS
101-
],
10299
exports: [
103100
...COMPONENTS,
104101
...DIRECTIVES
Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
import { createFeatureSelector, createSelector, MemoizedSelector } from '@ngrx/store';
1+
import { createSelector, MemoizedSelector } from '@ngrx/store';
22
import { subStateSelector } from '../../shared/selector.util';
33
import { openaireSelector, OpenaireState } from '../openaire.reducer';
4-
import { OpenaireSuggestionTarget } from '../../core/openaire/reciter-suggestions/models/openaire-suggestion-target.model';
5-
import { SuggestionTargetState } from './suggestion-targets/suggestion-targets.reducer';
6-
7-
/**
8-
* Returns the Reciter Suggestion Target state.
9-
* @function _getReciterSuggestionTargetState
10-
* @param {AppState} state Top level state.
11-
* @return {OpenaireState}
12-
*/
13-
const _getReciterSuggestionTargetState = createFeatureSelector<OpenaireState>('openaire');
4+
import {
5+
OpenaireSuggestionTarget
6+
} from '../../core/openaire/reciter-suggestions/models/openaire-suggestion-target.model';
7+
import { SuggestionTargetEntry, SuggestionTargetState } from './suggestion-targets/suggestion-targets.reducer';
148

159
// Reciter Suggestion Targets
1610
// ----------------------------------------------------------------------------
@@ -25,73 +19,82 @@ export function reciterSuggestionTargetStateSelector(): MemoizedSelector<Openair
2519
}
2620

2721
/**
28-
* Returns the Reciter Suggestion Targets list.
22+
* Returns the Reciter Suggestion source state
23+
* @function reciterSuggestionTargetObjectSelector
24+
* @return {SuggestionTargetEntry}
25+
*/
26+
export function reciterSuggestionSourceSelector(source: string): MemoizedSelector<OpenaireState, SuggestionTargetEntry> {
27+
return createSelector(reciterSuggestionTargetStateSelector(),(state: SuggestionTargetState) => state.sources[source]);
28+
}
29+
30+
/**
31+
* Returns the Reciter Suggestion Targets list by source.
2932
* @function reciterSuggestionTargetObjectSelector
30-
* @return {OpenaireReciterSuggestionTarget[]}
33+
* @return {OpenaireSuggestionTarget[]}
3134
*/
32-
export function reciterSuggestionTargetObjectSelector(): MemoizedSelector<OpenaireState, OpenaireSuggestionTarget[]> {
33-
return subStateSelector<OpenaireState, OpenaireSuggestionTarget[]>(reciterSuggestionTargetStateSelector(), 'targets');
35+
export function reciterSuggestionTargetObjectSelector(source: string): MemoizedSelector<OpenaireState, OpenaireSuggestionTarget[]> {
36+
return createSelector(reciterSuggestionSourceSelector(source), (state: SuggestionTargetEntry) => state.targets);
3437
}
3538

3639
/**
3740
* Returns true if the Reciter Suggestion Targets are loaded.
3841
* @function isReciterSuggestionTargetLoadedSelector
3942
* @return {boolean}
4043
*/
41-
export const isReciterSuggestionTargetLoadedSelector = createSelector(_getReciterSuggestionTargetState,
42-
(state: OpenaireState) => state.suggestionTarget.loaded
43-
);
44+
export const isReciterSuggestionTargetLoadedSelector = (source: string) => {
45+
return createSelector(reciterSuggestionSourceSelector(source), (state: SuggestionTargetEntry) => state?.loaded || false);
46+
};
4447

4548
/**
4649
* Returns true if the deduplication sets are processing.
4750
* @function isDeduplicationSetsProcessingSelector
4851
* @return {boolean}
4952
*/
50-
export const isreciterSuggestionTargetProcessingSelector = createSelector(_getReciterSuggestionTargetState,
51-
(state: OpenaireState) => state.suggestionTarget.processing
52-
);
53+
export const isreciterSuggestionTargetProcessingSelector = (source: string) => {
54+
return createSelector(reciterSuggestionSourceSelector(source), (state: SuggestionTargetEntry) => state?.processing || false);
55+
};
5356

5457
/**
5558
* Returns the total available pages of Reciter Suggestion Targets.
5659
* @function getreciterSuggestionTargetTotalPagesSelector
5760
* @return {number}
5861
*/
59-
export const getreciterSuggestionTargetTotalPagesSelector = createSelector(_getReciterSuggestionTargetState,
60-
(state: OpenaireState) => state.suggestionTarget.totalPages
61-
);
62+
export const getReciterSuggestionTargetTotalPagesSelector = (source: string) => {
63+
return createSelector(reciterSuggestionSourceSelector(source), (state: SuggestionTargetEntry) => state?.totalPages || 0);
64+
};
6265

6366
/**
6467
* Returns the current page of Reciter Suggestion Targets.
65-
* @function getreciterSuggestionTargetCurrentPageSelector
68+
* @function getReciterSuggestionTargetCurrentPageSelector
6669
* @return {number}
6770
*/
68-
export const getreciterSuggestionTargetCurrentPageSelector = createSelector(_getReciterSuggestionTargetState,
69-
(state: OpenaireState) => state.suggestionTarget.currentPage
70-
);
71+
export const getReciterSuggestionTargetCurrentPageSelector = (source: string) => {
72+
return createSelector(reciterSuggestionSourceSelector(source), (state: SuggestionTargetEntry) => state?.currentPage || 0);
73+
};
7174

7275
/**
7376
* Returns the total number of Reciter Suggestion Targets.
74-
* @function getreciterSuggestionTargetTotalsSelector
77+
* @function getReciterSuggestionTargetTotalsSelector
7578
* @return {number}
7679
*/
77-
export const getreciterSuggestionTargetTotalsSelector = createSelector(_getReciterSuggestionTargetState,
78-
(state: OpenaireState) => state.suggestionTarget.totalElements
79-
);
80+
export const getReciterSuggestionTargetTotalsSelector = (source: string) => {
81+
return createSelector(reciterSuggestionSourceSelector(source), (state: SuggestionTargetEntry) => state?.totalElements || 0);
82+
};
8083

8184
/**
8285
* Returns Suggestion Targets for the current user.
8386
* @function getCurrentUserReciterSuggestionTargetSelector
8487
* @return {OpenaireSuggestionTarget[]}
8588
*/
86-
export const getCurrentUserSuggestionTargetsSelector = createSelector(_getReciterSuggestionTargetState,
87-
(state: OpenaireState) => state.suggestionTarget.currentUserTargets
88-
);
89+
export const getCurrentUserSuggestionTargetsSelector = () => {
90+
return createSelector(reciterSuggestionTargetStateSelector(), (state: SuggestionTargetState) => state?.currentUserTargets || []);
91+
};
8992

9093
/**
91-
* Returns whether or not the user has consulted their suggestions
94+
* Returns whether the user has consulted their suggestions
9295
* @function getCurrentUserReciterSuggestionTargetSelector
9396
* @return {boolean}
9497
*/
95-
export const getCurrentUserSuggestionTargetsVisitedSelector = createSelector(_getReciterSuggestionTargetState,
96-
(state: OpenaireState) => state.suggestionTarget.currentUserTargetsVisited
97-
);
98+
export const getCurrentUserSuggestionTargetsVisitedSelector = () => {
99+
return createSelector(reciterSuggestionTargetStateSelector(), (state: SuggestionTargetState) => state?.currentUserTargetsVisited || false);
100+
};

0 commit comments

Comments
 (0)