Merge remote-tracking branch 'github/main' into task/main/CST-15074

# Conflicts:
#	src/assets/i18n/en.json5
This commit is contained in:
Vincenzo Mecca
2025-03-23 15:44:38 +01:00
14 changed files with 5235 additions and 833 deletions

View File

@@ -1,5 +1,4 @@
import { testA11y } from 'cypress/support/utils'; import { testA11y } from 'cypress/support/utils';
import { Options } from 'cypress-axe';
describe('Admin Sidebar', () => { describe('Admin Sidebar', () => {
beforeEach(() => { beforeEach(() => {
@@ -16,13 +15,6 @@ describe('Admin Sidebar', () => {
cy.get('ds-expandable-admin-sidebar-section').click({ multiple: true }); cy.get('ds-expandable-admin-sidebar-section').click({ multiple: true });
// Analyze <ds-admin-sidebar> for accessibility // Analyze <ds-admin-sidebar> for accessibility
testA11y('ds-admin-sidebar', testA11y('ds-admin-sidebar');
{
rules: {
// Currently all expandable sections have nested interactive elements
// See https://github.com/DSpace/dspace-angular/issues/2178
'nested-interactive': { enabled: false },
},
} as Options);
}); });
}); });

View File

@@ -1,10 +1,16 @@
{ {
"extends": "../tsconfig.json", "extends": "../tsconfig.json",
"include": [ "include": [
"**/*.ts" "**/*.ts",
"../cypress.config.ts"
], ],
"compilerOptions": { "compilerOptions": {
"sourceMap": false, "sourceMap": false,
"typeRoots": [
"../node_modules",
"../node_modules/@types",
"../src/typings.d.ts"
],
"types": [ "types": [
"cypress", "cypress",
"cypress-axe", "cypress-axe",

View File

@@ -128,6 +128,22 @@
} }
</div> </div>
<!-- In the usesActorEmailId section -->
<div class="mb-5 mt-5">
<label class="status-label font-weight-bold" for="usesActorEmailId">{{ 'ldn-service-usesActorEmailId' | translate }}</label>
<div>
<input formControlName="usesActorEmailId" hidden id="usesActorEmailId"
name="usesActorEmailId" type="checkbox">
<div (click)="toggleUsesActorEmailId()"
[class.checked]="formModel.get('usesActorEmailId').value" class="toggle-switch">
<div class="slider"></div>
</div>
<div class="text-muted">
{{ 'ldn-service-usesActorEmailId-description' | translate }}
</div>
</div>
</div>
<!-- In the Inbound Patterns Labels section --> <!-- In the Inbound Patterns Labels section -->
@if (areControlsInitialized) { @if (areControlsInitialized) {

View File

@@ -125,6 +125,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
score: ['', [Validators.required, Validators.pattern('^0*(\.[0-9]+)?$|^1(\.0+)?$')]], inboundPattern: [''], score: ['', [Validators.required, Validators.pattern('^0*(\.[0-9]+)?$|^1(\.0+)?$')]], inboundPattern: [''],
constraintPattern: [''], constraintPattern: [''],
enabled: [''], enabled: [''],
usesActorEmailId: [''],
type: LDN_SERVICE.value, type: LDN_SERVICE.value,
}); });
} }
@@ -178,7 +179,8 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
return rest; return rest;
}); });
const values = { ...this.formModel.value, enabled: true }; const values = { ...this.formModel.value, enabled: true,
usesActorEmailId: this.formModel.get('usesActorEmailId').value };
const ldnServiceData = this.ldnServicesService.create(values); const ldnServiceData = this.ldnServicesService.create(values);
@@ -237,6 +239,7 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
ldnUrl: this.ldnService.ldnUrl, ldnUrl: this.ldnService.ldnUrl,
type: this.ldnService.type, type: this.ldnService.type,
enabled: this.ldnService.enabled, enabled: this.ldnService.enabled,
usesActorEmailId: this.ldnService.usesActorEmailId,
lowerIp: this.ldnService.lowerIp, lowerIp: this.ldnService.lowerIp,
upperIp: this.ldnService.upperIp, upperIp: this.ldnService.upperIp,
}); });
@@ -384,6 +387,32 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
); );
} }
/**
* Toggles the usesActorEmailId field of the LDN service by sending a patch request
*/
toggleUsesActorEmailId() {
const newStatus = !this.formModel.get('usesActorEmailId').value;
if (!this.isNewService) {
const patchOperation: Operation = {
op: 'replace',
path: '/usesActorEmailId',
value: newStatus,
};
this.ldnServicesService.patch(this.ldnService, [patchOperation]).pipe(
getFirstCompletedRemoteData(),
).subscribe(
() => {
this.formModel.get('usesActorEmailId').setValue(newStatus);
this.cdRef.detectChanges();
},
);
} else {
this.formModel.get('usesActorEmailId').setValue(newStatus);
this.cdRef.detectChanges();
}
}
/** /**
* Closes the modal * Closes the modal
*/ */

View File

@@ -12,6 +12,7 @@ import { LdnService } from '../ldn-services-model/ldn-services.model';
export const mockLdnService: LdnService = { export const mockLdnService: LdnService = {
uuid: '1', uuid: '1',
enabled: false, enabled: false,
usesActorEmailId: false,
score: 0, score: 0,
id: 1, id: 1,
lowerIp: '192.0.2.146', lowerIp: '192.0.2.146',
@@ -49,6 +50,7 @@ export const mockLdnServiceRD$ = createSuccessfulRemoteDataObject$(mockLdnServic
export const mockLdnServices: LdnService[] = [{ export const mockLdnServices: LdnService[] = [{
uuid: '1', uuid: '1',
enabled: false, enabled: false,
usesActorEmailId: false,
score: 0, score: 0,
id: 1, id: 1,
lowerIp: '192.0.2.146', lowerIp: '192.0.2.146',
@@ -81,6 +83,7 @@ export const mockLdnServices: LdnService[] = [{
}, { }, {
uuid: '2', uuid: '2',
enabled: false, enabled: false,
usesActorEmailId: false,
score: 0, score: 0,
id: 2, id: 2,
lowerIp: '192.0.2.146', lowerIp: '192.0.2.146',

View File

@@ -52,6 +52,9 @@ export class LdnService extends CacheableObject {
@autoserialize @autoserialize
enabled: boolean; enabled: boolean;
@autoserialize
usesActorEmailId: boolean;
@autoserialize @autoserialize
ldnUrl: string; ldnUrl: string;

View File

@@ -4,5 +4,6 @@
export interface SignpostingLink { export interface SignpostingLink {
href?: string, href?: string,
rel?: string, rel?: string,
type?: string type?: string,
profile?: string
} }

View File

@@ -166,7 +166,8 @@ export class ItemPageComponent implements OnInit, OnDestroy {
this.signpostingLinks = signpostingLinks; this.signpostingLinks = signpostingLinks;
signpostingLinks.forEach((link: SignpostingLink) => { signpostingLinks.forEach((link: SignpostingLink) => {
links = links + (isNotEmpty(links) ? ', ' : '') + `<${link.href}> ; rel="${link.rel}"` + (isNotEmpty(link.type) ? ` ; type="${link.type}" ` : ' '); links = links + (isNotEmpty(links) ? ', ' : '') + `<${link.href}> ; rel="${link.rel}"` + (isNotEmpty(link.type) ? ` ; type="${link.type}" ` : ' ')
+ (isNotEmpty(link.profile) ? ` ; profile="${link.profile}" ` : '');
let tag: LinkDefinition = { let tag: LinkDefinition = {
href: link.href, href: link.href,
rel: link.rel, rel: link.rel,
@@ -176,6 +177,11 @@ export class ItemPageComponent implements OnInit, OnDestroy {
type: link.type, type: link.type,
}); });
} }
if (isNotEmpty(link.profile)) {
tag = Object.assign(tag, {
profile: link.profile,
});
}
this.linkHeadService.addTag(tag); this.linkHeadService.addTag(tag);
}); });

View File

@@ -2,4 +2,5 @@ export enum RequestStatusEnum {
ACCEPTED = 'ACCEPTED', ACCEPTED = 'ACCEPTED',
REJECTED = 'REJECTED', REJECTED = 'REJECTED',
REQUESTED = 'REQUESTED', REQUESTED = 'REQUESTED',
TENTATIVE_REJECT = 'TENTATIVE_REJECT',
} }

View File

@@ -68,6 +68,13 @@ export class RequestStatusAlertBoxComponent implements OnInit {
}; };
break; break;
case RequestStatusEnum.TENTATIVE_REJECT:
this.displayOptions = {
alertType: 'alert-warning',
text: 'request-status-alert-box.tentative_rejected',
};
break;
case RequestStatusEnum.REQUESTED: case RequestStatusEnum.REQUESTED:
this.displayOptions = { this.displayOptions = {
alertType: 'alert-warning', alertType: 'alert-warning',

File diff suppressed because it is too large Load Diff

View File

@@ -4576,6 +4576,12 @@
"search.filters.filter.supervisedBy.label": "Search Supervised By", "search.filters.filter.supervisedBy.label": "Search Supervised By",
"search.filters.filter.access_status.head": "Access type",
"search.filters.filter.access_status.placeholder": "Access type",
"search.filters.filter.access_status.label": "Search by access type",
"search.filters.entityType.JournalIssue": "Journal Issue", "search.filters.entityType.JournalIssue": "Journal Issue",
"search.filters.entityType.JournalVolume": "Journal Volume", "search.filters.entityType.JournalVolume": "Journal Volume",
@@ -6330,7 +6336,7 @@
"quality-assurance.events.description-with-topic-and-target": "Below the list of all the suggestions for the selected topic <b>{{topic}}</b>, related to <b>{{source}}</b> and ", "quality-assurance.events.description-with-topic-and-target": "Below the list of all the suggestions for the selected topic <b>{{topic}}</b>, related to <b>{{source}}</b> and ",
"quality-assurance.event.table.event.message.serviceUrl": "Service URL:", "quality-assurance.event.table.event.message.serviceUrl": "Actor:",
"quality-assurance.event.table.event.message.link": "Link:", "quality-assurance.event.table.event.message.link": "Link:",
@@ -6394,6 +6400,8 @@
"request-status-alert-box.rejected": "The requested {{ offerType }} for <a href='{{serviceUrl}}' target='_blank'> {{ serviceName }} </a> has been rejected.", "request-status-alert-box.rejected": "The requested {{ offerType }} for <a href='{{serviceUrl}}' target='_blank'> {{ serviceName }} </a> has been rejected.",
"request-status-alert-box.tentative_rejected": "The requested {{ offerType }} for <a href='{{serviceUrl}}' target='_blank'> {{ serviceName }} </a> has been tentatively rejected. Revisions are required",
"request-status-alert-box.requested": "The requested {{ offerType }} for <a href='{{serviceUrl}}' target='_blank'> {{ serviceName }} </a> is pending.", "request-status-alert-box.requested": "The requested {{ offerType }} for <a href='{{serviceUrl}}' target='_blank'> {{ serviceName }} </a> is pending.",
"ldn-service-button-mark-inbound-deletion": "Mark supported pattern for deletion", "ldn-service-button-mark-inbound-deletion": "Mark supported pattern for deletion",
@@ -6410,6 +6418,10 @@
"ldn-service-overview-close-modal": "Close modal", "ldn-service-overview-close-modal": "Close modal",
"ldn-service-usesActorEmailId": "Requires actor email in notifications",
"ldn-service-usesActorEmailId-description": "If enabled, initial notifications sent will include the submitter email rather than the repository URL. This is usually the case for endorsement or review services.",
"a-common-or_statement.label": "Item type is Journal Article or Dataset", "a-common-or_statement.label": "Item type is Journal Article or Dataset",
"always_true_filter.label": "Always true", "always_true_filter.label": "Always true",
@@ -6538,6 +6550,8 @@
"search.filters.applied.f.notifyRelation": "Notify Relation", "search.filters.applied.f.notifyRelation": "Notify Relation",
"search.filters.applied.f.access_status": "Access type",
"search.filters.filter.queue_last_start_time.head": "Last processing time ", "search.filters.filter.queue_last_start_time.head": "Last processing time ",
"search.filters.filter.queue_last_start_time.min.label": "Min range", "search.filters.filter.queue_last_start_time.min.label": "Min range",
@@ -6886,4 +6900,13 @@
"external-login-page.orcid-confirmation.email.label": "Email", "external-login-page.orcid-confirmation.email.label": "Email",
"search.filters.access_status.open.access": "Open access",
"search.filters.access_status.restricted": "Restricted access",
"search.filters.access_status.embargo": "Embargoed access",
"search.filters.access_status.metadata.only": "Metadata only",
"search.filters.access_status.unknown": "Unknown",
} }

View File

@@ -5474,6 +5474,15 @@
// "search.filters.filter.submitter.label": "Search submitter", // "search.filters.filter.submitter.label": "Search submitter",
"search.filters.filter.submitter.label": "Recherche d'un déposant", "search.filters.filter.submitter.label": "Recherche d'un déposant",
// "search.filters.filter.access_status.head": "Access type",
"search.filters.filter.access_status.head": "Type d'accès",
// "search.filters.filter.access_status.placeholder": "Access type",
"search.filters.filter.access_status.placeholder": "Accès",
// "search.filters.filter.access_status.label": "Search by access type",
"search.filters.filter.access_status.label": "Rechercher par type d'accès",
// "search.filters.entityType.JournalIssue": "Journal Issue", // "search.filters.entityType.JournalIssue": "Journal Issue",
"search.filters.entityType.JournalIssue": "Numéro de revue", "search.filters.entityType.JournalIssue": "Numéro de revue",
@@ -8182,6 +8191,9 @@
//"search.filters.applied.f.notifyRelation": "Notify Relation", //"search.filters.applied.f.notifyRelation": "Notify Relation",
"search.filters.applied.f.notifyRelation": "Relation Notify", "search.filters.applied.f.notifyRelation": "Relation Notify",
//"search.filters.applied.f.access_status": "Access type",
"search.filters.applied.f.access_status": "Type d'accès",
//"search.filters.filter.queue_last_start_time.head": "Last processing time ", //"search.filters.filter.queue_last_start_time.head": "Last processing time ",
"search.filters.filter.queue_last_start_time.head": "Dernière heure de traitement ", "search.filters.filter.queue_last_start_time.head": "Dernière heure de traitement ",
@@ -8556,5 +8568,20 @@
//"browse.search-form.placeholder": "Search the repository", //"browse.search-form.placeholder": "Search the repository",
"browse.search-form.placeholder": "Chercher dans le dépôt", "browse.search-form.placeholder": "Chercher dans le dépôt",
}
//"search.filters.access_status.open.access": "Open access",
"search.filters.access_status.open.access": "Accès libre",
//"search.filters.access_status.restricted": "Restricted access",
"search.filters.access_status.restricted": "Restreint",
//"search.filters.access_status.embargo": "Embargoed access",
"search.filters.access_status.embargo": "Restriction temporaire",
//"search.filters.access_status.metadata.only": "Metadata only",
"search.filters.access_status.metadata.only": "Métadonnées seulement",
//"search.filters.access_status.unknown": "Unknown",
"search.filters.access_status.unknown": "Inconnu",
}

View File

@@ -6817,6 +6817,15 @@
// "search.filters.filter.supervisedBy.label": "Search Supervised By", // "search.filters.filter.supervisedBy.label": "Search Supervised By",
"search.filters.filter.supervisedBy.label": "Pesquisar supervisionado por", "search.filters.filter.supervisedBy.label": "Pesquisar supervisionado por",
// "search.filters.filter.access_status.head": "Access type",
"search.filters.filter.access_status.head": "Tipo de acesso",
// "search.filters.filter.access_status.placeholder": "Access type",
"search.filters.filter.access_status.placeholder": "Acesso",
// "search.filters.filter.access_status.label": "Search by access type",
"search.filters.filter.access_status.label": "Pesquisar por tipo de acesso",
// "search.filters.entityType.JournalIssue": "Journal Issue", // "search.filters.entityType.JournalIssue": "Journal Issue",
"search.filters.entityType.JournalIssue": "Número de revista", "search.filters.entityType.JournalIssue": "Número de revista",
@@ -9930,6 +9939,9 @@
// "search.filters.applied.f.notifyRelation": "Notify Relation", // "search.filters.applied.f.notifyRelation": "Notify Relation",
"search.filters.applied.f.notifyRelation": "Notificar relação", "search.filters.applied.f.notifyRelation": "Notificar relação",
// "search.filters.applied.f.access_status": "Access type",
"search.filters.applied.f.access_status": "Tipo de acesso",
// "search.filters.filter.queue_last_start_time.head": "Last processing time", // "search.filters.filter.queue_last_start_time.head": "Last processing time",
"search.filters.filter.queue_last_start_time.head": "Última hora de processamento", "search.filters.filter.queue_last_start_time.head": "Última hora de processamento",
@@ -10361,4 +10373,19 @@
// "item.preview.dc.identifier.eisbn": "EISBN", // "item.preview.dc.identifier.eisbn": "EISBN",
"item.preview.dc.identifier.eisbn": "EISBN", "item.preview.dc.identifier.eisbn": "EISBN",
// "search.filters.access_status.open.access": "Open access",
"search.filters.access_status.open.access": "Acesso aberto",
// "search.filters.access_status.restricted": "Restricted access",
"search.filters.access_status.restricted": "Acesso restrito",
// "search.filters.access_status.embargo": "Embargoed access",
"search.filters.access_status.embargo": "Acesso embargado",
// "search.filters.access_status.metadata.only": "Metadata only",
"search.filters.access_status.metadata.only": "Apenas metadados",
// "search.filters.access_status.unknown": "Unknown",
"search.filters.access_status.unknown": "Desconhecido",
} }