Skip to content

Commit

Permalink
Merged dspace-cris-2023_02_x into DSC-1486-item-page-resolver-mainten…
Browse files Browse the repository at this point in the history
…ance
  • Loading branch information
vins01-4science committed Feb 9, 2024
2 parents 9acb3b6 + 0a0227f commit 8393cc9
Show file tree
Hide file tree
Showing 25 changed files with 472 additions and 61 deletions.
1 change: 1 addition & 0 deletions src/app/core/eperson/group-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { Operation } from 'fast-json-patch';
import { RestRequestMethod } from '../data/rest-request-method';
import { dataService } from '../data/base/data-service.decorator';
import { getGroupEditRoute } from '../../access-control/access-control-routing-paths';
import { isNotEmpty } from '../../shared/empty.util';

const groupRegistryStateSelector = (state: AppState) => state.groupRegistry;
const editGroupSelector = createSelector(groupRegistryStateSelector, (groupRegistryState: GroupRegistryState) => groupRegistryState.editGroup);
Expand Down
76 changes: 68 additions & 8 deletions src/app/core/metadata/metadata.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ export class MetadataService {
this.setCitationTechnicalReportNumberTag();
}

this.setOpenGraphTitleTag();
this.setOpenGraphDescriptionTag();
this.setOpenGraphImageTag();

this.setTwitterTitleTag();
this.setTwitterDescriptionTag();
this.setTwitterImageTag();
}

/**
Expand Down Expand Up @@ -401,22 +408,75 @@ export class MetadataService {
* Add <meta name="citation_pdf_url" ... > to the <head>
*/
private setCitationPdfUrlTag(): void {
this.setPrimaryBitstreamInBundleTag('ORIGINAL', 'citation_pdf_url');
}

/**
* Add <meta name="og:title" ... > to the <head>
*/
private setOpenGraphTitleTag(): void {
const value = this.getMetaTagValue('dc.title');
this.addMetaTag('og:title', value);
}

/**
* Add <meta name="og:description" ... > to the <head>
*/
private setOpenGraphDescriptionTag(): void {
// TODO: truncate abstract
const value = this.getMetaTagValue('dc.description.abstract');
this.addMetaTag('og:description', value);
}

/**
* Add <meta name="og:image" ... > to the <head>
*/
private setOpenGraphImageTag(): void {
this.setPrimaryBitstreamInBundleTag('THUMBNAIL', 'og:image');
}


/**
* Add <meta name="twitter:title" ... > to the <head>
*/
private setTwitterTitleTag(): void {
const value = this.getMetaTagValue('dc.title');
this.addMetaTag('twitter:title', value);
}

/**
* Add <meta name="twitter:description" ... > to the <head>
*/
private setTwitterDescriptionTag(): void {
// TODO: truncate abstract
const value = this.getMetaTagValue('dc.description.abstract');
this.addMetaTag('twitter:description', value);
}

/**
* Add <meta name="twitter:image" ... > to the <head>
*/
private setTwitterImageTag(): void {
this.setPrimaryBitstreamInBundleTag('THUMBNAIL', 'twitter:image');
}

private setPrimaryBitstreamInBundleTag(bundleName: string, tag: string): void {
if (this.currentObject.value instanceof Item) {
const item = this.currentObject.value as Item;

// Retrieve the ORIGINAL bundle for the item
// Retrieve the bundle for the item
this.bundleDataService.findByItemAndName(
item,
'ORIGINAL',
bundleName,
true,
true,
followLink('primaryBitstream'),
followLink('bitstreams', {
findListOptions: {
// limit the number of bitstreams used to find the citation pdf url to the number
// shown by default on an item page
elementsPerPage: this.appConfig.item.bitstream.pageSize
}
findListOptions: {
// limit the number of bitstreams used to find the citation pdf url to the number
// shown by default on an item page
elementsPerPage: this.appConfig.item.bitstream.pageSize
}
}, followLink('format')),
).pipe(
getFirstSucceededRemoteDataPayload(),
Expand Down Expand Up @@ -460,7 +520,7 @@ export class MetadataService {
).subscribe((link: string) => {
// Use the found link to set the <meta> tag
this.addMetaTag(
'citation_pdf_url',
tag,
new URLCombiner(this.hardRedirectService.getCurrentOrigin(), link).toString()
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ describe('ThumbnailComponent', () => {
}));

it('should show default thumbnail', () => {
expect(component.default).toBe('assets/images/person-placeholder.svg');
expect(component.default).toBe('assets/images/file-placeholder.svg');
});

});
Expand All @@ -172,7 +172,7 @@ describe('ThumbnailComponent', () => {
}));

it('should show default thumbnail', () => {
expect(component.default).toBe('assets/images/person-placeholder.svg');
expect(component.default).toBe('assets/images/file-placeholder.svg');
});

});
Expand Down Expand Up @@ -239,7 +239,7 @@ describe('ThumbnailComponent', () => {
});

it('should show default thumbnail', () => {
expect(component.default).toBe('assets/images/person-placeholder.svg');
expect(component.default).toBe('assets/images/file-placeholder.svg');
});

});
Expand All @@ -254,7 +254,7 @@ describe('ThumbnailComponent', () => {
});

it('should not show bitstream content image src but the default image', () => {
expect(component.default).toBe('assets/images/person-placeholder.svg');
expect(component.default).toBe('assets/images/file-placeholder.svg');
});

});
Expand All @@ -269,7 +269,7 @@ describe('ThumbnailComponent', () => {
});

it('should not show thumbnail content image src but the default image', () => {
expect(component.default).toBe('assets/images/person-placeholder.svg');
expect(component.default).toBe('assets/images/file-placeholder.svg');
});

});
Expand All @@ -284,7 +284,7 @@ describe('ThumbnailComponent', () => {
});

it('should not show thumbnail content image src but the default image', () => {
expect(component.default).toBe('assets/images/person-placeholder.svg');
expect(component.default).toBe('assets/images/file-placeholder.svg');
});

});
Expand Down
48 changes: 45 additions & 3 deletions src/app/shared/cookies/browser-klaro.service.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { Inject, Injectable, InjectionToken } from '@angular/core';
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
import { AuthService } from '../../core/auth/auth.service';
import { TranslateService } from '@ngx-translate/core';
import { environment } from '../../../environments/environment';
import { map, switchMap, take } from 'rxjs/operators';
import { EPerson } from '../../core/eperson/models/eperson.model';
import { KlaroService } from './klaro.service';
import { CookieConsents, KlaroService } from './klaro.service';
import { hasValue, isEmpty, isNotEmpty } from '../empty.util';
import { CookieService } from '../../core/services/cookie.service';
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
import cloneDeep from 'lodash/cloneDeep';
import debounce from 'lodash/debounce';
import { ANONYMOUS_STORAGE_NAME_KLARO, klaroConfiguration } from './klaro-configuration';
import { Operation } from 'fast-json-patch';
import { deepClone, Operation } from 'fast-json-patch';
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import { ConfigurationDataService } from '../../core/data/configuration-data.service';
import { CAPTCHA_NAME } from '../../core/google-recaptcha/google-recaptcha.service';
import isEqual from 'lodash/isEqual';

/**
* Metadata field to store a user's cookie consent preferences in
Expand Down Expand Up @@ -65,11 +66,19 @@ export class BrowserKlaroService extends KlaroService {

private readonly GOOGLE_ANALYTICS_SERVICE_NAME = 'google-analytics';

private lastCookiesConsents: CookieConsents;

/**
* Initial Klaro configuration
*/
klaroConfig = cloneDeep(klaroConfiguration);

/**
* Subject to emit updates in the consents
*/
consentsUpdates$: BehaviorSubject<CookieConsents> = new BehaviorSubject<CookieConsents>(null);


constructor(
private translateService: TranslateService,
private authService: AuthService,
Expand All @@ -94,6 +103,20 @@ export class BrowserKlaroService extends KlaroService {
this.klaroConfig.translations.zz.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy';
}

if (hasValue(environment.info.metricsConsents)) {
environment.info.metricsConsents.forEach((metric) => {
if (metric.enabled) {
this.klaroConfig.services.push(
{
name: metric.key,
purposes: ['thirdPartyJs'],
required: false,
}
);
}
});
}

const hideGoogleAnalytics$ = this.configService.findByPropertyName(this.GOOGLE_ANALYTICS_KEY).pipe(
getFirstCompletedRemoteData(),
map(remoteData => !remoteData.hasSucceeded || !remoteData.payload || isEmpty(remoteData.payload.values)),
Expand Down Expand Up @@ -331,6 +354,25 @@ export class BrowserKlaroService extends KlaroService {
return 'klaro-' + identifier;
}

watchConsentUpdates(): void {
this.lazyKlaro.then(({getManager}) => {
const manager = getManager(this.klaroConfig);
const consentsSubject$ = this.consentsUpdates$;
let lastCookiesConsents = this.lastCookiesConsents;

consentsSubject$.next(manager.consents);
manager.watch({
update(_, eventName, consents) {

if (eventName === 'consents' && !isEqual(consents, lastCookiesConsents)) {
lastCookiesConsents = deepClone(consents);
consentsSubject$.next(consents);
}
}
});
});
}

/**
* remove the google analytics from the services
*/
Expand Down
20 changes: 16 additions & 4 deletions src/app/shared/cookies/klaro.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Injectable } from '@angular/core';

import { Observable } from 'rxjs';

import { BehaviorSubject, Observable } from 'rxjs';
export interface CookieConsents {
[key: string]: boolean;
}
/**
* Abstract class representing a service for handling Klaro consent preferences and UI
*/
Expand All @@ -10,15 +12,25 @@ export abstract class KlaroService {
/**
* Initializes the service
*/
abstract initialize();
abstract initialize(): void;

/**
* Shows a dialog with the current consent preferences
*/
abstract showSettings();
abstract showSettings(): void;

/**
* Return saved preferences stored in the klaro cookie
*/
abstract getSavedPreferences(): Observable<any>;

/**
* Watch for changes in consents
*/
abstract watchConsentUpdates(): void;

/**
* Subject to emit updates in the consents
*/
abstract consentsUpdates$: BehaviorSubject<CookieConsents>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { FeatureID } from '../../../../core/data/feature-authorization/feature-i
templateUrl: '../dso-selector-modal-wrapper.component.html',
})
export class ExportBatchSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
configuration = 'backend';
configuration = 'communityOrCollection';
objectType = DSpaceObjectType.DSPACEOBJECT;
selectorTypes = [DSpaceObjectType.COLLECTION];
action = SelectorActionType.EXPORT_BATCH;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Observable, of } from 'rxjs';
templateUrl: '../dso-selector-modal-wrapper.component.html',
})
export class ImportBatchSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
configuration = 'backend';
configuration = 'communityOrCollection';
objectType = DSpaceObjectType.DSPACEOBJECT;
selectorTypes = [DSpaceObjectType.COLLECTION];
action = SelectorActionType.IMPORT_BATCH;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<div class="row d-flex align-items-center"
*ngIf="!failed && !(isHidden$ | async) && (remark | dsListMetricProps: 'data-badge-enabled':isListElement == true)">
*ngIf="(!failed &&
canLoadScript &&
!(isHidden$ | async) &&
(remark | dsListMetricProps: 'data-badge-enabled':isListElement == true))"
>
<div class="col-5 text-left">
<div #metricChild>
<div
class="altmetric-embed"
[attr.data-hide-no-mentions]="remark | dsListMetricProps : 'data-hide-no-mentions' : isListElement"
[attr.data-hide-no-mentions]="visibleWithoutData ? false : (remark | dsListMetricProps : 'data-hide-no-mentions' : isListElement)"
[attr.data-hide-less-than]="remark | dsListMetricProps : 'data-hide-less-than' : isListElement"
[attr.data-badge-details]="remark | dsListMetricProps : 'data-badge-details' : isListElement"
[attr.data-badge-type]="remark | dsListMetricProps : 'badgeType' : isListElement"
Expand All @@ -21,3 +25,9 @@
</div>
</div>
</div>
<div class="row d-flex align-items-center justify-content-center m-2" *ngIf="!canLoadScript && !isListElement">
<div>
{{ "third-party-metrics-cookies.message" | translate: {metricType: metric.metricType | titlecase} }}
<div role="button" class="btn-link" (click)="requestSettingsConsent.emit(true)">{{"third-party-metrics-cookies.consent-settings" | translate}}</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<div class="row d-flex align-items-center"
*ngIf="!(isHidden$ | async) && !failed && (remark | dsListMetricProps: 'data-badge-enabled':isListElement == true)">
*ngIf="!(isHidden$ | async) &&
canLoadScript &&
!failed &&
(remark | dsListMetricProps: 'data-badge-enabled':isListElement == true)"
>
<div class="col-5 text-left">
<div
#metricChild
class="__dimensions_badge_embed__"
[attr.data-hide-zero-citations]="remark | dsListMetricProps: 'data-hide-zero-citations':isListElement"
[attr.data-hide-zero-citations]="visibleWithoutData ? false : (remark | dsListMetricProps: 'data-hide-zero-citations':isListElement)"
[attr.data-pmid]="
(remark | dsListMetricProps: 'data-doi':isListElement)
? null
Expand All @@ -21,3 +25,9 @@
</div>
</div>
</div>
<div class="row d-flex align-items-center justify-content-center m-2" *ngIf="!canLoadScript && !isListElement">
<div>
{{ "third-party-metrics-cookies.message" | translate: {metricType: metric.metricType | titlecase} }}
<div role="button" class="btn-link" (click)="requestSettingsConsent.emit(true)">{{"third-party-metrics-cookies.consent-settings" | translate}}</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export abstract class BaseEmbeddedMetricComponent extends BaseMetricComponent im
* When the html content has been initialized, initialize the script.
*/
ngAfterViewInit() {
if (this.metric) {
if (this.metric && this.canLoadScript) {
this.initScript();
}
}
Expand Down
Loading

0 comments on commit 8393cc9

Please sign in to comment.