From be6dbdec66e6caf000c966a2e1e30f3acf199458 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Mon, 2 Oct 2023 13:31:25 +0200 Subject: [PATCH 001/822] 107155: Allow caching null objects --- src/app/core/cache/object-cache.reducer.ts | 31 +++++++++++-------- src/app/core/cache/object-cache.service.ts | 16 +++++++--- .../dspace-rest-response-parsing.service.ts | 7 +++-- src/app/core/index/index.effects.ts | 4 +-- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/app/core/cache/object-cache.reducer.ts b/src/app/core/cache/object-cache.reducer.ts index dc3f50db68f..7f389344fb4 100644 --- a/src/app/core/cache/object-cache.reducer.ts +++ b/src/app/core/cache/object-cache.reducer.ts @@ -166,20 +166,25 @@ export function objectCacheReducer(state = initialState, action: ObjectCacheActi * the new state, with the object added, or overwritten. */ function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheAction): ObjectCacheState { - const existing = state[action.payload.objectToCache._links.self.href] || {} as any; + const cacheLink = hasValue(action.payload.objectToCache) ? action.payload.objectToCache._links.self.href : action.payload.alternativeLink; + const existing = state[cacheLink] || {} as any; const newAltLinks = hasValue(action.payload.alternativeLink) ? [action.payload.alternativeLink] : []; - return Object.assign({}, state, { - [action.payload.objectToCache._links.self.href]: { - data: action.payload.objectToCache, - timeCompleted: action.payload.timeCompleted, - msToLive: action.payload.msToLive, - requestUUIDs: [action.payload.requestUUID, ...(existing.requestUUIDs || [])], - dependentRequestUUIDs: existing.dependentRequestUUIDs || [], - isDirty: isNotEmpty(existing.patches), - patches: existing.patches || [], - alternativeLinks: [...(existing.alternativeLinks || []), ...newAltLinks] - } as ObjectCacheEntry - }); + if (hasValue(cacheLink)) { + return Object.assign({}, state, { + [cacheLink]: { + data: action.payload.objectToCache, + timeCompleted: action.payload.timeCompleted, + msToLive: action.payload.msToLive, + requestUUIDs: [action.payload.requestUUID, ...(existing.requestUUIDs || [])], + dependentRequestUUIDs: existing.dependentRequestUUIDs || [], + isDirty: isNotEmpty(existing.patches), + patches: existing.patches || [], + alternativeLinks: [...(existing.alternativeLinks || []), ...newAltLinks] + } as ObjectCacheEntry + }); + } else { + return state; + } } /** diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts index 9ca02162108..0330a03f02c 100644 --- a/src/app/core/cache/object-cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -63,7 +63,9 @@ export class ObjectCacheService { * An optional alternative link to this object */ add(object: CacheableObject, msToLive: number, requestUUID: string, alternativeLink?: string): void { - object = this.linkService.removeResolvedLinks(object); // Ensure the object we're storing has no resolved links + if (hasValue(object)) { + object = this.linkService.removeResolvedLinks(object); // Ensure the object we're storing has no resolved links + } this.store.dispatch(new AddToObjectCacheAction(object, new Date().getTime(), msToLive, requestUUID, alternativeLink)); } @@ -139,11 +141,15 @@ export class ObjectCacheService { } ), map((entry: ObjectCacheEntry) => { - const type: GenericConstructor = getClassForType((entry.data as any).type); - if (typeof type !== 'function') { - throw new Error(`${type} is not a valid constructor for ${JSON.stringify(entry.data)}`); + if (hasValue(entry.data)) { + const type: GenericConstructor = getClassForType((entry.data as any).type); + if (typeof type !== 'function') { + throw new Error(`${type} is not a valid constructor for ${JSON.stringify(entry.data)}`); + } + return Object.assign(new type(), entry.data) as T; + } else { + return null; } - return Object.assign(new type(), entry.data) as T; }) ); } diff --git a/src/app/core/data/dspace-rest-response-parsing.service.ts b/src/app/core/data/dspace-rest-response-parsing.service.ts index 500afc4aff6..2f79edd129a 100644 --- a/src/app/core/data/dspace-rest-response-parsing.service.ts +++ b/src/app/core/data/dspace-rest-response-parsing.service.ts @@ -109,6 +109,9 @@ export class DspaceRestResponseParsingService implements ResponseParsingService if (hasValue(match)) { embedAltUrl = new URLCombiner(embedAltUrl, `?size=${match.size}`).toString(); } + if (data._embedded[property] == null) { + this.addToObjectCache(null, request, data, embedAltUrl); + } this.process(data._embedded[property], request, embedAltUrl); }); } @@ -226,7 +229,7 @@ export class DspaceRestResponseParsingService implements ResponseParsingService * @param alternativeURL an alternative url that can be used to retrieve the object */ addToObjectCache(co: CacheableObject, request: RestRequest, data: any, alternativeURL?: string): void { - if (!isCacheableObject(co)) { + if (hasValue(co) && !isCacheableObject(co)) { const type = hasValue(data) && hasValue(data.type) ? data.type : 'object'; let dataJSON: string; if (hasValue(data._embedded)) { @@ -240,7 +243,7 @@ export class DspaceRestResponseParsingService implements ResponseParsingService return; } - if (alternativeURL === co._links.self.href) { + if (hasValue(co) && alternativeURL === co._links.self.href) { alternativeURL = undefined; } diff --git a/src/app/core/index/index.effects.ts b/src/app/core/index/index.effects.ts index 18d639023f1..9ec013813d0 100644 --- a/src/app/core/index/index.effects.ts +++ b/src/app/core/index/index.effects.ts @@ -27,7 +27,7 @@ export class UUIDIndexEffects { addObject$ = createEffect(() => this.actions$ .pipe( ofType(ObjectCacheActionTypes.ADD), - filter((action: AddToObjectCacheAction) => hasValue(action.payload.objectToCache.uuid)), + filter((action: AddToObjectCacheAction) => hasValue(action.payload.objectToCache) && hasValue(action.payload.objectToCache.uuid)), map((action: AddToObjectCacheAction) => { return new AddToIndexAction( IndexName.OBJECT, @@ -46,7 +46,7 @@ export class UUIDIndexEffects { ofType(ObjectCacheActionTypes.ADD), map((action: AddToObjectCacheAction) => { const alternativeLink = action.payload.alternativeLink; - const selfLink = action.payload.objectToCache._links.self.href; + const selfLink = hasValue(action.payload.objectToCache) ? action.payload.objectToCache._links.self.href : alternativeLink; if (hasValue(alternativeLink) && alternativeLink !== selfLink) { return new AddToIndexAction( IndexName.ALTERNATIVE_OBJECT_LINK, From 984c9bfc2a2271e65190e02902ea0589dcfe6c4f Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Thu, 26 Oct 2023 16:33:14 +0200 Subject: [PATCH 002/822] 107155: Allow caching of embedded objects without selflink --- src/app/core/cache/object-cache.reducer.ts | 2 +- src/app/core/data/dspace-rest-response-parsing.service.ts | 4 ++++ src/app/core/index/index.effects.ts | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app/core/cache/object-cache.reducer.ts b/src/app/core/cache/object-cache.reducer.ts index 7f389344fb4..21dc729f1b9 100644 --- a/src/app/core/cache/object-cache.reducer.ts +++ b/src/app/core/cache/object-cache.reducer.ts @@ -166,7 +166,7 @@ export function objectCacheReducer(state = initialState, action: ObjectCacheActi * the new state, with the object added, or overwritten. */ function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheAction): ObjectCacheState { - const cacheLink = hasValue(action.payload.objectToCache) ? action.payload.objectToCache._links.self.href : action.payload.alternativeLink; + const cacheLink = hasValue(action.payload.objectToCache?._links?.self) ? action.payload.objectToCache._links.self.href : action.payload.alternativeLink; const existing = state[cacheLink] || {} as any; const newAltLinks = hasValue(action.payload.alternativeLink) ? [action.payload.alternativeLink] : []; if (hasValue(cacheLink)) { diff --git a/src/app/core/data/dspace-rest-response-parsing.service.ts b/src/app/core/data/dspace-rest-response-parsing.service.ts index 2f79edd129a..c0e1c70cae9 100644 --- a/src/app/core/data/dspace-rest-response-parsing.service.ts +++ b/src/app/core/data/dspace-rest-response-parsing.service.ts @@ -110,7 +110,11 @@ export class DspaceRestResponseParsingService implements ResponseParsingService embedAltUrl = new URLCombiner(embedAltUrl, `?size=${match.size}`).toString(); } if (data._embedded[property] == null) { + // Embedded object is null, meaning it exists (not undefined), but had an empty response (204) -> cache it as null this.addToObjectCache(null, request, data, embedAltUrl); + } else if (!isCacheableObject(data._embedded[property])) { + // Embedded object exists, but doesn't contain a self link -> cache it using the alternative link instead + this.objectCache.add(data._embedded[property], hasValue(request.responseMsToLive) ? request.responseMsToLive : environment.cache.msToLive.default, request.uuid, embedAltUrl); } this.process(data._embedded[property], request, embedAltUrl); }); diff --git a/src/app/core/index/index.effects.ts b/src/app/core/index/index.effects.ts index 9ec013813d0..65aa45e5710 100644 --- a/src/app/core/index/index.effects.ts +++ b/src/app/core/index/index.effects.ts @@ -46,7 +46,7 @@ export class UUIDIndexEffects { ofType(ObjectCacheActionTypes.ADD), map((action: AddToObjectCacheAction) => { const alternativeLink = action.payload.alternativeLink; - const selfLink = hasValue(action.payload.objectToCache) ? action.payload.objectToCache._links.self.href : alternativeLink; + const selfLink = hasValue(action.payload.objectToCache?._links?.self) ? action.payload.objectToCache._links.self.href : alternativeLink; if (hasValue(alternativeLink) && alternativeLink !== selfLink) { return new AddToIndexAction( IndexName.ALTERNATIVE_OBJECT_LINK, From 36c95db7bf19b83453691ef4e0dbc52608c08ee5 Mon Sep 17 00:00:00 2001 From: Victor Hugo Duran Santiago Date: Thu, 9 May 2024 20:50:51 -0600 Subject: [PATCH 003/822] Set color black on filter section for mobile --- .../search-filters/search-filter/search-filter.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.html b/src/app/shared/search/search-filters/search-filter/search-filter.component.html index 97809ef8547..6c3873d296d 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.html +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.html @@ -6,7 +6,7 @@ [attr.aria-label]="(((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate) + ' ' + (('search.filters.filter.' + filter.name + '.head') | translate | lowercase)" [attr.data-test]="'filter-toggle' | dsBrowserOnly" > - + {{'search.filters.filter.' + filter.name + '.head'| translate}} Date: Tue, 21 May 2024 12:02:15 +0200 Subject: [PATCH 004/822] 115051: Created ThemedAdminSearchPageComponent --- src/app/admin/admin-routing.module.ts | 4 +-- .../admin-search-page/admin-search.module.ts | 2 ++ .../themed-admin-search-page.component.ts | 26 +++++++++++++++++++ .../admin-search-page.component.html | 0 .../admin-search-page.component.scss | 0 .../admin-search-page.component.ts | 12 +++++++++ src/themes/custom/lazy-theme.module.ts | 4 +-- 7 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 src/app/admin/admin-search-page/themed-admin-search-page.component.ts create mode 100644 src/themes/custom/app/admin/admin-search-page/admin-search-page.component.html create mode 100644 src/themes/custom/app/admin/admin-search-page/admin-search-page.component.scss create mode 100644 src/themes/custom/app/admin/admin-search-page/admin-search-page.component.ts diff --git a/src/app/admin/admin-routing.module.ts b/src/app/admin/admin-routing.module.ts index 1ea20bc9a0f..3e3a8924ac8 100644 --- a/src/app/admin/admin-routing.module.ts +++ b/src/app/admin/admin-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { MetadataImportPageComponent } from './admin-import-metadata-page/metadata-import-page.component'; -import { AdminSearchPageComponent } from './admin-search-page/admin-search-page.component'; +import { ThemedAdminSearchPageComponent } from './admin-search-page/themed-admin-search-page.component'; import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; import { AdminWorkflowPageComponent } from './admin-workflow-page/admin-workflow-page.component'; import { I18nBreadcrumbsService } from '../core/breadcrumbs/i18n-breadcrumbs.service'; @@ -20,7 +20,7 @@ import { BatchImportPageComponent } from './admin-import-batch-page/batch-import { path: 'search', resolve: { breadcrumb: I18nBreadcrumbResolver }, - component: AdminSearchPageComponent, + component: ThemedAdminSearchPageComponent, data: { title: 'admin.search.title', breadcrumbKey: 'admin.search' } }, { diff --git a/src/app/admin/admin-search-page/admin-search.module.ts b/src/app/admin/admin-search-page/admin-search.module.ts index 353d6dd4985..b45eca15c4b 100644 --- a/src/app/admin/admin-search-page/admin-search.module.ts +++ b/src/app/admin/admin-search-page/admin-search.module.ts @@ -1,5 +1,6 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../shared/shared.module'; +import { ThemedAdminSearchPageComponent } from './themed-admin-search-page.component'; import { AdminSearchPageComponent } from './admin-search-page.component'; import { ItemAdminSearchResultListElementComponent } from './admin-search-results/admin-search-result-list-element/item-search-result/item-admin-search-result-list-element.component'; import { CommunityAdminSearchResultListElementComponent } from './admin-search-results/admin-search-result-list-element/community-search-result/community-admin-search-result-list-element.component'; @@ -31,6 +32,7 @@ const ENTRY_COMPONENTS = [ ResearchEntitiesModule.withEntryComponents() ], declarations: [ + ThemedAdminSearchPageComponent, AdminSearchPageComponent, ...ENTRY_COMPONENTS ] diff --git a/src/app/admin/admin-search-page/themed-admin-search-page.component.ts b/src/app/admin/admin-search-page/themed-admin-search-page.component.ts new file mode 100644 index 00000000000..741a3b04f9c --- /dev/null +++ b/src/app/admin/admin-search-page/themed-admin-search-page.component.ts @@ -0,0 +1,26 @@ +import { Component } from '@angular/core'; +import { ThemedComponent } from '../../shared/theme-support/themed.component'; +import { AdminSearchPageComponent } from './admin-search-page.component'; + +/** + * Themed wrapper for {@link AdminSearchPageComponent} + */ +@Component({ + selector: 'ds-themed-admin-search-page', + templateUrl: '../../shared/theme-support/themed.component.html', +}) +export class ThemedAdminSearchPageComponent extends ThemedComponent { + + protected getComponentName(): string { + return 'AdminSearchPageComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../themes/${themeName}/app/admin/admin-search-page/admin-search-page.component`); + } + + protected importUnthemedComponent(): Promise { + return import('./admin-search-page.component'); + } + +} diff --git a/src/themes/custom/app/admin/admin-search-page/admin-search-page.component.html b/src/themes/custom/app/admin/admin-search-page/admin-search-page.component.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/custom/app/admin/admin-search-page/admin-search-page.component.scss b/src/themes/custom/app/admin/admin-search-page/admin-search-page.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/custom/app/admin/admin-search-page/admin-search-page.component.ts b/src/themes/custom/app/admin/admin-search-page/admin-search-page.component.ts new file mode 100644 index 00000000000..358f11f0d19 --- /dev/null +++ b/src/themes/custom/app/admin/admin-search-page/admin-search-page.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { AdminSearchPageComponent as BaseComponent } from '../../../../../app/admin/admin-search-page/admin-search-page.component'; + +@Component({ + selector: 'ds-admin-search-page', + // styleUrls: ['./admin-search-page.component.scss'], + styleUrls: ['../../../../../app/admin/admin-search-page/admin-search-page.component.scss'], + // templateUrl: './admin-search-page.component.html', + templateUrl: '../../../../../app/admin/admin-search-page/admin-search-page.component.html', +}) +export class AdminSearchPageComponent extends BaseComponent { +} diff --git a/src/themes/custom/lazy-theme.module.ts b/src/themes/custom/lazy-theme.module.ts index d2ac0ae7877..4f35854e5ed 100644 --- a/src/themes/custom/lazy-theme.module.ts +++ b/src/themes/custom/lazy-theme.module.ts @@ -114,6 +114,7 @@ import { ObjectListComponent } from './app/shared/object-list/object-list.compon import { BrowseByMetadataPageComponent } from './app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component'; import { BrowseByDatePageComponent } from './app/browse-by/browse-by-date-page/browse-by-date-page.component'; import { BrowseByTitlePageComponent } from './app/browse-by/browse-by-title-page/browse-by-title-page.component'; +import { AdminSearchPageComponent } from './app/admin/admin-search-page/admin-search-page.component'; const DECLARATIONS = [ FileSectionComponent, @@ -168,8 +169,7 @@ const DECLARATIONS = [ BrowseByMetadataPageComponent, BrowseByDatePageComponent, BrowseByTitlePageComponent, - - + AdminSearchPageComponent, ]; @NgModule({ From 970b19bf0104a9f361717d148bfc66a60e70e239 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Wed, 22 May 2024 14:02:41 +0200 Subject: [PATCH 005/822] 115051: Created ThemedAdminWorkflowPageComponent --- src/app/admin/admin-routing.module.ts | 3 ++- .../admin-workflow.module.ts | 2 ++ .../themed-admin-workflow-page.component.ts | 26 +++++++++++++++++++ .../admin-workflow-page.component.html | 0 .../admin-workflow-page.component.scss | 0 .../admin-workflow-page.component.ts | 12 +++++++++ src/themes/custom/lazy-theme.module.ts | 2 ++ 7 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/admin/admin-workflow-page/themed-admin-workflow-page.component.ts create mode 100644 src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.html create mode 100644 src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.scss create mode 100644 src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.ts diff --git a/src/app/admin/admin-routing.module.ts b/src/app/admin/admin-routing.module.ts index 3e3a8924ac8..58ccd54c767 100644 --- a/src/app/admin/admin-routing.module.ts +++ b/src/app/admin/admin-routing.module.ts @@ -8,6 +8,7 @@ import { I18nBreadcrumbsService } from '../core/breadcrumbs/i18n-breadcrumbs.ser import { AdminCurationTasksComponent } from './admin-curation-tasks/admin-curation-tasks.component'; import { REGISTRIES_MODULE_PATH } from './admin-routing-paths'; import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component'; +import { ThemedAdminWorkflowPageComponent } from './admin-workflow-page/themed-admin-workflow-page.component'; @NgModule({ imports: [ @@ -26,7 +27,7 @@ import { BatchImportPageComponent } from './admin-import-batch-page/batch-import { path: 'workflow', resolve: { breadcrumb: I18nBreadcrumbResolver }, - component: AdminWorkflowPageComponent, + component: ThemedAdminWorkflowPageComponent, data: { title: 'admin.workflow.title', breadcrumbKey: 'admin.workflow' } }, { diff --git a/src/app/admin/admin-workflow-page/admin-workflow.module.ts b/src/app/admin/admin-workflow-page/admin-workflow.module.ts index 85e8f00a462..1622a3b290b 100644 --- a/src/app/admin/admin-workflow-page/admin-workflow.module.ts +++ b/src/app/admin/admin-workflow-page/admin-workflow.module.ts @@ -6,6 +6,7 @@ import { WorkflowItemAdminWorkflowActionsComponent } from './admin-workflow-sear import { WorkflowItemSearchResultAdminWorkflowListElementComponent } from './admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component'; import { AdminWorkflowPageComponent } from './admin-workflow-page.component'; import { SearchModule } from '../../shared/search/search.module'; +import { ThemedAdminWorkflowPageComponent } from './themed-admin-workflow-page.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -19,6 +20,7 @@ const ENTRY_COMPONENTS = [ SharedModule.withEntryComponents() ], declarations: [ + ThemedAdminWorkflowPageComponent, AdminWorkflowPageComponent, WorkflowItemAdminWorkflowActionsComponent, ...ENTRY_COMPONENTS diff --git a/src/app/admin/admin-workflow-page/themed-admin-workflow-page.component.ts b/src/app/admin/admin-workflow-page/themed-admin-workflow-page.component.ts new file mode 100644 index 00000000000..fe84c44d0ea --- /dev/null +++ b/src/app/admin/admin-workflow-page/themed-admin-workflow-page.component.ts @@ -0,0 +1,26 @@ +import { Component } from '@angular/core'; +import { ThemedComponent } from '../../shared/theme-support/themed.component'; +import { AdminWorkflowPageComponent } from './admin-workflow-page.component'; + +/** + * Themed wrapper for {@link AdminWorkflowPageComponent} + */ +@Component({ + selector: 'ds-themed-admin-workflow-page', + templateUrl: '../../shared/theme-support/themed.component.html', +}) +export class ThemedAdminWorkflowPageComponent extends ThemedComponent { + + protected getComponentName(): string { + return 'AdminWorkflowPageComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../themes/${themeName}/app/admin/admin-workflow-page/admin-workflow-page.component`); + } + + protected importUnthemedComponent(): Promise { + return import('./admin-workflow-page.component'); + } + +} diff --git a/src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.html b/src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.scss b/src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.ts b/src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.ts new file mode 100644 index 00000000000..27c7e57fed8 --- /dev/null +++ b/src/themes/custom/app/admin/admin-workflow-page/admin-workflow-page.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { AdminWorkflowPageComponent as BaseComponent } from '../../../../../app/admin/admin-workflow-page/admin-workflow-page.component'; + +@Component({ + selector: 'ds-admin-workflow-page', + // styleUrls: ['./admin-workflow-page.component.scss'], + styleUrls: ['../../../../../app/admin/admin-workflow-page/admin-workflow-page.component.scss'], + // templateUrl: './admin-workflow-page.component.html', + templateUrl: '../../../../../app/admin/admin-workflow-page/admin-workflow-page.component.html', +}) +export class AdminWorkflowPageComponent extends BaseComponent { +} diff --git a/src/themes/custom/lazy-theme.module.ts b/src/themes/custom/lazy-theme.module.ts index 4f35854e5ed..1939483c4ff 100644 --- a/src/themes/custom/lazy-theme.module.ts +++ b/src/themes/custom/lazy-theme.module.ts @@ -115,6 +115,7 @@ import { BrowseByMetadataPageComponent } from './app/browse-by/browse-by-metadat import { BrowseByDatePageComponent } from './app/browse-by/browse-by-date-page/browse-by-date-page.component'; import { BrowseByTitlePageComponent } from './app/browse-by/browse-by-title-page/browse-by-title-page.component'; import { AdminSearchPageComponent } from './app/admin/admin-search-page/admin-search-page.component'; +import { AdminWorkflowPageComponent } from './app/admin/admin-workflow-page/admin-workflow-page.component'; const DECLARATIONS = [ FileSectionComponent, @@ -170,6 +171,7 @@ const DECLARATIONS = [ BrowseByDatePageComponent, BrowseByTitlePageComponent, AdminSearchPageComponent, + AdminWorkflowPageComponent, ]; @NgModule({ From 087c203f725a0748042fd2b2dc30993641e15e55 Mon Sep 17 00:00:00 2001 From: lotte Date: Tue, 25 Jun 2024 18:28:56 +0200 Subject: [PATCH 006/822] 116132: Fixed cookie issue --- src/app/shared/cookies/klaro-configuration.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/shared/cookies/klaro-configuration.ts b/src/app/shared/cookies/klaro-configuration.ts index a41b641dec1..a09db759a61 100644 --- a/src/app/shared/cookies/klaro-configuration.ts +++ b/src/app/shared/cookies/klaro-configuration.ts @@ -183,7 +183,6 @@ export const klaroConfiguration: any = { purposes: ['registration-password-recovery'], required: false, cookies: [ - [/^klaro-.+$/], CAPTCHA_COOKIE ], onAccept: `window.refreshCaptchaScript?.call()`, From a23cdfbc2b1dd6dd4a494432c992fdac3a38fc70 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Wed, 26 Jun 2024 08:32:43 +0200 Subject: [PATCH 007/822] 115284: Add repeatable based on relationship max cardinality --- .../edit-relationship-list.component.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts index 6cca52ba962..835ee4ad7a5 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts @@ -232,6 +232,22 @@ export class EditRelationshipListComponent implements OnInit, OnDestroy { return update && update.field ? update.field.uuid : undefined; } + /** + * Check whether the current entity can have multiple relationships of this type + * This is based on the max cardinality of the relationship + * @private + */ + private isRepeatable(): boolean { + const isLeft = this.currentItemIsLeftItem$.getValue(); + if (isLeft) { + const leftMaxCardinality = this.relationshipType.leftMaxCardinality; + return hasNoValue(leftMaxCardinality) || leftMaxCardinality > 1; + } else { + const rightMaxCardinality = this.relationshipType.rightMaxCardinality; + return hasNoValue(rightMaxCardinality) || rightMaxCardinality > 1; + } + } + /** * Open the dynamic lookup modal to search for items to add as relationships */ @@ -249,6 +265,7 @@ export class EditRelationshipListComponent implements OnInit, OnDestroy { modalComp.toAdd = []; modalComp.toRemove = []; modalComp.isPending = false; + modalComp.repeatable = this.isRepeatable(); modalComp.hiddenQuery = '-search.resourceid:' + this.item.uuid; this.item.owningCollection.pipe( From 1d8d3b3c273fb7f39e2c26ad0bd620b865ce84c8 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 9 Jul 2024 14:34:17 -0500 Subject: [PATCH 008/822] Update version tag for development of next release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 664bef37ea1..ae3cf5ac513 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dspace-angular", - "version": "7.6.2", + "version": "7.6.3-next", "scripts": { "ng": "ng", "config:watch": "nodemon", From bb770ba65b7941f936d8e657771a88cb11994aeb Mon Sep 17 00:00:00 2001 From: Vincenzo Mecca Date: Wed, 10 Jul 2024 11:34:18 +0200 Subject: [PATCH 009/822] [CST-14903] Orcid Synchronization improvements feat: - Introduces reactive states derived from item inside orcid-sync page - Removes unnecessary navigation ref: - Introduces catchError operator and handles failures with error messages --- .../orcid-auth/orcid-auth.component.ts | 15 +- .../orcid-page/orcid-page.component.ts | 18 +- .../orcid-sync-settings.component.spec.ts | 10 +- .../orcid-sync-settings.component.ts | 165 ++++++++++++------ 4 files changed, 144 insertions(+), 64 deletions(-) diff --git a/src/app/item-page/orcid-page/orcid-auth/orcid-auth.component.ts b/src/app/item-page/orcid-page/orcid-auth/orcid-auth.component.ts index ea970e7d315..73b4a7b4e1b 100644 --- a/src/app/item-page/orcid-page/orcid-auth/orcid-auth.component.ts +++ b/src/app/item-page/orcid-page/orcid-auth/orcid-auth.component.ts @@ -1,8 +1,8 @@ import { Component, EventEmitter, Inject, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; -import { BehaviorSubject, Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { BehaviorSubject, Observable, of } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; import { NativeWindowRef, NativeWindowService } from '../../../core/services/window.service'; import { Item } from '../../../core/shared/item.model'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -10,6 +10,8 @@ import { RemoteData } from '../../../core/data/remote-data'; import { ResearcherProfile } from '../../../core/profile/model/researcher-profile.model'; import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { OrcidAuthService } from '../../../core/orcid/orcid-auth.service'; +import { createFailedRemoteDataObject } from '../../../shared/remote-data.utils'; +import { HttpErrorResponse } from '@angular/common/http'; @Component({ selector: 'ds-orcid-auth', @@ -170,14 +172,15 @@ export class OrcidAuthComponent implements OnInit, OnChanges { unlinkOrcid(): void { this.unlinkProcessing.next(true); this.orcidAuthService.unlinkOrcidByItem(this.item).pipe( - getFirstCompletedRemoteData() + getFirstCompletedRemoteData(), + catchError((err: HttpErrorResponse) => of(createFailedRemoteDataObject(err.message, err.status))) ).subscribe((remoteData: RemoteData) => { this.unlinkProcessing.next(false); - if (remoteData.isSuccess) { + if (remoteData.hasFailed) { + this.notificationsService.error(this.translateService.get('person.page.orcid.unlink.error')); + } else { this.notificationsService.success(this.translateService.get('person.page.orcid.unlink.success')); this.unlink.emit(); - } else { - this.notificationsService.error(this.translateService.get('person.page.orcid.unlink.error')); } }); } diff --git a/src/app/item-page/orcid-page/orcid-page.component.ts b/src/app/item-page/orcid-page/orcid-page.component.ts index f3dbb569d9d..1d62c9691c1 100644 --- a/src/app/item-page/orcid-page/orcid-page.component.ts +++ b/src/app/item-page/orcid-page/orcid-page.component.ts @@ -3,7 +3,7 @@ import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { isPlatformBrowser } from '@angular/common'; import { BehaviorSubject, combineLatest } from 'rxjs'; -import { map, take } from 'rxjs/operators'; +import { filter, map, take } from 'rxjs/operators'; import { OrcidAuthService } from '../../core/orcid/orcid-auth.service'; import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; @@ -147,7 +147,19 @@ export class OrcidPageComponent implements OnInit { */ private clearRouteParams(): void { // update route removing the code from query params - const redirectUrl = this.router.url.split('?')[0]; - this.router.navigate([redirectUrl]); + this.route.queryParamMap + .pipe( + filter((paramMap: ParamMap) => isNotEmpty(paramMap.keys)), + map(_ => Object.assign({})), + take(1), + ).subscribe(queryParams => + this.router.navigate( + [], + { + relativeTo: this.route, + queryParams + } + ) + ); } } diff --git a/src/app/item-page/orcid-page/orcid-sync-settings/orcid-sync-settings.component.spec.ts b/src/app/item-page/orcid-page/orcid-sync-settings/orcid-sync-settings.component.spec.ts index f2fa9d2440b..38a6df909eb 100644 --- a/src/app/item-page/orcid-page/orcid-sync-settings/orcid-sync-settings.component.spec.ts +++ b/src/app/item-page/orcid-page/orcid-sync-settings/orcid-sync-settings.component.spec.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { UntypedFormControl, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; import { By } from '@angular/platform-browser'; @@ -24,8 +24,8 @@ describe('OrcidSyncSettingsComponent test suite', () => { let comp: OrcidSyncSettingsComponent; let fixture: ComponentFixture; let scheduler: TestScheduler; - let researcherProfileService: jasmine.SpyObj; let notificationsService; + let researcherProfileService: jasmine.SpyObj; let formGroup: UntypedFormGroup; const mockResearcherProfile: ResearcherProfile = Object.assign(new ResearcherProfile(), { @@ -161,6 +161,7 @@ describe('OrcidSyncSettingsComponent test suite', () => { scheduler = getTestScheduler(); fixture = TestBed.createComponent(OrcidSyncSettingsComponent); comp = fixture.componentInstance; + researcherProfileService.findByRelatedItem.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile)); comp.item = mockItemLinkedToOrcid; fixture.detectChanges(); })); @@ -197,7 +198,6 @@ describe('OrcidSyncSettingsComponent test suite', () => { }); it('should call updateByOrcidOperations properly', () => { - researcherProfileService.findByRelatedItem.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile)); researcherProfileService.patch.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile)); const expectedOps: Operation[] = [ { @@ -226,7 +226,6 @@ describe('OrcidSyncSettingsComponent test suite', () => { }); it('should show notification on success', () => { - researcherProfileService.findByRelatedItem.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile)); researcherProfileService.patch.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile)); scheduler.schedule(() => comp.onSubmit(formGroup)); @@ -238,6 +237,8 @@ describe('OrcidSyncSettingsComponent test suite', () => { it('should show notification on error', () => { researcherProfileService.findByRelatedItem.and.returnValue(createFailedRemoteDataObject$()); + comp.item = mockItemLinkedToOrcid; + fixture.detectChanges(); scheduler.schedule(() => comp.onSubmit(formGroup)); scheduler.flush(); @@ -247,7 +248,6 @@ describe('OrcidSyncSettingsComponent test suite', () => { }); it('should show notification on error', () => { - researcherProfileService.findByRelatedItem.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile)); researcherProfileService.patch.and.returnValue(createFailedRemoteDataObject$()); scheduler.schedule(() => comp.onSubmit(formGroup)); diff --git a/src/app/item-page/orcid-page/orcid-sync-settings/orcid-sync-settings.component.ts b/src/app/item-page/orcid-page/orcid-sync-settings/orcid-sync-settings.component.ts index 0bcbc295ac0..422041d340f 100644 --- a/src/app/item-page/orcid-page/orcid-sync-settings/orcid-sync-settings.component.ts +++ b/src/app/item-page/orcid-page/orcid-sync-settings/orcid-sync-settings.component.ts @@ -1,80 +1,97 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; import { Operation } from 'fast-json-patch'; -import { of } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { BehaviorSubject, Observable, of } from 'rxjs'; +import { catchError, filter, map, switchMap, take, takeUntil } from 'rxjs/operators'; import { RemoteData } from '../../../core/data/remote-data'; import { ResearcherProfileDataService } from '../../../core/profile/researcher-profile-data.service'; import { Item } from '../../../core/shared/item.model'; -import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../../../core/shared/operators'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { ResearcherProfile } from '../../../core/profile/model/researcher-profile.model'; +import { hasValue } from '../../../shared/empty.util'; +import { HttpErrorResponse } from '@angular/common/http'; +import { createFailedRemoteDataObject } from '../../../shared/remote-data.utils'; @Component({ selector: 'ds-orcid-sync-setting', templateUrl: './orcid-sync-settings.component.html', styleUrls: ['./orcid-sync-settings.component.scss'] }) -export class OrcidSyncSettingsComponent implements OnInit { - - /** - * The item for which showing the orcid settings - */ - @Input() item: Item; +export class OrcidSyncSettingsComponent implements OnInit, OnDestroy { /** * The prefix used for i18n keys */ messagePrefix = 'person.page.orcid'; - /** * The current synchronization mode */ currentSyncMode: string; - /** * The current synchronization mode for publications */ currentSyncPublications: string; - /** * The current synchronization mode for funding */ currentSyncFunding: string; - /** * The synchronization options */ syncModes: { value: string, label: string }[]; - /** * The synchronization options for publications */ syncPublicationOptions: { value: string, label: string }[]; - /** * The synchronization options for funding */ syncFundingOptions: { value: string, label: string }[]; - /** * The profile synchronization options */ syncProfileOptions: { value: string, label: string, checked: boolean }[]; - /** * An event emitted when settings are updated */ @Output() settingsUpdated: EventEmitter = new EventEmitter(); + /** + * Emitter that triggers onDestroy lifecycle + * @private + */ + readonly #destroy$ = new EventEmitter(); + /** + * {@link BehaviorSubject} that reflects {@link item} input changes + * @private + */ + readonly #item$ = new BehaviorSubject(null); + /** + * {@link Observable} that contains {@link ResearcherProfile} linked to the {@link #item$} + * @private + */ + #researcherProfile$: Observable; constructor(private researcherProfileService: ResearcherProfileDataService, private notificationsService: NotificationsService, private translateService: TranslateService) { } + /** + * The item for which showing the orcid settings + */ + @Input() + set item(item: Item) { + this.#item$.next(item); + } + + ngOnDestroy(): void { + this.#destroy$.next(); + } + /** * Init orcid settings form */ @@ -106,20 +123,21 @@ export class OrcidSyncSettingsComponent implements OnInit { }; }); - const syncProfilePreferences = this.item.allMetadataValues('dspace.orcid.sync-profile'); + this.updateSyncProfileOptions(this.#item$.asObservable()); + this.updateSyncPreferences(this.#item$.asObservable()); - this.syncProfileOptions = ['BIOGRAPHICAL', 'IDENTIFIERS'] - .map((value) => { - return { - label: this.messagePrefix + '.sync-profile.' + value.toLowerCase(), - value: value, - checked: syncProfilePreferences.includes(value) - }; - }); - - this.currentSyncMode = this.getCurrentPreference('dspace.orcid.sync-mode', ['BATCH', 'MANUAL'], 'MANUAL'); - this.currentSyncPublications = this.getCurrentPreference('dspace.orcid.sync-publications', ['DISABLED', 'ALL'], 'DISABLED'); - this.currentSyncFunding = this.getCurrentPreference('dspace.orcid.sync-fundings', ['DISABLED', 'ALL'], 'DISABLED'); + this.#researcherProfile$ = + this.#item$.pipe( + switchMap(item => + this.researcherProfileService.findByRelatedItem(item) + .pipe( + getFirstCompletedRemoteData(), + catchError((err: HttpErrorResponse) => of(createFailedRemoteDataObject(err.message, err.status))), + getRemoteDataPayload(), + ) + ), + takeUntil(this.#destroy$) + ); } /** @@ -144,37 +162,84 @@ export class OrcidSyncSettingsComponent implements OnInit { return; } - this.researcherProfileService.findByRelatedItem(this.item).pipe( - getFirstCompletedRemoteData(), - switchMap((profileRD: RemoteData) => { - if (profileRD.hasSucceeded) { - return this.researcherProfileService.patch(profileRD.payload, operations).pipe( - getFirstCompletedRemoteData(), - ); + this.#researcherProfile$ + .pipe( + switchMap(researcherProfile => this.researcherProfileService.patch(researcherProfile, operations)), + getFirstCompletedRemoteData(), + catchError((err: HttpErrorResponse) => of(createFailedRemoteDataObject(err.message, err.status))), + take(1) + ) + .subscribe((remoteData: RemoteData) => { + if (remoteData.hasFailed) { + this.notificationsService.error(this.translateService.get(this.messagePrefix + '.synchronization-settings-update.error')); } else { - return of(profileRD); + this.notificationsService.success(this.translateService.get(this.messagePrefix + '.synchronization-settings-update.success')); + this.settingsUpdated.emit(); } - }), - ).subscribe((remoteData: RemoteData) => { - if (remoteData.isSuccess) { - this.notificationsService.success(this.translateService.get(this.messagePrefix + '.synchronization-settings-update.success')); - this.settingsUpdated.emit(); - } else { - this.notificationsService.error(this.translateService.get(this.messagePrefix + '.synchronization-settings-update.error')); - } - }); + }); + } + + /** + * + * Handles subscriptions to populate sync preferences + * + * @param item observable that emits update on item changes + * @private + */ + private updateSyncPreferences(item: Observable) { + item.pipe( + filter(hasValue), + map(i => this.getCurrentPreference(i, 'dspace.orcid.sync-mode', ['BATCH', 'MANUAL'], 'MANUAL')), + takeUntil(this.#destroy$) + ).subscribe(val => this.currentSyncMode = val); + item.pipe( + filter(hasValue), + map(i => this.getCurrentPreference(i, 'dspace.orcid.sync-publications', ['DISABLED', 'ALL'], 'DISABLED')), + takeUntil(this.#destroy$) + ).subscribe(val => this.currentSyncPublications = val); + item.pipe( + filter(hasValue), + map(i => this.getCurrentPreference(i, 'dspace.orcid.sync-fundings', ['DISABLED', 'ALL'], 'DISABLED')), + takeUntil(this.#destroy$) + ).subscribe(val => this.currentSyncFunding = val); + } + + /** + * Handles subscription to populate the {@link syncProfileOptions} field + * + * @param item observable that emits update on item changes + * @private + */ + private updateSyncProfileOptions(item: Observable) { + item.pipe( + filter(hasValue), + map(i => i.allMetadataValues('dspace.orcid.sync-profile')), + map(metadata => + ['BIOGRAPHICAL', 'IDENTIFIERS'] + .map((value) => { + return { + label: this.messagePrefix + '.sync-profile.' + value.toLowerCase(), + value: value, + checked: metadata.includes(value) + }; + }) + ), + takeUntil(this.#destroy$) + ) + .subscribe(value => this.syncProfileOptions = value); } /** * Retrieve setting saved in the item's metadata * + * @param item The item from which retrieve settings * @param metadataField The metadata name that contains setting * @param allowedValues The allowed values * @param defaultValue The default value * @private */ - private getCurrentPreference(metadataField: string, allowedValues: string[], defaultValue: string): string { - const currentPreference = this.item.firstMetadataValue(metadataField); + private getCurrentPreference(item: Item, metadataField: string, allowedValues: string[], defaultValue: string): string { + const currentPreference = item.firstMetadataValue(metadataField); return (currentPreference && allowedValues.includes(currentPreference)) ? currentPreference : defaultValue; } From bdea9a6d716eefd6858787fd1bab69f5f8c2ad2a Mon Sep 17 00:00:00 2001 From: root Date: Mon, 1 Jul 2024 15:00:07 -0300 Subject: [PATCH 010/822] Resolution of issue #1193 - Addition of the aria-label attribute to the add, save, discard and undo buttons on the metadata editing page (cherry picked from commit 4e783e76d167e642c9205b440232211bfd4bc290) --- .../dso-edit-metadata/dso-edit-metadata.component.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html index 8fb676a7247..09868c6865e 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html @@ -1,21 +1,25 @@ From 288c75851eb0cb901ea3e80566fcf36f6128c870 Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Thu, 8 Aug 2024 23:17:22 -0700 Subject: [PATCH 031/822] src/app/shared/search: date slider accessibility Update date slider to prevent automatic page reloads. --- .../search-range-filter.component.html | 10 +++++++--- .../search-range-filter.component.ts | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.html b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.html index 6d4ba449204..dcb2b04c9fa 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.html +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.html @@ -8,7 +8,7 @@ {{'search.filters.filter.' + filterConfig.name + '.min.label' | translate}} @@ -20,7 +20,7 @@ {{'search.filters.filter.' + filterConfig.name + '.max.label' | translate}} @@ -33,7 +33,8 @@ @@ -43,5 +44,8 @@ + diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts index a6eaf436c97..1528acc0c66 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts @@ -81,6 +81,11 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple */ range; + /** + * The range currently selected by the slider + */ + sliderRange: [number | undefined, number | undefined]; + /** * Subscription to unsubscribe from */ @@ -138,6 +143,15 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple }; } + /** + * Updates the sliderRange property with the current slider range. + * This method is called whenever the slider value changes, but it does not immediately apply the changes. + * @param range - The current range selected by the slider + */ + onSliderChange(range: [number | undefined, number | undefined]): void { + this.sliderRange = range; + } + /** * Submits new custom range values to the range filter from the widget */ From 9d7aa07c1df73cee754fad38f7938149ad11985d Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 8 Aug 2024 16:49:20 -0500 Subject: [PATCH 032/822] Fix lint error regarding missing interface (cherry picked from commit ad6a9438de13f861a9096768e6efdacccbfdeaf4) --- .../publication-claim/publication-claim.component.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/notifications/suggestion-targets/publication-claim/publication-claim.component.ts b/src/app/notifications/suggestion-targets/publication-claim/publication-claim.component.ts index 5128c884689..a111fcd704c 100644 --- a/src/app/notifications/suggestion-targets/publication-claim/publication-claim.component.ts +++ b/src/app/notifications/suggestion-targets/publication-claim/publication-claim.component.ts @@ -4,6 +4,7 @@ import { NgIf, } from '@angular/common'; import { + AfterViewInit, Component, Input, OnDestroy, @@ -51,7 +52,7 @@ import { SuggestionTargetsStateService } from '../suggestion-targets.state.servi ], standalone: true, }) -export class PublicationClaimComponent implements OnDestroy, OnInit { +export class PublicationClaimComponent implements AfterViewInit, OnDestroy, OnInit { /** * The source for which to list targets From a0515c412140184c23cface4febb5d48f0d430eb Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Tue, 13 Aug 2024 11:43:36 +0200 Subject: [PATCH 033/822] 110615: Fixed related entities ay11 tab issue & removed potential duplicate ID issue by removing the unused #browseDropdown ID --- .../tabbed-related-entities-search.component.html | 8 +++++--- .../expandable-navbar-section.component.html | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/app/item-page/simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component.html b/src/app/item-page/simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component.html index 223d4a6ed0c..3ce96b2ce34 100644 --- a/src/app/item-page/simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component.html +++ b/src/app/item-page/simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component.html @@ -1,7 +1,9 @@ - - + diff --git a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.ts b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.ts index 7572d3ac8ba..eb7a703cc2d 100644 --- a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.ts +++ b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.ts @@ -36,7 +36,7 @@ import { getFirstSucceededRemoteDataPayload, } from '../../../core/shared/operators'; import { PageInfo } from '../../../core/shared/page-info.model'; -import { DisabledDirective } from '../../../shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive'; import { hasValue } from '../../../shared/empty.util'; import { HostWindowService } from '../../../shared/host-window.service'; import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils'; @@ -71,7 +71,7 @@ export interface ExternalSourceData { InfiniteScrollModule, NgbDropdownModule, FormsModule, - DisabledDirective, + BtnDisabledDirective, ], standalone: true, }) diff --git a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.ts b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.ts index 62546e18352..7618de51734 100644 --- a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.ts +++ b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.ts @@ -40,7 +40,7 @@ import { import { WorkspaceitemSectionCcLicenseObject } from '../../../core/submission/models/workspaceitem-section-cc-license.model'; import { SubmissionCcLicenseDataService } from '../../../core/submission/submission-cc-license-data.service'; import { SubmissionCcLicenseUrlDataService } from '../../../core/submission/submission-cc-license-url-data.service'; -import { DisabledDirective } from '../../../shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive'; import { DsSelectComponent } from '../../../shared/ds-select/ds-select.component'; import { isNotEmpty } from '../../../shared/empty.util'; import { ThemedLoadingComponent } from '../../../shared/loading/themed-loading.component'; @@ -65,7 +65,7 @@ import { SectionsType } from '../sections-type'; VarDirective, NgForOf, DsSelectComponent, - DisabledDirective, + BtnDisabledDirective, ], standalone: true, }) diff --git a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html index 91b89e84359..b03504c6beb 100644 --- a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html +++ b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html @@ -1,7 +1,7 @@
diff --git a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts index c7ba64e4b90..0a6c1bd44df 100644 --- a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts +++ b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts @@ -39,7 +39,7 @@ import { JsonPatchOperationsBuilder } from '../../../../../core/json-patch/build import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submission/models/workspaceitem-section-upload-file.model'; import { SubmissionJsonPatchOperationsService } from '../../../../../core/submission/submission-json-patch-operations.service'; import { dateToISOFormat } from '../../../../../shared/date.util'; -import { DisabledDirective } from '../../../../../shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../shared/btn-disabled.directive'; import { hasNoValue, hasValue, @@ -81,7 +81,7 @@ import { FormComponent, NgIf, TranslateModule, - DisabledDirective, + BtnDisabledDirective, ], standalone: true, }) diff --git a/src/app/submission/sections/upload/file/section-upload-file.component.html b/src/app/submission/sections/upload/file/section-upload-file.component.html index f8d6b9ca931..bfc09e86c18 100644 --- a/src/app/submission/sections/upload/file/section-upload-file.component.html +++ b/src/app/submission/sections/upload/file/section-upload-file.component.html @@ -35,7 +35,7 @@

{{fileName}} ({{fileData?.sizeBytes | dsFileSize}}) -

diff --git a/src/app/system-wide-alert/alert-form/system-wide-alert-form.component.ts b/src/app/system-wide-alert/alert-form/system-wide-alert-form.component.ts index b695bb47edd..ea1c0a55f0c 100644 --- a/src/app/system-wide-alert/alert-form/system-wide-alert-form.component.ts +++ b/src/app/system-wide-alert/alert-form/system-wide-alert-form.component.ts @@ -43,7 +43,7 @@ import { RemoteData } from '../../core/data/remote-data'; import { RequestService } from '../../core/data/request.service'; import { SystemWideAlertDataService } from '../../core/data/system-wide-alert-data.service'; import { getFirstCompletedRemoteData } from '../../core/shared/operators'; -import { DisabledDirective } from '../../shared/disabled-directive'; +import { BtnDisabledDirective } from '../../shared/btn-disabled.directive'; import { hasValue, isNotEmpty, @@ -60,7 +60,7 @@ import { SystemWideAlert } from '../system-wide-alert.model'; styleUrls: ['./system-wide-alert-form.component.scss'], templateUrl: './system-wide-alert-form.component.html', standalone: true, - imports: [FormsModule, ReactiveFormsModule, UiSwitchModule, NgIf, NgbDatepickerModule, NgbTimepickerModule, AsyncPipe, TranslateModule, DisabledDirective], + imports: [FormsModule, ReactiveFormsModule, UiSwitchModule, NgIf, NgbDatepickerModule, NgbTimepickerModule, AsyncPipe, TranslateModule, BtnDisabledDirective], }) export class SystemWideAlertFormComponent implements OnInit { diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts index e87a292c0ca..57e8c730316 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts @@ -45,7 +45,7 @@ import { Group } from '../../../../core/eperson/models/group.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators'; import { ContextHelpDirective } from '../../../../shared/context-help.directive'; -import { DisabledDirective } from '../../../../shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../shared/btn-disabled.directive'; import { hasValue } from '../../../../shared/empty.util'; import { NotificationsService } from '../../../../shared/notifications/notifications.service'; import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; @@ -77,7 +77,7 @@ enum SubKey { RouterLink, NgClass, NgForOf, - DisabledDirective, + BtnDisabledDirective, ], }) export class ReviewersListComponent extends MembersListComponent implements OnInit, OnChanges, OnDestroy { diff --git a/src/themes/custom/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts b/src/themes/custom/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts index 40a6264e4e2..f74a73a4b88 100644 --- a/src/themes/custom/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts +++ b/src/themes/custom/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts @@ -13,7 +13,7 @@ import { DsoEditMetadataValueComponent } from '../../../../../app/dso-shared/dso import { DsoEditMetadataValueHeadersComponent } from '../../../../../app/dso-shared/dso-edit-metadata/dso-edit-metadata-value-headers/dso-edit-metadata-value-headers.component'; import { MetadataFieldSelectorComponent } from '../../../../../app/dso-shared/dso-edit-metadata/metadata-field-selector/metadata-field-selector.component'; import { AlertComponent } from '../../../../../app/shared/alert/alert.component'; -import { DisabledDirective } from '../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../app/shared/btn-disabled.directive'; import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed-loading.component'; @Component({ @@ -23,7 +23,7 @@ import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed // templateUrl: './dso-edit-metadata.component.html', templateUrl: '../../../../../app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html', standalone: true, - imports: [NgIf, DsoEditMetadataHeadersComponent, MetadataFieldSelectorComponent, DsoEditMetadataValueHeadersComponent, DsoEditMetadataValueComponent, NgFor, DsoEditMetadataFieldValuesComponent, AlertComponent, ThemedLoadingComponent, AsyncPipe, TranslateModule, DisabledDirective], + imports: [NgIf, DsoEditMetadataHeadersComponent, MetadataFieldSelectorComponent, DsoEditMetadataValueHeadersComponent, DsoEditMetadataValueComponent, NgFor, DsoEditMetadataFieldValuesComponent, AlertComponent, ThemedLoadingComponent, AsyncPipe, TranslateModule, BtnDisabledDirective], }) export class DsoEditMetadataComponent extends BaseComponent { } diff --git a/src/themes/custom/app/forgot-password/forgot-password-form/forgot-password-form.component.ts b/src/themes/custom/app/forgot-password/forgot-password-form/forgot-password-form.component.ts index ff64b096644..37fb3834294 100644 --- a/src/themes/custom/app/forgot-password/forgot-password-form/forgot-password-form.component.ts +++ b/src/themes/custom/app/forgot-password/forgot-password-form/forgot-password-form.component.ts @@ -7,7 +7,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { ForgotPasswordFormComponent as BaseComponent } from '../../../../../app/forgot-password/forgot-password-form/forgot-password-form.component'; import { ProfilePageSecurityFormComponent } from '../../../../../app/profile-page/profile-page-security-form/profile-page-security-form.component'; -import { DisabledDirective } from '../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../app/shared/btn-disabled.directive'; import { BrowserOnlyPipe } from '../../../../../app/shared/utils/browser-only.pipe'; @Component({ @@ -23,7 +23,7 @@ import { BrowserOnlyPipe } from '../../../../../app/shared/utils/browser-only.pi ProfilePageSecurityFormComponent, AsyncPipe, NgIf, - DisabledDirective, + BtnDisabledDirective, ], }) /** diff --git a/src/themes/custom/app/info/end-user-agreement/end-user-agreement.component.ts b/src/themes/custom/app/info/end-user-agreement/end-user-agreement.component.ts index e557fc466cc..2b78006f650 100644 --- a/src/themes/custom/app/info/end-user-agreement/end-user-agreement.component.ts +++ b/src/themes/custom/app/info/end-user-agreement/end-user-agreement.component.ts @@ -4,7 +4,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { EndUserAgreementComponent as BaseComponent } from '../../../../../app/info/end-user-agreement/end-user-agreement.component'; import { EndUserAgreementContentComponent } from '../../../../../app/info/end-user-agreement/end-user-agreement-content/end-user-agreement-content.component'; -import { DisabledDirective } from '../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../app/shared/btn-disabled.directive'; @Component({ selector: 'ds-themed-end-user-agreement', @@ -13,7 +13,7 @@ import { DisabledDirective } from '../../../../../app/shared/disabled-directive' // templateUrl: './end-user-agreement.component.html' templateUrl: '../../../../../app/info/end-user-agreement/end-user-agreement.component.html', standalone: true, - imports: [EndUserAgreementContentComponent, FormsModule, TranslateModule, DisabledDirective], + imports: [EndUserAgreementContentComponent, FormsModule, TranslateModule, BtnDisabledDirective], }) /** diff --git a/src/themes/custom/app/info/feedback/feedback-form/feedback-form.component.ts b/src/themes/custom/app/info/feedback/feedback-form/feedback-form.component.ts index b86fecae7a6..38356671118 100644 --- a/src/themes/custom/app/info/feedback/feedback-form/feedback-form.component.ts +++ b/src/themes/custom/app/info/feedback/feedback-form/feedback-form.component.ts @@ -7,7 +7,7 @@ import { import { TranslateModule } from '@ngx-translate/core'; import { FeedbackFormComponent as BaseComponent } from '../../../../../../app/info/feedback/feedback-form/feedback-form.component'; -import { DisabledDirective } from '../../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../../app/shared/btn-disabled.directive'; import { ErrorComponent } from '../../../../../../app/shared/error/error.component'; @Component({ @@ -17,7 +17,7 @@ import { ErrorComponent } from '../../../../../../app/shared/error/error.compone // styleUrls: ['./feedback-form.component.scss'], styleUrls: ['../../../../../../app/info/feedback/feedback-form/feedback-form.component.scss'], standalone: true, - imports: [FormsModule, ReactiveFormsModule, NgIf, ErrorComponent, TranslateModule, DisabledDirective], + imports: [FormsModule, ReactiveFormsModule, NgIf, ErrorComponent, TranslateModule, BtnDisabledDirective], }) export class FeedbackFormComponent extends BaseComponent { } diff --git a/src/themes/custom/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts b/src/themes/custom/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts index 020293214ef..0efa0130640 100644 --- a/src/themes/custom/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts +++ b/src/themes/custom/app/item-page/media-viewer/media-viewer-video/media-viewer-video.component.ts @@ -7,7 +7,7 @@ import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { MediaViewerVideoComponent as BaseComponent } from '../../../../../../app/item-page/media-viewer/media-viewer-video/media-viewer-video.component'; -import { DisabledDirective } from '../../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../../app/shared/btn-disabled.directive'; @Component({ selector: 'ds-themed-media-viewer-video', @@ -21,7 +21,7 @@ import { DisabledDirective } from '../../../../../../app/shared/disabled-directi NgbDropdownModule, TranslateModule, NgIf, - DisabledDirective, + BtnDisabledDirective, ], }) export class MediaViewerVideoComponent extends BaseComponent { diff --git a/src/themes/custom/app/register-email-form/register-email-form.component.ts b/src/themes/custom/app/register-email-form/register-email-form.component.ts index d9be35f39dc..d1f4a6d3ffe 100644 --- a/src/themes/custom/app/register-email-form/register-email-form.component.ts +++ b/src/themes/custom/app/register-email-form/register-email-form.component.ts @@ -12,14 +12,14 @@ import { AlertComponent } from 'src/app/shared/alert/alert.component'; import { GoogleRecaptchaComponent } from 'src/app/shared/google-recaptcha/google-recaptcha.component'; import { RegisterEmailFormComponent as BaseComponent } from '../../../../app/register-email-form/register-email-form.component'; -import { DisabledDirective } from '../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../app/shared/btn-disabled.directive'; @Component({ selector: 'ds-themed-register-email-form', // templateUrl: './register-email-form.component.html', templateUrl: '../../../../app/register-email-form/register-email-form.component.html', standalone: true, - imports: [NgIf, FormsModule, ReactiveFormsModule, AlertComponent, GoogleRecaptchaComponent, AsyncPipe, TranslateModule, DisabledDirective], + imports: [NgIf, FormsModule, ReactiveFormsModule, AlertComponent, GoogleRecaptchaComponent, AsyncPipe, TranslateModule, BtnDisabledDirective], }) export class RegisterEmailFormComponent extends BaseComponent { } diff --git a/src/themes/custom/app/register-page/create-profile/create-profile.component.ts b/src/themes/custom/app/register-page/create-profile/create-profile.component.ts index 659e260b1c2..7c1ff908c37 100644 --- a/src/themes/custom/app/register-page/create-profile/create-profile.component.ts +++ b/src/themes/custom/app/register-page/create-profile/create-profile.component.ts @@ -9,7 +9,7 @@ import { TranslateModule } from '@ngx-translate/core'; import { ProfilePageSecurityFormComponent } from '../../../../../app/profile-page/profile-page-security-form/profile-page-security-form.component'; import { CreateProfileComponent as BaseComponent } from '../../../../../app/register-page/create-profile/create-profile.component'; -import { DisabledDirective } from '../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../app/shared/btn-disabled.directive'; /** * Component that renders the create profile page to be used by a user registering through a token @@ -28,7 +28,7 @@ import { DisabledDirective } from '../../../../../app/shared/disabled-directive' AsyncPipe, ReactiveFormsModule, NgForOf, - DisabledDirective, + BtnDisabledDirective, ], }) export class CreateProfileComponent extends BaseComponent { diff --git a/src/themes/custom/app/request-copy/email-request-copy/email-request-copy.component.ts b/src/themes/custom/app/request-copy/email-request-copy/email-request-copy.component.ts index a299e47a27b..cf4981d289b 100644 --- a/src/themes/custom/app/request-copy/email-request-copy/email-request-copy.component.ts +++ b/src/themes/custom/app/request-copy/email-request-copy/email-request-copy.component.ts @@ -7,7 +7,7 @@ import { FormsModule } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; import { EmailRequestCopyComponent as BaseComponent } from 'src/app/request-copy/email-request-copy/email-request-copy.component'; -import { DisabledDirective } from '../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../app/shared/btn-disabled.directive'; @Component({ selector: 'ds-themed-email-request-copy', @@ -16,7 +16,7 @@ import { DisabledDirective } from '../../../../../app/shared/disabled-directive' // templateUrl: './email-request-copy.component.html', templateUrl: './../../../../../app/request-copy/email-request-copy/email-request-copy.component.html', standalone: true, - imports: [FormsModule, NgClass, NgIf, TranslateModule, DisabledDirective], + imports: [FormsModule, NgClass, NgIf, TranslateModule, BtnDisabledDirective], }) export class EmailRequestCopyComponent extends BaseComponent { diff --git a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts index 7936deb4066..aec7bfd6db2 100644 --- a/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts +++ b/src/themes/custom/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts @@ -5,7 +5,7 @@ import { import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; -import { DisabledDirective } from '../../../../../../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../../../../../../app/shared/btn-disabled.directive'; import { ExternalSourceEntryImportModalComponent as BaseComponent } from '../../../../../../../../../../app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; import { ThemedSearchResultsComponent } from '../../../../../../../../../../app/shared/search/search-results/themed-search-results.component'; @@ -20,7 +20,7 @@ import { ThemedSearchResultsComponent } from '../../../../../../../../../../app/ ThemedSearchResultsComponent, NgIf, AsyncPipe, - DisabledDirective, + BtnDisabledDirective, ], }) export class ExternalSourceEntryImportModalComponent extends BaseComponent { diff --git a/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts b/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts index 17bc5d91364..cea515102ac 100644 --- a/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts +++ b/src/themes/custom/app/submission/sections/upload/file/section-upload-file.component.ts @@ -6,7 +6,7 @@ import { Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { SubmissionSectionUploadFileComponent as BaseComponent } from 'src/app/submission/sections/upload/file/section-upload-file.component'; -import { DisabledDirective } from '../../../../../../../app/shared/disabled-directive'; +import { BtnDisabledDirective } from '../../../../../../../app/shared/btn-disabled.directive'; import { ThemedFileDownloadLinkComponent } from '../../../../../../../app/shared/file-download-link/themed-file-download-link.component'; import { FileSizePipe } from '../../../../../../../app/shared/utils/file-size-pipe'; import { SubmissionSectionUploadFileViewComponent } from '../../../../../../../app/submission/sections/upload/file/view/section-upload-file-view.component'; @@ -28,7 +28,7 @@ import { SubmissionSectionUploadFileViewComponent } from '../../../../../../../a AsyncPipe, ThemedFileDownloadLinkComponent, FileSizePipe, - DisabledDirective, + BtnDisabledDirective, ], }) export class SubmissionSectionUploadFileComponent From eb5aadaf8ac9f5a4928997983aee00098d9ca8cd Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 16 Sep 2024 14:11:59 +0200 Subject: [PATCH 070/822] 117544: linting --- .../epeople-registry/eperson-form/eperson-form.component.ts | 2 +- .../group-form/members-list/members-list.component.ts | 2 +- .../delete-collection-page/delete-collection-page.component.ts | 2 +- .../delete-community-page/delete-community-page.component.ts | 2 +- .../profile-page-researcher-form.component.ts | 2 +- src/app/register-email-form/register-email-form.component.ts | 2 +- .../access-control-array-form.component.ts | 2 +- .../external-source-entry-import-modal.component.ts | 2 +- .../form/resource-policy-form.component.spec.ts | 2 +- .../resource-policies/form/resource-policy-form.component.ts | 2 +- .../subscription-view/subscription-view.component.ts | 2 +- .../collection/submission-form-collection.component.spec.ts | 2 +- .../form/collection/submission-form-collection.component.ts | 2 +- .../upload/file/edit/section-upload-file-edit.component.ts | 2 +- .../reviewers-list/reviewers-list.component.ts | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts index 1c6f1929f38..c8236ca22d1 100644 --- a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts +++ b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts @@ -65,8 +65,8 @@ import { import { PageInfo } from '../../../core/shared/page-info.model'; import { Registration } from '../../../core/shared/registration.model'; import { TYPE_REQUEST_FORGOT } from '../../../register-email-form/register-email-form.component'; -import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component'; import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive'; +import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component'; import { hasValue } from '../../../shared/empty.util'; import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; import { FormComponent } from '../../../shared/form/form.component'; diff --git a/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts b/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts index 6563a765d28..22934394c8a 100644 --- a/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts +++ b/src/app/access-control/group-registry/group-form/members-list/members-list.component.ts @@ -54,8 +54,8 @@ import { getFirstCompletedRemoteData, getRemoteDataPayload, } from '../../../../core/shared/operators'; -import { ContextHelpDirective } from '../../../../shared/context-help.directive'; import { BtnDisabledDirective } from '../../../../shared/btn-disabled.directive'; +import { ContextHelpDirective } from '../../../../shared/context-help.directive'; import { NotificationsService } from '../../../../shared/notifications/notifications.service'; import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; diff --git a/src/app/collection-page/delete-collection-page/delete-collection-page.component.ts b/src/app/collection-page/delete-collection-page/delete-collection-page.component.ts index 3d4d4abb5f9..acc716b52a7 100644 --- a/src/app/collection-page/delete-collection-page/delete-collection-page.component.ts +++ b/src/app/collection-page/delete-collection-page/delete-collection-page.component.ts @@ -15,8 +15,8 @@ import { import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { CollectionDataService } from '../../core/data/collection-data.service'; import { Collection } from '../../core/shared/collection.model'; -import { DeleteComColPageComponent } from '../../shared/comcol/comcol-forms/delete-comcol-page/delete-comcol-page.component'; import { BtnDisabledDirective } from '../../shared/btn-disabled.directive'; +import { DeleteComColPageComponent } from '../../shared/comcol/comcol-forms/delete-comcol-page/delete-comcol-page.component'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { VarDirective } from '../../shared/utils/var.directive'; diff --git a/src/app/community-page/delete-community-page/delete-community-page.component.ts b/src/app/community-page/delete-community-page/delete-community-page.component.ts index b2fa5956cbd..9c19a5eb472 100644 --- a/src/app/community-page/delete-community-page/delete-community-page.component.ts +++ b/src/app/community-page/delete-community-page/delete-community-page.component.ts @@ -15,8 +15,8 @@ import { import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { CommunityDataService } from '../../core/data/community-data.service'; import { Community } from '../../core/shared/community.model'; -import { DeleteComColPageComponent } from '../../shared/comcol/comcol-forms/delete-comcol-page/delete-comcol-page.component'; import { BtnDisabledDirective } from '../../shared/btn-disabled.directive'; +import { DeleteComColPageComponent } from '../../shared/comcol/comcol-forms/delete-comcol-page/delete-comcol-page.component'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { VarDirective } from '../../shared/utils/var.directive'; diff --git a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.ts b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.ts index 925ed6d5a6b..5d09097e6b9 100644 --- a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.ts +++ b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.ts @@ -36,8 +36,8 @@ import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload, } from '../../core/shared/operators'; -import { ConfirmationModalComponent } from '../../shared/confirmation-modal/confirmation-modal.component'; import { BtnDisabledDirective } from '../../shared/btn-disabled.directive'; +import { ConfirmationModalComponent } from '../../shared/confirmation-modal/confirmation-modal.component'; import { isNotEmpty } from '../../shared/empty.util'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { followLink } from '../../shared/utils/follow-link-config.model'; diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index 37ce725778e..585ca71c243 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -54,8 +54,8 @@ import { import { Registration } from '../core/shared/registration.model'; import { AlertComponent } from '../shared/alert/alert.component'; import { AlertType } from '../shared/alert/alert-type'; -import { KlaroService } from '../shared/cookies/klaro.service'; import { BtnDisabledDirective } from '../shared/btn-disabled.directive'; +import { KlaroService } from '../shared/cookies/klaro.service'; import { isNotEmpty } from '../shared/empty.util'; import { GoogleRecaptchaComponent } from '../shared/google-recaptcha/google-recaptcha.component'; import { NotificationsService } from '../shared/notifications/notifications.service'; diff --git a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts index 8f7f640c289..3dc84a833a5 100644 --- a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts +++ b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts @@ -16,8 +16,8 @@ import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateModule } from '@ngx-translate/core'; import { AccessesConditionOption } from '../../../core/config/models/config-accesses-conditions-options.model'; -import { dateToISOFormat } from '../../date.util'; import { BtnDisabledDirective } from '../../btn-disabled.directive'; +import { dateToISOFormat } from '../../date.util'; import { ToDatePipe } from './to-date.pipe'; @Component({ diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts index c666baf21fe..e0cc90ceaa6 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component.ts @@ -37,8 +37,8 @@ import { getRemoteDataPayload, } from '../../../../../../../core/shared/operators'; import { SubmissionImportExternalCollectionComponent } from '../../../../../../../submission/import-external/import-external-collection/submission-import-external-collection.component'; -import { CollectionListEntry } from '../../../../../../collection-dropdown/collection-dropdown.component'; import { BtnDisabledDirective } from '../../../../../../btn-disabled.directive'; +import { CollectionListEntry } from '../../../../../../collection-dropdown/collection-dropdown.component'; import { NotificationsService } from '../../../../../../notifications/notifications.service'; import { CollectionElementLinkType } from '../../../../../../object-collection/collection-element-link.type'; import { ItemSearchResult } from '../../../../../../object-collection/shared/item-search-result.model'; diff --git a/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts b/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts index d4dac77d72c..deaef6c611f 100644 --- a/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts +++ b/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts @@ -45,11 +45,11 @@ import { ResourcePolicy } from '../../../core/resource-policy/models/resource-po import { RESOURCE_POLICY } from '../../../core/resource-policy/models/resource-policy.resource-type'; import { SubmissionObjectDataService } from '../../../core/submission/submission-object-data.service'; import { SubmissionService } from '../../../submission/submission.service'; +import { BtnDisabledDirective } from '../../btn-disabled.directive'; import { dateToISOFormat, stringToNgbDateStruct, } from '../../date.util'; -import { BtnDisabledDirective } from '../../btn-disabled.directive'; import { isNotEmptyOperator } from '../../empty.util'; import { EpersonGroupListComponent } from '../../eperson-group-list/eperson-group-list.component'; import { dsDynamicFormControlMapFn } from '../../form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-map-fn'; diff --git a/src/app/shared/resource-policies/form/resource-policy-form.component.ts b/src/app/shared/resource-policies/form/resource-policy-form.component.ts index e13ba9ecc79..08a7f184922 100644 --- a/src/app/shared/resource-policies/form/resource-policy-form.component.ts +++ b/src/app/shared/resource-policies/form/resource-policy-form.component.ts @@ -47,11 +47,11 @@ import { ResourcePolicy } from '../../../core/resource-policy/models/resource-po import { RESOURCE_POLICY } from '../../../core/resource-policy/models/resource-policy.resource-type'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { getFirstSucceededRemoteData } from '../../../core/shared/operators'; +import { BtnDisabledDirective } from '../../btn-disabled.directive'; import { dateToISOFormat, stringToNgbDateStruct, } from '../../date.util'; -import { BtnDisabledDirective } from '../../btn-disabled.directive'; import { hasValue, hasValueOperator, diff --git a/src/app/shared/subscriptions/subscription-view/subscription-view.component.ts b/src/app/shared/subscriptions/subscription-view/subscription-view.component.ts index 9d9ce08905e..f940e697950 100644 --- a/src/app/shared/subscriptions/subscription-view/subscription-view.component.ts +++ b/src/app/shared/subscriptions/subscription-view/subscription-view.component.ts @@ -19,8 +19,8 @@ import { getDSORoute } from 'src/app/app-routing-paths'; import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { ConfirmationModalComponent } from '../../confirmation-modal/confirmation-modal.component'; import { BtnDisabledDirective } from '../../btn-disabled.directive'; +import { ConfirmationModalComponent } from '../../confirmation-modal/confirmation-modal.component'; import { hasValue } from '../../empty.util'; import { ThemedTypeBadgeComponent } from '../../object-collection/shared/badges/type-badge/themed-type-badge.component'; import { Subscription } from '../models/subscription.model'; diff --git a/src/app/submission/form/collection/submission-form-collection.component.spec.ts b/src/app/submission/form/collection/submission-form-collection.component.spec.ts index 61bad0439f0..3a5ae8a18d3 100644 --- a/src/app/submission/form/collection/submission-form-collection.component.spec.ts +++ b/src/app/submission/form/collection/submission-form-collection.component.spec.ts @@ -30,8 +30,8 @@ import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder'; import { Collection } from '../../../core/shared/collection.model'; import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service'; -import { ThemedCollectionDropdownComponent } from '../../../shared/collection-dropdown/themed-collection-dropdown.component'; import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive'; +import { ThemedCollectionDropdownComponent } from '../../../shared/collection-dropdown/themed-collection-dropdown.component'; import { DSONameServiceMock } from '../../../shared/mocks/dso-name.service.mock'; import { mockSubmissionId, diff --git a/src/app/submission/form/collection/submission-form-collection.component.ts b/src/app/submission/form/collection/submission-form-collection.component.ts index 10b1f815dc4..1736b474d5f 100644 --- a/src/app/submission/form/collection/submission-form-collection.component.ts +++ b/src/app/submission/form/collection/submission-form-collection.component.ts @@ -34,9 +34,9 @@ import { Collection } from '../../../core/shared/collection.model'; import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators'; import { SubmissionObject } from '../../../core/submission/models/submission-object.model'; import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service'; +import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive'; import { CollectionDropdownComponent } from '../../../shared/collection-dropdown/collection-dropdown.component'; import { ThemedCollectionDropdownComponent } from '../../../shared/collection-dropdown/themed-collection-dropdown.component'; -import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive'; import { hasValue, isNotEmpty, diff --git a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts index 0a6c1bd44df..79b3d3a5652 100644 --- a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts +++ b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.ts @@ -38,8 +38,8 @@ import { JsonPatchOperationPathCombiner } from '../../../../../core/json-patch/b import { JsonPatchOperationsBuilder } from '../../../../../core/json-patch/builder/json-patch-operations-builder'; import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submission/models/workspaceitem-section-upload-file.model'; import { SubmissionJsonPatchOperationsService } from '../../../../../core/submission/submission-json-patch-operations.service'; -import { dateToISOFormat } from '../../../../../shared/date.util'; import { BtnDisabledDirective } from '../../../../../shared/btn-disabled.directive'; +import { dateToISOFormat } from '../../../../../shared/date.util'; import { hasNoValue, hasValue, diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts index 57e8c730316..c43fabdb83a 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/reviewers-list/reviewers-list.component.ts @@ -44,8 +44,8 @@ import { EpersonDtoModel } from '../../../../core/eperson/models/eperson-dto.mod import { Group } from '../../../../core/eperson/models/group.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators'; -import { ContextHelpDirective } from '../../../../shared/context-help.directive'; import { BtnDisabledDirective } from '../../../../shared/btn-disabled.directive'; +import { ContextHelpDirective } from '../../../../shared/context-help.directive'; import { hasValue } from '../../../../shared/empty.util'; import { NotificationsService } from '../../../../shared/notifications/notifications.service'; import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; From 685e6d83c5a85269d0c47678ab4a282346184d99 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 16 Sep 2024 13:44:06 +0200 Subject: [PATCH 071/822] 117544: PR feedback - added typedocs - changed directive to only be present for buttons - various other small fixes --- .../filtered-items.component.html | 0 .../dso-edit-metadata-value.component.html | 47 +++++++++++++++++++ .../item-delete/item-delete.component.html | 2 +- .../access-control-array-form.component.html | 2 +- ...cess-control-form-container.component.html | 12 ++--- src/app/shared/disabled-directive.spec.ts | 8 ++++ src/app/shared/disabled-directive.ts | 28 ++++++++++- ...amic-form-control-container.component.html | 2 +- .../date-picker/date-picker.component.html | 6 +-- .../disabled/dynamic-disabled.component.html | 2 +- .../dynamic-disabled.component.spec.ts | 2 +- .../lookup/dynamic-lookup.component.html | 4 +- .../onebox/dynamic-onebox.component.html | 4 +- ...dynamic-scrollable-dropdown.component.html | 2 +- .../number-picker.component.html | 2 +- .../vocabulary-treeview.component.html | 4 +- .../collection-select.component.html | 2 +- .../item-select/item-select.component.html | 2 +- .../item-select/item-select.component.spec.ts | 3 +- .../pagination/pagination.component.html | 2 +- ...mission-section-cc-licenses.component.html | 4 +- 21 files changed, 110 insertions(+), 30 deletions(-) create mode 100644 src/app/admin/admin-reports/filtered-items/filtered-items.component.html diff --git a/src/app/admin/admin-reports/filtered-items/filtered-items.component.html b/src/app/admin/admin-reports/filtered-items/filtered-items.component.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html index f3d92ace2d1..18378019026 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html @@ -6,6 +6,53 @@ + + + + +
+ + + {{ dsoType + '.edit.metadata.authority.label' | translate }} {{ mdValue.newValue.authority }} + +
+
+
+ + + + +
+
{{ mdRepresentationName$ | async }} diff --git a/src/app/item-page/edit-item-page/item-delete/item-delete.component.html b/src/app/item-page/edit-item-page/item-delete/item-delete.component.html index eadec9babfa..667363a3813 100644 --- a/src/app/item-page/edit-item-page/item-delete/item-delete.component.html +++ b/src/app/item-page/edit-item-page/item-delete/item-delete.component.html @@ -18,7 +18,7 @@

{{headerMessage | translate: {id: item.handle} }}

diff --git a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html index 630812c3455..f2a5bdd4225 100644 --- a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html +++ b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html @@ -13,7 +13,7 @@

- - diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts index 3a431705c3d..eef3e45fa93 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts @@ -16,7 +16,7 @@ import { DATA_SERVICE_FACTORY } from '../../core/data/base/data-service.decorato import { Operation } from 'fast-json-patch'; import { RemoteData } from '../../core/data/remote-data'; import { Observable } from 'rxjs/internal/Observable'; -import {DisabledDirective} from '../../shared/disabled-directive'; +import {BtnDisabledDirective} from '../../shared/btn-disabled.directive'; const ADD_BTN = 'add'; const REINSTATE_BTN = 'reinstate'; @@ -72,7 +72,7 @@ describe('DsoEditMetadataComponent', () => { notificationsService = jasmine.createSpyObj('notificationsService', ['error', 'success']); TestBed.configureTestingModule({ - declarations: [DsoEditMetadataComponent, VarDirective, DisabledDirective], + declarations: [DsoEditMetadataComponent, VarDirective, BtnDisabledDirective], imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([])], providers: [ TestDataService, diff --git a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.html b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.html index 1f3df7e3334..6cff2903b94 100644 --- a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.html +++ b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.html @@ -28,7 +28,7 @@

{{'forgot-password.form.head' | translate}}

diff --git a/src/app/info/end-user-agreement/end-user-agreement.component.html b/src/app/info/end-user-agreement/end-user-agreement.component.html index 4b93d631b71..ceb2ad23a4c 100644 --- a/src/app/info/end-user-agreement/end-user-agreement.component.html +++ b/src/app/info/end-user-agreement/end-user-agreement.component.html @@ -7,7 +7,7 @@
- +
diff --git a/src/app/info/end-user-agreement/end-user-agreement.component.spec.ts b/src/app/info/end-user-agreement/end-user-agreement.component.spec.ts index 153fe4a51f6..c7735f0579f 100644 --- a/src/app/info/end-user-agreement/end-user-agreement.component.spec.ts +++ b/src/app/info/end-user-agreement/end-user-agreement.component.spec.ts @@ -11,7 +11,7 @@ import { Store } from '@ngrx/store'; import { By } from '@angular/platform-browser'; import { LogOutAction } from '../../core/auth/auth.actions'; import { ActivatedRouteStub } from '../../shared/testing/active-router.stub'; -import {DisabledDirective} from '../../shared/disabled-directive'; +import {BtnDisabledDirective} from '../../shared/btn-disabled.directive'; describe('EndUserAgreementComponent', () => { let component: EndUserAgreementComponent; @@ -50,7 +50,7 @@ describe('EndUserAgreementComponent', () => { init(); TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], - declarations: [EndUserAgreementComponent, DisabledDirective], + declarations: [EndUserAgreementComponent, BtnDisabledDirective], providers: [ { provide: EndUserAgreementService, useValue: endUserAgreementService }, { provide: NotificationsService, useValue: notificationsService }, diff --git a/src/app/info/feedback/feedback-form/feedback-form.component.html b/src/app/info/feedback/feedback-form/feedback-form.component.html index 3fdc66820ad..c5c4b460a23 100644 --- a/src/app/info/feedback/feedback-form/feedback-form.component.html +++ b/src/app/info/feedback/feedback-form/feedback-form.component.html @@ -41,7 +41,7 @@

{{ 'info.feedback.head' | translate }}

- +
diff --git a/src/app/info/feedback/feedback-form/feedback-form.component.spec.ts b/src/app/info/feedback/feedback-form/feedback-form.component.spec.ts index 0507b7173bc..7b7c6e28b65 100644 --- a/src/app/info/feedback/feedback-form/feedback-form.component.spec.ts +++ b/src/app/info/feedback/feedback-form/feedback-form.component.spec.ts @@ -18,7 +18,7 @@ import { Router } from '@angular/router'; import { RouterMock } from '../../../shared/mocks/router.mock'; import { NativeWindowService } from '../../../core/services/window.service'; import { NativeWindowMockFactory } from '../../../shared/mocks/mock-native-window-ref'; -import {DisabledDirective} from '../../../shared/disabled-directive'; +import {BtnDisabledDirective} from '../../../shared/btn-disabled.directive'; describe('FeedbackFormComponent', () => { @@ -39,7 +39,7 @@ describe('FeedbackFormComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], - declarations: [FeedbackFormComponent, DisabledDirective], + declarations: [FeedbackFormComponent, BtnDisabledDirective], providers: [ { provide: RouteService, useValue: routeServiceStub }, { provide: UntypedFormBuilder, useValue: new UntypedFormBuilder() }, diff --git a/src/app/item-page/bitstreams/request-a-copy/bitstream-request-a-copy-page.component.html b/src/app/item-page/bitstreams/request-a-copy/bitstream-request-a-copy-page.component.html index feffb1066fd..5b4b1bda521 100644 --- a/src/app/item-page/bitstreams/request-a-copy/bitstream-request-a-copy-page.component.html +++ b/src/app/item-page/bitstreams/request-a-copy/bitstream-request-a-copy-page.component.html @@ -79,7 +79,7 @@

{{'bitstream-request-a-copy.header' | translate}}

diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index c52d99b4394..ab20c3c22ba 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -12,7 +12,7 @@ class="fas fa-undo-alt">  {{"item.edit.bitstreams.reinstate-button" | translate}} -
- - - - diff --git a/src/app/item-page/edit-item-page/item-move/item-move.component.html b/src/app/item-page/edit-item-page/item-move/item-move.component.html index 2df52c6651a..e8061ae88bf 100644 --- a/src/app/item-page/edit-item-page/item-move/item-move.component.html +++ b/src/app/item-page/edit-item-page/item-move/item-move.component.html @@ -40,7 +40,7 @@

{{'item.edit.move.head' | translate: {id: (itemRD$ | async)?.payload?.handle - -

diff --git a/src/app/item-page/edit-item-page/item-operation/item-operation.component.html b/src/app/item-page/edit-item-page/item-operation/item-operation.component.html index 88acec3171f..75f0736bbc7 100644 --- a/src/app/item-page/edit-item-page/item-operation/item-operation.component.html +++ b/src/app/item-page/edit-item-page/item-operation/item-operation.component.html @@ -5,12 +5,12 @@

- - diff --git a/src/app/item-page/edit-item-page/item-operation/item-operation.component.spec.ts b/src/app/item-page/edit-item-page/item-operation/item-operation.component.spec.ts index 8c2774ad6c9..7d7087e02da 100644 --- a/src/app/item-page/edit-item-page/item-operation/item-operation.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-operation/item-operation.component.spec.ts @@ -4,7 +4,7 @@ import { ItemOperationComponent } from './item-operation.component'; import { TranslateModule } from '@ngx-translate/core'; import { By } from '@angular/platform-browser'; import { RouterTestingModule } from '@angular/router/testing'; -import {DisabledDirective} from '../../../shared/disabled-directive'; +import {BtnDisabledDirective} from '../../../shared/btn-disabled.directive'; describe('ItemOperationComponent', () => { let itemOperation: ItemOperation; @@ -15,7 +15,7 @@ describe('ItemOperationComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([])], - declarations: [ItemOperationComponent, DisabledDirective] + declarations: [ItemOperationComponent, BtnDisabledDirective] }).compileComponents(); })); diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html index b9a01c6b385..27faee89a79 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html @@ -1,6 +1,6 @@

{{relationshipMessageKey$ | async | translate}} - diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.html b/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.html index 169a171d3f2..8cd86d597b8 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.html +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.html @@ -9,12 +9,12 @@

- -
@@ -8,7 +8,7 @@ ngbDropdown *ngIf="(moreThanOne$ | async)">
-
diff --git a/src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html b/src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html index a118cd680d0..3233aa55550 100644 --- a/src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html +++ b/src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html @@ -29,7 +29,7 @@ {{ 'dso-selector.claim.item.not-mine-label' | translate }}

- diff --git a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html index aa2b81f0574..d14a9edfecc 100644 --- a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html +++ b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html @@ -13,7 +13,7 @@

{{'researcher.profile.not.associated' | translate}}

- -

- - diff --git a/src/app/register-page/create-profile/create-profile.component.html b/src/app/register-page/create-profile/create-profile.component.html index dbdb006785e..e5cf6c3e2e2 100644 --- a/src/app/register-page/create-profile/create-profile.component.html +++ b/src/app/register-page/create-profile/create-profile.component.html @@ -81,7 +81,7 @@

{{'register-page.create-profile.header' | translate}}

diff --git a/src/app/request-copy/email-request-copy/email-request-copy.component.html b/src/app/request-copy/email-request-copy/email-request-copy.component.html index 815a9a96916..b2227bfbaee 100644 --- a/src/app/request-copy/email-request-copy/email-request-copy.component.html +++ b/src/app/request-copy/email-request-copy/email-request-copy.component.html @@ -13,7 +13,7 @@
@@ -76,7 +76,7 @@
@@ -93,7 +93,7 @@ @@ -103,7 +103,7 @@ diff --git a/src/app/shared/disabled-directive.ts b/src/app/shared/btn-disabled.directive.ts similarity index 96% rename from src/app/shared/disabled-directive.ts rename to src/app/shared/btn-disabled.directive.ts index e5ae820e50e..ab37643c021 100644 --- a/src/app/shared/disabled-directive.ts +++ b/src/app/shared/btn-disabled.directive.ts @@ -1,7 +1,7 @@ import { Directive, Input, HostBinding, HostListener } from '@angular/core'; @Directive({ - selector: '[dsDisabled]' + selector: '[dsBtnDisabled]' }) /** @@ -10,7 +10,7 @@ import { Directive, Input, HostBinding, HostListener } from '@angular/core'; * * This directive should always be used instead of the HTML disabled attribute as it is more accessible. */ -export class DisabledDirective { +export class BtnDisabledDirective { @Input() set dsDisabled(value: boolean) { this.isDisabled = !!value; diff --git a/src/app/shared/disabled-directive.spec.ts b/src/app/shared/disabled-directive.spec.ts index 514011cebdc..71515c48ff3 100644 --- a/src/app/shared/disabled-directive.spec.ts +++ b/src/app/shared/disabled-directive.spec.ts @@ -1,11 +1,11 @@ import { Component, DebugElement } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { DisabledDirective } from './disabled-directive'; +import { BtnDisabledDirective } from './btn-disabled.directive'; @Component({ template: ` - + ` }) class TestComponent { @@ -19,7 +19,7 @@ describe('DisabledDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - declarations: [TestComponent, DisabledDirective] + declarations: [TestComponent, BtnDisabledDirective] }); fixture = TestBed.createComponent(TestComponent); component = fixture.componentInstance; diff --git a/src/app/shared/ds-select/ds-select.component.html b/src/app/shared/ds-select/ds-select.component.html index de53ef07921..e87b7c5cc6c 100644 --- a/src/app/shared/ds-select/ds-select.component.html +++ b/src/app/shared/ds-select/ds-select.component.html @@ -13,7 +13,7 @@ class="btn btn-outline-primary selection" (blur)="close.emit($event)" (click)="close.emit($event)" - [dsDisabled]="disabled" + [dsBtnDisabled]="disabled" ngbDropdownToggle> diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html index 747d14cac6a..05032813296 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.html @@ -1,7 +1,7 @@
-
    diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html index 9f796c35cec..0738e2f28ab 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html @@ -5,7 +5,7 @@ {{itemModel.text | translate}} - @@ -13,7 +13,7 @@
    - @@ -60,7 +60,7 @@ type="button" ngbTooltip="{{'form.clear-help' | translate}}" placement="top" - [dsDisabled]="model.readOnly" + [dsBtnDisabled]="model.readOnly" (click)="remove()">{{'form.clear' | translate}}
    @@ -69,14 +69,14 @@ type="button" ngbTooltip="{{'form.edit-help' | translate}}" placement="top" - [dsDisabled]="isEditDisabled()" + [dsBtnDisabled]="isEditDisabled()" (click)="switchEditMode()">{{'form.edit' | translate}}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts index 2fb6488e93f..81db85f863b 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts @@ -26,7 +26,7 @@ import { mockDynamicFormLayoutService, mockDynamicFormValidationService } from '../../../../../testing/dynamic-form-mock-services'; -import {DisabledDirective} from '../../../../../disabled-directive'; +import {BtnDisabledDirective} from '../../../../../btn-disabled.directive'; let LOOKUP_TEST_MODEL_CONFIG: DynamicLookupModelConfig = { vocabularyOptions: { @@ -155,7 +155,7 @@ describe('Dynamic Lookup component', () => { TestComponent, AuthorityConfidenceStateDirective, ObjNgFor, - DisabledDirective + BtnDisabledDirective ], // declare the test component providers: [ ChangeDetectorRef, diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html index 92c68fd9b92..6a0e34f6719 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html @@ -32,21 +32,21 @@ @@ -73,18 +73,18 @@
diff --git a/src/app/shared/form/form.component.html b/src/app/shared/form/form.component.html index 4099cdb915a..fca41bc2523 100644 --- a/src/app/shared/form/form.component.html +++ b/src/app/shared/form/form.component.html @@ -41,7 +41,7 @@ title="{{'form.discard' | translate}}" attr.aria-label="{{'form.discard' | translate}}" (click)="removeItem($event, context, index)" - [dsDisabled]="group.context.groups.length === 1 || isItemReadOnly(context, index)"> + [dsBtnDisabled]="group.context.groups.length === 1 || isItemReadOnly(context, index)"> {{'form.discard' | translate}}
@@ -62,7 +62,7 @@ diff --git a/src/app/shared/form/number-picker/number-picker.component.html b/src/app/shared/form/number-picker/number-picker.component.html index 8f2a875685b..9b9d038e868 100644 --- a/src/app/shared/form/number-picker/number-picker.component.html +++ b/src/app/shared/form/number-picker/number-picker.component.html @@ -3,7 +3,7 @@ class="btn btn-link-focus" type="button" tabindex="0" - [dsDisabled]="disabled" + [dsBtnDisabled]="disabled" (click)="toggleUp()"> {{'form.number-picker.increment' | translate: {field: name} }} @@ -30,7 +30,7 @@ class="btn btn-link-focus" type="button" tabindex="0" - [dsDisabled]="disabled" + [dsBtnDisabled]="disabled" (click)="toggleDown()"> {{'form.number-picker.decrement' | translate: {field: name} }} diff --git a/src/app/shared/form/number-picker/number-picker.component.spec.ts b/src/app/shared/form/number-picker/number-picker.component.spec.ts index 5857d9e4a5a..b6d623d70b7 100644 --- a/src/app/shared/form/number-picker/number-picker.component.spec.ts +++ b/src/app/shared/form/number-picker/number-picker.component.spec.ts @@ -44,7 +44,7 @@ describe('NumberPickerComponent test suite', () => { beforeEach(() => { html = `
- -
@@ -45,7 +45,7 @@

{{ (message | async) | translate }}

+ [dsBtnDisabled]="!form.valid"> {{"login.form.submit" | translate}}
diff --git a/src/app/shared/mydspace-actions/claimed-task/approve/claimed-task-actions-approve.component.html b/src/app/shared/mydspace-actions/claimed-task/approve/claimed-task-actions-approve.component.html index e4f52cf3619..9785715ee80 100644 --- a/src/app/shared/mydspace-actions/claimed-task/approve/claimed-task-actions-approve.component.html +++ b/src/app/shared/mydspace-actions/claimed-task/approve/claimed-task-actions-approve.component.html @@ -1,7 +1,7 @@ diff --git a/src/app/shared/object-select/item-select/item-select.component.html b/src/app/shared/object-select/item-select/item-select.component.html index 58eed6ae4aa..d1c2986076a 100644 --- a/src/app/shared/object-select/item-select/item-select.component.html +++ b/src/app/shared/object-select/item-select/item-select.component.html @@ -42,7 +42,7 @@ diff --git a/src/app/shared/object-select/item-select/item-select.component.spec.ts b/src/app/shared/object-select/item-select/item-select.component.spec.ts index 7d2e5c4146d..9fb9a0260a1 100644 --- a/src/app/shared/object-select/item-select/item-select.component.spec.ts +++ b/src/app/shared/object-select/item-select/item-select.component.spec.ts @@ -24,7 +24,7 @@ import { LinkHeadService } from '../../../core/services/link-head.service'; import { GroupDataService } from '../../../core/eperson/group-data.service'; import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; import { ConfigurationProperty } from '../../../core/shared/configuration-property.model'; -import {DisabledDirective} from '../../disabled-directive'; +import {BtnDisabledDirective} from '../../btn-disabled.directive'; describe('ItemSelectComponent', () => { let comp: ItemSelectComponent; @@ -99,7 +99,7 @@ describe('ItemSelectComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), SharedModule, RouterTestingModule.withRoutes([])], - declarations: [DisabledDirective], + declarations: [BtnDisabledDirective], providers: [ { provide: ObjectSelectService, useValue: new ObjectSelectServiceStub([mockItemList[1].id]) }, { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, diff --git a/src/app/shared/pagination/pagination.component.html b/src/app/shared/pagination/pagination.component.html index b85dcb01ee7..f7f2c64e2c5 100644 --- a/src/app/shared/pagination/pagination.component.html +++ b/src/app/shared/pagination/pagination.component.html @@ -55,12 +55,12 @@
-
diff --git a/src/app/submission/form/collection/submission-form-collection.component.html b/src/app/submission/form/collection/submission-form-collection.component.html index 7f50e5a3417..fe9527c2665 100644 --- a/src/app/submission/form/collection/submission-form-collection.component.html +++ b/src/app/submission/form/collection/submission-form-collection.component.html @@ -25,7 +25,7 @@ class="btn btn-outline-primary" (blur)="onClose()" (click)="onClose()" - [dsDisabled]="(processingChange$ | async) || collectionModifiable == false || isReadonly" + [dsBtnDisabled]="(processingChange$ | async) || collectionModifiable == false || isReadonly" ngbDropdownToggle> {{ selectedCollectionName$ | async }} diff --git a/src/app/submission/form/collection/submission-form-collection.component.spec.ts b/src/app/submission/form/collection/submission-form-collection.component.spec.ts index 4cb40e2293a..467f164f89c 100644 --- a/src/app/submission/form/collection/submission-form-collection.component.spec.ts +++ b/src/app/submission/form/collection/submission-form-collection.component.spec.ts @@ -25,7 +25,7 @@ import { Collection } from '../../../core/shared/collection.model'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock } from '../../../shared/mocks/dso-name.service.mock'; -import {DisabledDirective} from '../../../shared/disabled-directive'; +import {BtnDisabledDirective} from '../../../shared/btn-disabled.directive'; describe('SubmissionFormCollectionComponent Component', () => { @@ -137,7 +137,7 @@ describe('SubmissionFormCollectionComponent Component', () => { declarations: [ SubmissionFormCollectionComponent, TestComponent, - DisabledDirective + BtnDisabledDirective ], providers: [ { provide: DSONameService, useValue: new DSONameServiceMock() }, diff --git a/src/app/submission/form/footer/submission-form-footer.component.html b/src/app/submission/form/footer/submission-form-footer.component.html index f7e8bae792a..457a56cc769 100644 --- a/src/app/submission/form/footer/submission-form-footer.component.html +++ b/src/app/submission/form/footer/submission-form-footer.component.html @@ -5,7 +5,7 @@ id="discard" [attr.data-test]="'discard' | dsBrowserOnly" class="btn btn-danger" - [dsDisabled]="(processingSaveStatus | async) || (processingDepositStatus | async)" + [dsBtnDisabled]="(processingSaveStatus | async) || (processingDepositStatus | async)" (click)="$event.preventDefault();confirmDiscard(content)"> {{'submission.general.discard.submit' | translate}} @@ -28,7 +28,7 @@ class="btn btn-secondary" id="save" [attr.data-test]="'save' | dsBrowserOnly" - [dsDisabled]="(processingSaveStatus | async) || !(hasUnsavedModification | async)" + [dsBtnDisabled]="(processingSaveStatus | async) || !(hasUnsavedModification | async)" (click)="save($event)"> {{'submission.general.save' | translate}} @@ -38,7 +38,7 @@ class="btn" id="saveForLater" [attr.data-test]="'save-for-later' | dsBrowserOnly" - [dsDisabled]="(processingSaveStatus | async) || (processingDepositStatus | async)" + [dsBtnDisabled]="(processingSaveStatus | async) || (processingDepositStatus | async)" (click)="saveLater($event)"> {{'submission.general.save-later' | translate}} @@ -47,7 +47,7 @@ id="deposit" [attr.data-test]="'deposit' | dsBrowserOnly" class="btn btn-success" - [dsDisabled]="(processingSaveStatus | async) || (processingDepositStatus | async)" + [dsBtnDisabled]="(processingSaveStatus | async) || (processingDepositStatus | async)" (click)="deposit($event)"> {{'submission.general.deposit' | translate}} diff --git a/src/app/submission/form/footer/submission-form-footer.component.spec.ts b/src/app/submission/form/footer/submission-form-footer.component.spec.ts index 90718055144..658926834c9 100644 --- a/src/app/submission/form/footer/submission-form-footer.component.spec.ts +++ b/src/app/submission/form/footer/submission-form-footer.component.spec.ts @@ -16,7 +16,7 @@ import { SubmissionFormFooterComponent } from './submission-form-footer.componen import { SubmissionRestService } from '../../../core/submission/submission-rest.service'; import { createTestComponent } from '../../../shared/testing/utils.test'; import { BrowserOnlyMockPipe } from '../../../shared/testing/browser-only-mock.pipe'; -import {DisabledDirective} from '../../../shared/disabled-directive'; +import {BtnDisabledDirective} from '../../../shared/btn-disabled.directive'; const submissionServiceStub: SubmissionServiceStub = new SubmissionServiceStub(); @@ -40,7 +40,7 @@ describe('SubmissionFormFooterComponent', () => { SubmissionFormFooterComponent, TestComponent, BrowserOnlyMockPipe, - DisabledDirective + BtnDisabledDirective ], providers: [ { provide: SubmissionService, useValue: submissionServiceStub }, diff --git a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.html b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.html index 28fa4695fbb..cb8dde18c50 100644 --- a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.html +++ b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.html @@ -23,6 +23,6 @@

{{'submission.import-external.source.loading' | translate}}

- +
diff --git a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html index 1ce811ce661..b529d9aee49 100644 --- a/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html +++ b/src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html @@ -1,7 +1,7 @@
diff --git a/src/app/submission/sections/upload/file/section-upload-file.component.html b/src/app/submission/sections/upload/file/section-upload-file.component.html index 589e7b6ebfe..3567ef5c64d 100644 --- a/src/app/submission/sections/upload/file/section-upload-file.component.html +++ b/src/app/submission/sections/upload/file/section-upload-file.component.html @@ -19,7 +19,7 @@

{{fileName}} ({{fileData?.sizeBytes | dsFileSize}}) -

From d3e87c68fdb6cc797e641d45d2040a94b6302232 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 16 Sep 2024 16:09:41 +0200 Subject: [PATCH 073/822] 117544: fix remaining bug --- src/app/shared/btn-disabled.directive.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/btn-disabled.directive.ts b/src/app/shared/btn-disabled.directive.ts index f73422a9d5d..427d1654da0 100644 --- a/src/app/shared/btn-disabled.directive.ts +++ b/src/app/shared/btn-disabled.directive.ts @@ -18,7 +18,7 @@ import { */ export class BtnDisabledDirective { - @Input() set dsDisabled(value: boolean) { + @Input() set dsBtnDisabled(value: boolean) { this.isDisabled = !!value; } From 4a7ebeea16cdd902f99da11ba2dc9e5ab155620e Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 16 Sep 2024 16:09:41 +0200 Subject: [PATCH 074/822] 117544: fix remaining bug --- src/app/shared/btn-disabled.directive.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/btn-disabled.directive.ts b/src/app/shared/btn-disabled.directive.ts index ab37643c021..512aa87edef 100644 --- a/src/app/shared/btn-disabled.directive.ts +++ b/src/app/shared/btn-disabled.directive.ts @@ -12,7 +12,7 @@ import { Directive, Input, HostBinding, HostListener } from '@angular/core'; */ export class BtnDisabledDirective { - @Input() set dsDisabled(value: boolean) { + @Input() set dsBtnDisabled(value: boolean) { this.isDisabled = !!value; } From 7ade45321814218c02e40047318703c1799b2471 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Wed, 18 Sep 2024 09:46:38 +0200 Subject: [PATCH 075/822] lint rule with autofix to disallow the disabled input on button elements --- .eslintrc.json | 3 +- lint/src/rules/html/index.ts | 3 + lint/src/rules/html/no-disabled-attr.ts | 144 ++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 lint/src/rules/html/no-disabled-attr.ts diff --git a/.eslintrc.json b/.eslintrc.json index 5fb4c121717..a9e44c59374 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -293,7 +293,8 @@ ], "rules": { // Custom DSpace Angular rules - "dspace-angular-html/themed-component-usages": "error" + "dspace-angular-html/themed-component-usages": "error", + "dspace-angular-html/no-disabled-attr": "error" } }, { diff --git a/lint/src/rules/html/index.ts b/lint/src/rules/html/index.ts index 7c1370ae2d4..120751d65aa 100644 --- a/lint/src/rules/html/index.ts +++ b/lint/src/rules/html/index.ts @@ -10,10 +10,13 @@ import { bundle, RuleExports, } from '../../util/structure'; +import * as noDisabledAttr from './no-disabled-attr'; import * as themedComponentUsages from './themed-component-usages'; const index = [ themedComponentUsages, + noDisabledAttr, + ] as unknown as RuleExports[]; export = { diff --git a/lint/src/rules/html/no-disabled-attr.ts b/lint/src/rules/html/no-disabled-attr.ts new file mode 100644 index 00000000000..22f987d52b9 --- /dev/null +++ b/lint/src/rules/html/no-disabled-attr.ts @@ -0,0 +1,144 @@ +import { + TmplAstBoundAttribute, + TmplAstTextAttribute +} from '@angular-eslint/bundled-angular-compiler'; +import { TemplateParserServices } from '@angular-eslint/utils'; +import { + ESLintUtils, + TSESLint, +} from '@typescript-eslint/utils'; +import { + DSpaceESLintRuleInfo, + NamedTests, +} from '../../util/structure'; +import { getSourceCode } from '../../util/typescript'; + +export enum Message { + USE_DSBTN_DISABLED = 'mustUseDsBtnDisabled', +} + +export const info = { + name: 'no-disabled-attr', + meta: { + docs: { + description: `Buttons should use the \`dsBtnDisabled\` directive instead of the HTML \`disabled\` attribute for accessibility reasons.`, + }, + type: 'problem', + fixable: 'code', + schema: [], + messages: { + [Message.USE_DSBTN_DISABLED]: 'Buttons should use the `dsBtnDisabled` directive instead of the `disabled` attribute.', + }, + }, + defaultOptions: [], +} as DSpaceESLintRuleInfo; + +export const rule = ESLintUtils.RuleCreator.withoutDocs({ + ...info, + create(context: TSESLint.RuleContext) { + const parserServices = getSourceCode(context).parserServices as TemplateParserServices; + + /** + * Some dynamic angular inputs will have disabled as name because of how Angular handles this internally (e.g [class.disabled]="isDisabled") + * But these aren't actually the disabled attribute we're looking for, we can determine this by checking the details of the keySpan + */ + function isOtherAttributeDisabled(node: TmplAstBoundAttribute | TmplAstTextAttribute): boolean { + // if the details are not null, and the details are not 'disabled', then it's not the disabled attribute we're looking for + return node.keySpan?.details !== null && node.keySpan?.details !== 'disabled'; + } + + /** + * Replace the disabled text with [dsBtnDisabled] in the template + */ + function replaceDisabledText(text: string ): string { + const hasBrackets = text.includes('[') && text.includes(']'); + const newDisabledText = hasBrackets ? 'dsBtnDisabled' : '[dsBtnDisabled]'; + return text.replace('disabled', newDisabledText); + } + + function inputIsChildOfButton(node: any): boolean { + return (node.parent?.tagName === 'button' || node.parent?.name === 'button'); + } + + function reportAndFix(node: TmplAstBoundAttribute | TmplAstTextAttribute) { + if (!inputIsChildOfButton(node) || isOtherAttributeDisabled(node)) { + return; + } + + const sourceSpan = node.sourceSpan; + context.report({ + messageId: Message.USE_DSBTN_DISABLED, + loc: parserServices.convertNodeSourceSpanToLoc(sourceSpan), + fix(fixer) { + const templateText = sourceSpan.start.file.content; + const disabledText = templateText.slice(sourceSpan.start.offset, sourceSpan.end.offset); + const newText = replaceDisabledText(disabledText); + return fixer.replaceTextRange([sourceSpan.start.offset, sourceSpan.end.offset], newText); + }, + }); + } + + return { + 'BoundAttribute[name="disabled"]'(node: TmplAstBoundAttribute) { + reportAndFix(node); + }, + 'TextAttribute[name="disabled"]'(node: TmplAstTextAttribute) { + reportAndFix(node); + }, + }; + }, +}); + +export const tests = { + plugin: info.name, + valid: [ + { + name: 'should use [dsBtnDisabled] in HTML templates', + code: ` + + `, + }, + { + name: 'disabled attribute is still valid on non-button elements', + code: ` + + `, + }, + { + name: '[disabled] attribute is still valid on non-button elements', + code: ` + + `, + }, + { + name: 'angular dynamic attributes that use disabled are still valid', + code: ` + + `, + }, + ], + invalid: [ + { + name: 'should not use disabled attribute in HTML templates', + code: ` + + `, + errors: [{ messageId: Message.USE_DSBTN_DISABLED }], + output: ` + + `, + }, + { + name: 'should not use [disabled] attribute in HTML templates', + code: ` + + `, + errors: [{ messageId: Message.USE_DSBTN_DISABLED }], + output: ` + + `, + }, + ], +} as NamedTests; + +export default rule; From 83a44ba924fb20065f0bb62fc2a09a7aaec391bc Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Mon, 16 Sep 2024 15:46:07 +0200 Subject: [PATCH 076/822] 118220: Add live-region service and component --- config/config.example.yml | 16 ++- .../live-region/live-region.component.html | 3 + .../live-region/live-region.component.scss | 13 ++ .../live-region/live-region.component.ts | 25 ++++ .../shared/live-region/live-region.config.ts | 9 ++ .../shared/live-region/live-region.service.ts | 118 ++++++++++++++++++ src/app/shared/shared.module.ts | 4 +- src/config/app-config.interface.ts | 2 + src/config/default-app-config.ts | 7 ++ src/environments/environment.test.ts | 7 +- src/styles/_custom_variables.scss | 1 + 11 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 src/app/shared/live-region/live-region.component.html create mode 100644 src/app/shared/live-region/live-region.component.scss create mode 100644 src/app/shared/live-region/live-region.component.ts create mode 100644 src/app/shared/live-region/live-region.config.ts create mode 100644 src/app/shared/live-region/live-region.service.ts diff --git a/config/config.example.yml b/config/config.example.yml index ea38303fa36..58eb6ff33d2 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -379,4 +379,18 @@ vocabularies: # Default collection/community sorting order at Advanced search, Create/update community and collection when there are not a query. comcolSelectionSort: sortField: 'dc.title' - sortDirection: 'ASC' \ No newline at end of file + sortDirection: 'ASC' + +# Live Region configuration +# Live Region as defined by w3c, https://www.w3.org/TR/wai-aria-1.1/#terms: +# Live regions are perceivable regions of a web page that are typically updated as a +# result of an external event when user focus may be elsewhere. +# +# The DSpace live region is a component present at the bottom of all pages that is invisible by default, but is useful +# for screen readers. Any message pushed to the live region will be announced by the screen reader. These messages +# usually contain information about changes on the page that might not be in focus. +liveRegion: + # The duration after which messages disappear from the live region in milliseconds + messageTimeOutDurationMs: 30000 + # The visibility of the live region. Setting this to true is only useful for debugging purposes. + isVisible: false diff --git a/src/app/shared/live-region/live-region.component.html b/src/app/shared/live-region/live-region.component.html new file mode 100644 index 00000000000..a48f3ad52e5 --- /dev/null +++ b/src/app/shared/live-region/live-region.component.html @@ -0,0 +1,3 @@ +
+
{{ message }}
+
diff --git a/src/app/shared/live-region/live-region.component.scss b/src/app/shared/live-region/live-region.component.scss new file mode 100644 index 00000000000..69844a93e1e --- /dev/null +++ b/src/app/shared/live-region/live-region.component.scss @@ -0,0 +1,13 @@ +.live-region { + position: fixed; + bottom: 0; + left: 0; + right: 0; + padding-left: 60px; + height: 90px; + line-height: 18px; + color: var(--bs-white); + background-color: var(--bs-dark); + opacity: 0.94; + z-index: var(--ds-live-region-z-index); +} diff --git a/src/app/shared/live-region/live-region.component.ts b/src/app/shared/live-region/live-region.component.ts new file mode 100644 index 00000000000..d7bd5eb806c --- /dev/null +++ b/src/app/shared/live-region/live-region.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit } from '@angular/core'; +import { LiveRegionService } from './live-region.service'; +import { Observable } from 'rxjs'; + +@Component({ + selector: `ds-live-region`, + templateUrl: './live-region.component.html', + styleUrls: ['./live-region.component.scss'], +}) +export class LiveRegionComponent implements OnInit { + + protected isVisible: boolean; + + protected messages$: Observable; + + constructor( + protected liveRegionService: LiveRegionService, + ) { + } + + ngOnInit() { + this.isVisible = this.liveRegionService.getLiveRegionVisibility(); + this.messages$ = this.liveRegionService.getMessages$(); + } +} diff --git a/src/app/shared/live-region/live-region.config.ts b/src/app/shared/live-region/live-region.config.ts new file mode 100644 index 00000000000..e545bfd2543 --- /dev/null +++ b/src/app/shared/live-region/live-region.config.ts @@ -0,0 +1,9 @@ +import { Config } from '../../../config/config.interface'; + +/** + * Configuration interface used by the LiveRegionService + */ +export class LiveRegionConfig implements Config { + messageTimeOutDurationMs: number; + isVisible: boolean; +} diff --git a/src/app/shared/live-region/live-region.service.ts b/src/app/shared/live-region/live-region.service.ts new file mode 100644 index 00000000000..482d1ca1bbf --- /dev/null +++ b/src/app/shared/live-region/live-region.service.ts @@ -0,0 +1,118 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { environment } from '../../../environments/environment'; + +@Injectable({ + providedIn: 'root', +}) +export class LiveRegionService { + + /** + * The duration after which the messages disappear in milliseconds + * @protected + */ + protected messageTimeOutDurationMs: number = environment.liveRegion.messageTimeOutDurationMs; + + /** + * Array containing the messages that should be shown in the live region + * @protected + */ + protected messages: string[] = []; + + /** + * BehaviorSubject emitting the array with messages every time the array updates + * @protected + */ + protected messages$: BehaviorSubject = new BehaviorSubject([]); + + /** + * Whether the live region should be visible + * @protected + */ + protected liveRegionIsVisible: boolean = environment.liveRegion.isVisible; + + /** + * Returns a copy of the array with the current live region messages + */ + getMessages() { + return [...this.messages]; + } + + /** + * Returns the BehaviorSubject emitting the array with messages every time the array updates + */ + getMessages$() { + return this.messages$; + } + + /** + * Adds a message to the live-region messages array + * @param message + */ + addMessage(message: string) { + this.messages.push(message); + this.emitCurrentMessages(); + + // Clear the message once the timeOut has passed + setTimeout(() => this.pop(), this.messageTimeOutDurationMs); + } + + /** + * Clears the live-region messages array + */ + clear() { + this.messages = []; + this.emitCurrentMessages(); + } + + /** + * Removes the longest living message from the array. + * @protected + */ + protected pop() { + if (this.messages.length > 0) { + this.messages.shift(); + this.emitCurrentMessages(); + } + } + + /** + * Makes the messages$ BehaviorSubject emit the current messages array + * @protected + */ + protected emitCurrentMessages() { + this.messages$.next(this.getMessages()); + } + + /** + * Returns a boolean specifying whether the live region should be visible. + * Returns 'true' if the region should be visible and false otherwise. + */ + getLiveRegionVisibility(): boolean { + return this.liveRegionIsVisible; + } + + /** + * Sets the visibility of the live region. + * Setting this to true will make the live region visible which is useful for debugging purposes. + * @param isVisible + */ + setLiveRegionVisibility(isVisible: boolean) { + this.liveRegionIsVisible = isVisible; + } + + /** + * Gets the current message timeOut duration in milliseconds + */ + getMessageTimeOutMs(): number { + return this.messageTimeOutDurationMs; + } + + /** + * Sets the message timeOut duration + * @param timeOutMs the message timeOut duration in milliseconds + */ + setMessageTimeOutMs(timeOutMs: number) { + this.messageTimeOutDurationMs = timeOutMs; + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 0f7871f7f9b..db5b7787228 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -284,6 +284,7 @@ import { } from '../item-page/simple/field-components/specific-field/title/themed-item-page-field.component'; import { BitstreamListItemComponent } from './object-list/bitstream-list-item/bitstream-list-item.component'; import { NgxPaginationModule } from 'ngx-pagination'; +import { LiveRegionComponent } from './live-region/live-region.component'; const MODULES = [ CommonModule, @@ -465,7 +466,8 @@ const ENTRY_COMPONENTS = [ AdvancedClaimedTaskActionRatingComponent, EpersonGroupListComponent, EpersonSearchBoxComponent, - GroupSearchBoxComponent + GroupSearchBoxComponent, + LiveRegionComponent, ]; const PROVIDERS = [ diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index 84a30549a72..aa3033ecec3 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -22,6 +22,7 @@ import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; +import { LiveRegionConfig } from '../app/shared/live-region/live-region.config'; interface AppConfig extends Config { ui: UIServerConfig; @@ -48,6 +49,7 @@ interface AppConfig extends Config { markdown: MarkdownConfig; vocabularies: FilterVocabularyConfig[]; comcolSelectionSort: DiscoverySortConfig; + liveRegion: LiveRegionConfig; } /** diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index a6e9e092e46..1c0f88cf477 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -22,6 +22,7 @@ import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; +import { LiveRegionConfig } from '../app/shared/live-region/live-region.config'; export class DefaultAppConfig implements AppConfig { production = false; @@ -432,4 +433,10 @@ export class DefaultAppConfig implements AppConfig { sortField:'dc.title', sortDirection:'ASC', }; + + // Live Region configuration, used by the LiveRegionService + liveRegion: LiveRegionConfig = { + messageTimeOutDurationMs: 30000, + isVisible: false, + }; } diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index cb9d2c71303..498799a454b 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -313,5 +313,10 @@ export const environment: BuildConfig = { vocabulary: 'srsc', enabled: true } - ] + ], + + liveRegion: { + messageTimeOutDurationMs: 30000, + isVisible: false, + }, }; diff --git a/src/styles/_custom_variables.scss b/src/styles/_custom_variables.scss index ddf490c7a7a..09267d15aef 100644 --- a/src/styles/_custom_variables.scss +++ b/src/styles/_custom_variables.scss @@ -13,6 +13,7 @@ --ds-login-logo-width:72px; --ds-submission-header-z-index: 1001; --ds-submission-footer-z-index: 999; + --ds-live-region-z-index: 1030; --ds-main-z-index: 1; --ds-nav-z-index: 10; From e987c35450f2a03e73fe5a9951ec412fb9675e33 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 17 Sep 2024 09:07:02 +0200 Subject: [PATCH 077/822] 118220: Add liveRegionComponent & Service tests --- .../live-region/live-region.component.spec.ts | 57 +++++++ .../live-region/live-region.service.spec.ts | 140 ++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 src/app/shared/live-region/live-region.component.spec.ts create mode 100644 src/app/shared/live-region/live-region.service.spec.ts diff --git a/src/app/shared/live-region/live-region.component.spec.ts b/src/app/shared/live-region/live-region.component.spec.ts new file mode 100644 index 00000000000..2e9797f9c38 --- /dev/null +++ b/src/app/shared/live-region/live-region.component.spec.ts @@ -0,0 +1,57 @@ +import { LiveRegionComponent } from './live-region.component'; +import { ComponentFixture, waitForAsync, TestBed } from '@angular/core/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { LiveRegionService } from './live-region.service'; +import { of } from 'rxjs'; +import { By } from '@angular/platform-browser'; + +describe('liveRegionComponent', () => { + let fixture: ComponentFixture; + let liveRegionService: LiveRegionService; + + beforeEach(waitForAsync(() => { + liveRegionService = jasmine.createSpyObj('liveRegionService', { + getMessages$: of(['message1', 'message2']), + getLiveRegionVisibility: false, + setLiveRegionVisibility: undefined, + }); + + void TestBed.configureTestingModule({ + imports: [ + TranslateModule.forRoot(), + ], + declarations: [LiveRegionComponent], + providers: [ + { provide: LiveRegionService, useValue: liveRegionService }, + ], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LiveRegionComponent); + fixture.detectChanges(); + }); + + it('should contain the current live region messages', () => { + const messages = fixture.debugElement.queryAll(By.css('.live-region-message')); + + expect(messages.length).toEqual(2); + expect(messages[0].nativeElement.textContent).toEqual('message1'); + expect(messages[1].nativeElement.textContent).toEqual('message2'); + }); + + it('should respect the live region visibility', () => { + const liveRegion = fixture.debugElement.query(By.css('.live-region')); + expect(liveRegion).toBeDefined(); + + const liveRegionHidden = fixture.debugElement.query(By.css('.visually-hidden')); + expect(liveRegionHidden).toBeDefined(); + + liveRegionService.getLiveRegionVisibility = jasmine.createSpy('getLiveRegionVisibility').and.returnValue(true); + fixture = TestBed.createComponent(LiveRegionComponent); + fixture.detectChanges(); + + const liveRegionVisible = fixture.debugElement.query(By.css('.visually-hidden')); + expect(liveRegionVisible).toBeNull(); + }); +}); diff --git a/src/app/shared/live-region/live-region.service.spec.ts b/src/app/shared/live-region/live-region.service.spec.ts new file mode 100644 index 00000000000..fe5e8b8d8c5 --- /dev/null +++ b/src/app/shared/live-region/live-region.service.spec.ts @@ -0,0 +1,140 @@ +import { LiveRegionService } from './live-region.service'; +import { fakeAsync, tick, flush } from '@angular/core/testing'; + +describe('liveRegionService', () => { + let service: LiveRegionService; + + + beforeEach(() => { + service = new LiveRegionService(); + }); + + describe('addMessage', () => { + it('should correctly add messages', () => { + expect(service.getMessages().length).toEqual(0); + + service.addMessage('Message One'); + expect(service.getMessages().length).toEqual(1); + expect(service.getMessages()[0]).toEqual('Message One'); + + service.addMessage('Message Two'); + expect(service.getMessages().length).toEqual(2); + expect(service.getMessages()[1]).toEqual('Message Two'); + }); + }); + + describe('clearMessages', () => { + it('should clear the messages', () => { + expect(service.getMessages().length).toEqual(0); + + service.addMessage('Message One'); + service.addMessage('Message Two'); + expect(service.getMessages().length).toEqual(2); + + service.clear(); + expect(service.getMessages().length).toEqual(0); + }); + }); + + describe('messages$', () => { + it('should emit when a message is added and when a message is removed after the timeOut', fakeAsync(() => { + const results: string[][] = []; + + service.getMessages$().subscribe((messages) => { + results.push(messages); + }); + + expect(results.length).toEqual(1); + expect(results[0]).toEqual([]); + + service.addMessage('message'); + + tick(); + + expect(results.length).toEqual(2); + expect(results[1]).toEqual(['message']); + + tick(service.getMessageTimeOutMs()); + + expect(results.length).toEqual(3); + expect(results[2]).toEqual([]); + })); + + it('should only emit once when the messages are cleared', fakeAsync(() => { + const results: string[][] = []; + + service.getMessages$().subscribe((messages) => { + results.push(messages); + }); + + expect(results.length).toEqual(1); + expect(results[0]).toEqual([]); + + service.addMessage('Message One'); + service.addMessage('Message Two'); + + tick(); + + expect(results.length).toEqual(3); + expect(results[2]).toEqual(['Message One', 'Message Two']); + + service.clear(); + flush(); + + expect(results.length).toEqual(4); + expect(results[3]).toEqual([]); + })); + + it('should respect configured timeOut', fakeAsync(() => { + const results: string[][] = []; + + service.getMessages$().subscribe((messages) => { + results.push(messages); + }); + + expect(results.length).toEqual(1); + expect(results[0]).toEqual([]); + + const timeOutMs = 500; + service.setMessageTimeOutMs(timeOutMs); + + service.addMessage('Message One'); + tick(timeOutMs - 1); + + expect(results.length).toEqual(2); + expect(results[1]).toEqual(['Message One']); + + tick(1); + + expect(results.length).toEqual(3); + expect(results[2]).toEqual([]); + + const timeOutMsTwo = 50000; + service.setMessageTimeOutMs(timeOutMsTwo); + + service.addMessage('Message Two'); + tick(timeOutMsTwo - 1); + + expect(results.length).toEqual(4); + expect(results[3]).toEqual(['Message Two']); + + tick(1); + + expect(results.length).toEqual(5); + expect(results[4]).toEqual([]); + })); + }); + + describe('liveRegionVisibility', () => { + it('should be false by default', () => { + expect(service.getLiveRegionVisibility()).toBeFalse(); + }); + + it('should correctly update', () => { + service.setLiveRegionVisibility(true); + expect(service.getLiveRegionVisibility()).toBeTrue(); + service.setLiveRegionVisibility(false); + expect(service.getLiveRegionVisibility()).toBeFalse(); + }); + }); +}); From 35d29c84258e1656ed17c53e6e7054c69b7878d1 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 20 Sep 2024 09:38:31 +0200 Subject: [PATCH 078/822] 118220: Add LiveRegion to RootComponent --- src/app/root/root.component.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/root/root.component.html b/src/app/root/root.component.html index bf49e507c0b..d59bea1db42 100644 --- a/src/app/root/root.component.html +++ b/src/app/root/root.component.html @@ -27,3 +27,5 @@
+ + From 2380d4e751563181b341c5a225bae5a9be40d7e3 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Fri, 20 Sep 2024 16:45:05 +0200 Subject: [PATCH 079/822] fix bug in lint rule, add docs for rule and update name so it's clear this is only for buttons currently --- .eslintrc.json | 2 +- docs/lint/html/index.md | 1 + lint/src/rules/html/index.ts | 4 ++-- ...attr.ts => no-disabled-attribute-on-button.ts} | 15 +++++++++------ 4 files changed, 13 insertions(+), 9 deletions(-) rename lint/src/rules/html/{no-disabled-attr.ts => no-disabled-attribute-on-button.ts} (89%) diff --git a/.eslintrc.json b/.eslintrc.json index a9e44c59374..888c968b5c6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -294,7 +294,7 @@ "rules": { // Custom DSpace Angular rules "dspace-angular-html/themed-component-usages": "error", - "dspace-angular-html/no-disabled-attr": "error" + "dspace-angular-html/no-disabled-attribute-on-button": "error" } }, { diff --git a/docs/lint/html/index.md b/docs/lint/html/index.md index 15d693843c0..e134e1070f4 100644 --- a/docs/lint/html/index.md +++ b/docs/lint/html/index.md @@ -2,3 +2,4 @@ _______ - [`dspace-angular-html/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via the selector of their `ThemedComponent` wrapper class +- [`dspace-angular-html/no-disabled-attribute-on-button`](./rules/no-disabled-attribute-on-button.md): Buttons should use the `dsBtnDisabled` directive instead of the HTML `disabled` attribute. diff --git a/lint/src/rules/html/index.ts b/lint/src/rules/html/index.ts index 120751d65aa..3d425c3ad48 100644 --- a/lint/src/rules/html/index.ts +++ b/lint/src/rules/html/index.ts @@ -10,12 +10,12 @@ import { bundle, RuleExports, } from '../../util/structure'; -import * as noDisabledAttr from './no-disabled-attr'; +import * as noDisabledAttributeOnButton from './no-disabled-attribute-on-button'; import * as themedComponentUsages from './themed-component-usages'; const index = [ themedComponentUsages, - noDisabledAttr, + noDisabledAttributeOnButton, ] as unknown as RuleExports[]; diff --git a/lint/src/rules/html/no-disabled-attr.ts b/lint/src/rules/html/no-disabled-attribute-on-button.ts similarity index 89% rename from lint/src/rules/html/no-disabled-attr.ts rename to lint/src/rules/html/no-disabled-attribute-on-button.ts index 22f987d52b9..bf1a72d70d0 100644 --- a/lint/src/rules/html/no-disabled-attr.ts +++ b/lint/src/rules/html/no-disabled-attribute-on-button.ts @@ -1,12 +1,13 @@ import { TmplAstBoundAttribute, - TmplAstTextAttribute + TmplAstTextAttribute, } from '@angular-eslint/bundled-angular-compiler'; import { TemplateParserServices } from '@angular-eslint/utils'; import { ESLintUtils, TSESLint, } from '@typescript-eslint/utils'; + import { DSpaceESLintRuleInfo, NamedTests, @@ -18,10 +19,12 @@ export enum Message { } export const info = { - name: 'no-disabled-attr', + name: 'no-disabled-attribute-on-button', meta: { docs: { - description: `Buttons should use the \`dsBtnDisabled\` directive instead of the HTML \`disabled\` attribute for accessibility reasons.`, + description: `Buttons should use the \`dsBtnDisabled\` directive instead of the HTML \`disabled\` attribute. + This should be done to ensure that users with a screen reader are able to understand that the a button button is present, and that it is disabled. + The native html disabled attribute does not allow users to navigate to the button by keyboard, and thus they have no way of knowing that the button is present.`, }, type: 'problem', fixable: 'code', @@ -52,7 +55,7 @@ export const rule = ESLintUtils.RuleCreator.withoutDocs({ */ function replaceDisabledText(text: string ): string { const hasBrackets = text.includes('[') && text.includes(']'); - const newDisabledText = hasBrackets ? 'dsBtnDisabled' : '[dsBtnDisabled]'; + const newDisabledText = hasBrackets ? 'dsBtnDisabled' : '[dsBtnDisabled]="true"'; return text.replace('disabled', newDisabledText); } @@ -101,7 +104,7 @@ export const tests = { { name: 'disabled attribute is still valid on non-button elements', code: ` - + `, }, { @@ -121,7 +124,7 @@ export const tests = { { name: 'should not use disabled attribute in HTML templates', code: ` - + `, errors: [{ messageId: Message.USE_DSBTN_DISABLED }], output: ` From e6a02bcbea39f44211d6bcf6d5b95be76498cf30 Mon Sep 17 00:00:00 2001 From: Andrea Barbasso <´andrea.barbasso@4science.com´> Date: Mon, 23 Sep 2024 18:15:39 +0200 Subject: [PATCH 080/822] [CST-15077] add orcid icon with tooltip --- ...-item-metadata-list-element.component.html | 5 ++ ...on-item-metadata-list-element.component.ts | 3 +- .../orcid-badge-and-tooltip.component.html | 11 +++ .../orcid-badge-and-tooltip.component.scss | 11 +++ .../orcid-badge-and-tooltip.component.spec.ts | 71 +++++++++++++++++++ .../orcid-badge-and-tooltip.component.ts | 65 +++++++++++++++++ src/assets/i18n/en.json5 | 4 ++ 7 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html create mode 100644 src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss create mode 100644 src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts create mode 100644 src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts diff --git a/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.html b/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.html index 6f560567814..f61c14d3ba1 100644 --- a/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.html +++ b/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.html @@ -12,4 +12,9 @@ + + diff --git a/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.ts b/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.ts index 48957a6cbdc..c7b9e1a3332 100644 --- a/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.ts +++ b/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.ts @@ -7,13 +7,14 @@ import { RouterLink } from '@angular/router'; import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; import { ItemMetadataRepresentationListElementComponent } from '../../../../shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component'; +import { OrcidBadgeAndTooltipComponent } from '../../../../shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component'; import { TruncatableComponent } from '../../../../shared/truncatable/truncatable.component'; @Component({ selector: 'ds-person-item-metadata-list-element', templateUrl: './person-item-metadata-list-element.component.html', standalone: true, - imports: [NgIf, NgFor, TruncatableComponent, RouterLink, NgbTooltipModule], + imports: [NgIf, NgFor, TruncatableComponent, RouterLink, NgbTooltipModule, OrcidBadgeAndTooltipComponent], }) /** * The component for displaying an item of the type Person as a metadata field diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html new file mode 100644 index 00000000000..fc34aee9705 --- /dev/null +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html @@ -0,0 +1,11 @@ +orcid-logo + + + {{ orcidTooltip }} + diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss new file mode 100644 index 00000000000..6a1c259e18a --- /dev/null +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss @@ -0,0 +1,11 @@ +:host { + display: inline-block; +} + +.orcid-icon { + height: 1.2rem; + + &.not-authenticated { + filter: grayscale(100%); + } +} diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts new file mode 100644 index 00000000000..dd47fd918bb --- /dev/null +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts @@ -0,0 +1,71 @@ +import { + NgClass, + NgIf, +} from '@angular/common'; +import { + ComponentFixture, + TestBed, +} from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateService } from '@ngx-translate/core'; + +import { MetadataValue } from '../../core/shared/metadata.models'; +import { OrcidBadgeAndTooltipComponent } from './orcid-badge-and-tooltip.component'; + +describe('OrcidBadgeAndTooltipComponent', () => { + let component: OrcidBadgeAndTooltipComponent; + let fixture: ComponentFixture; + let translateService: TranslateService; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + OrcidBadgeAndTooltipComponent, + NgbTooltipModule, + NgClass, + NgIf, + ], + providers: [ + { provide: TranslateService, useValue: { instant: (key: string) => key } }, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(OrcidBadgeAndTooltipComponent); + component = fixture.componentInstance; + translateService = TestBed.inject(TranslateService); + + component.orcid = { value: '0000-0002-1825-0097' } as MetadataValue; + component.authenticatedTimestamp = { value: '2023-10-01' } as MetadataValue; + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should set orcidTooltip when authenticatedTimestamp is provided', () => { + component.ngOnInit(); + expect(component.orcidTooltip).toBe('person.orcid-tooltip.authenticated'); + }); + + it('should set orcidTooltip when authenticatedTimestamp is not provided', () => { + component.authenticatedTimestamp = null; + component.ngOnInit(); + expect(component.orcidTooltip).toBe('person.orcid-tooltip.not-authenticated'); + }); + + it('should display the ORCID icon', () => { + const badgeIcon = fixture.debugElement.query(By.css('img[data-test="orcidIcon"]')); + expect(badgeIcon).toBeTruthy(); + }); + + it('should display the ORCID icon in greyscale if there is no authenticated timestamp', () => { + component.authenticatedTimestamp = null; + fixture.detectChanges(); + const badgeIcon = fixture.debugElement.query(By.css('img[data-test="orcidIcon"]')); + expect(badgeIcon.nativeElement.classList).toContain('not-authenticated'); + }); + +}); diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts new file mode 100644 index 00000000000..6e8ba7100f3 --- /dev/null +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts @@ -0,0 +1,65 @@ +import { + NgClass, + NgIf, +} from '@angular/common'; +import { + Component, + Input, + OnInit, +} from '@angular/core'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateService } from '@ngx-translate/core'; + +import { MetadataValue } from '../../core/shared/metadata.models'; + +/** + * Component to display an ORCID badge with a tooltip. + * The tooltip text changes based on whether the ORCID is authenticated. + */ +@Component({ + selector: 'ds-orcid-badge-and-tooltip', + standalone: true, + imports: [ + NgIf, + NgbTooltipModule, + NgClass, + ], + templateUrl: './orcid-badge-and-tooltip.component.html', + styleUrl: './orcid-badge-and-tooltip.component.scss', +}) +export class OrcidBadgeAndTooltipComponent implements OnInit { + + /** + * The ORCID value to be displayed. + */ + @Input() orcid: MetadataValue; + + /** + * The timestamp indicating when the ORCID was authenticated. + */ + @Input() authenticatedTimestamp: MetadataValue; + + /** + * The tooltip text to be displayed. + */ + orcidTooltip: string; + + /** + * Constructor to inject the TranslateService. + * @param translateService - Service for translation. + */ + constructor( + private translateService: TranslateService, + ) { } + + /** + * Initializes the component. + * Sets the tooltip text based on the presence of the authenticated timestamp. + */ + ngOnInit() { + this.orcidTooltip = this.authenticatedTimestamp ? + this.translateService.instant('person.orcid-tooltip.authenticated', { orcid: this.orcid.value }) : + this.translateService.instant('person.orcid-tooltip.not-authenticated', { orcid: this.orcid.value }); + } + +} diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 8f20c657f94..7ae8985fbe9 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5980,6 +5980,10 @@ "person.orcid.registry.auth": "ORCID Authorizations", + "person.orcid-tooltip.authenticated": "{{orcid}}", + + "person.orcid-tooltip.not-authenticated": "{{orcid}} (unconfirmed)", + "home.recent-submissions.head": "Recent Submissions", "listable-notification-object.default-message": "This object couldn't be retrieved", From cd51baa5f1ee5d8fa66e8ee94beb3168f93c5c01 Mon Sep 17 00:00:00 2001 From: Andrea Barbasso <´andrea.barbasso@4science.com´> Date: Mon, 23 Sep 2024 18:15:39 +0200 Subject: [PATCH 081/822] [CST-14904] add orcid icon with tooltip --- ...-item-metadata-list-element.component.html | 5 ++ .../orcid-badge-and-tooltip.component.html | 11 +++ .../orcid-badge-and-tooltip.component.scss | 11 +++ .../orcid-badge-and-tooltip.component.spec.ts | 71 +++++++++++++++++++ .../orcid-badge-and-tooltip.component.ts | 56 +++++++++++++++ src/app/shared/shared.module.ts | 2 + src/assets/i18n/en.json5 | 4 ++ 7 files changed, 160 insertions(+) create mode 100644 src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html create mode 100644 src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss create mode 100644 src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts create mode 100644 src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts diff --git a/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.html b/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.html index 6f560567814..f61c14d3ba1 100644 --- a/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.html +++ b/src/app/entity-groups/research-entities/metadata-representations/person/person-item-metadata-list-element.component.html @@ -12,4 +12,9 @@ + + diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html new file mode 100644 index 00000000000..fc34aee9705 --- /dev/null +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.html @@ -0,0 +1,11 @@ +orcid-logo + + + {{ orcidTooltip }} + diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss new file mode 100644 index 00000000000..6a1c259e18a --- /dev/null +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.scss @@ -0,0 +1,11 @@ +:host { + display: inline-block; +} + +.orcid-icon { + height: 1.2rem; + + &.not-authenticated { + filter: grayscale(100%); + } +} diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts new file mode 100644 index 00000000000..adb3c91f941 --- /dev/null +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.spec.ts @@ -0,0 +1,71 @@ +import { + NgClass, + NgIf, +} from '@angular/common'; +import { + ComponentFixture, + TestBed, +} from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateService } from '@ngx-translate/core'; + +import { MetadataValue } from '../../core/shared/metadata.models'; +import { OrcidBadgeAndTooltipComponent } from './orcid-badge-and-tooltip.component'; + +describe('OrcidBadgeAndTooltipComponent', () => { + let component: OrcidBadgeAndTooltipComponent; + let fixture: ComponentFixture; + let translateService: TranslateService; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [OrcidBadgeAndTooltipComponent], + imports: [ + NgbTooltipModule, + NgClass, + NgIf, + ], + providers: [ + { provide: TranslateService, useValue: { instant: (key: string) => key } }, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(OrcidBadgeAndTooltipComponent); + component = fixture.componentInstance; + translateService = TestBed.inject(TranslateService); + + component.orcid = { value: '0000-0002-1825-0097' } as MetadataValue; + component.authenticatedTimestamp = { value: '2023-10-01' } as MetadataValue; + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should set orcidTooltip when authenticatedTimestamp is provided', () => { + component.ngOnInit(); + expect(component.orcidTooltip).toBe('person.orcid-tooltip.authenticated'); + }); + + it('should set orcidTooltip when authenticatedTimestamp is not provided', () => { + component.authenticatedTimestamp = null; + component.ngOnInit(); + expect(component.orcidTooltip).toBe('person.orcid-tooltip.not-authenticated'); + }); + + it('should display the ORCID icon', () => { + const badgeIcon = fixture.debugElement.query(By.css('img[data-test="orcidIcon"]')); + expect(badgeIcon).toBeTruthy(); + }); + + it('should display the ORCID icon in greyscale if there is no authenticated timestamp', () => { + component.authenticatedTimestamp = null; + fixture.detectChanges(); + const badgeIcon = fixture.debugElement.query(By.css('img[data-test="orcidIcon"]')); + expect(badgeIcon.nativeElement.classList).toContain('not-authenticated'); + }); + +}); diff --git a/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts new file mode 100644 index 00000000000..1939bad57f3 --- /dev/null +++ b/src/app/shared/orcid-badge-and-tooltip/orcid-badge-and-tooltip.component.ts @@ -0,0 +1,56 @@ + + +import { + Component, + Input, + OnInit, +} from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; + +import { MetadataValue } from '../../core/shared/metadata.models'; + +/** + * Component to display an ORCID badge with a tooltip. + * The tooltip text changes based on whether the ORCID is authenticated. + */ +@Component({ + selector: 'ds-orcid-badge-and-tooltip', + templateUrl: './orcid-badge-and-tooltip.component.html', + styleUrls: ['./orcid-badge-and-tooltip.component.scss'], +}) +export class OrcidBadgeAndTooltipComponent implements OnInit { + + /** + * The ORCID value to be displayed. + */ + @Input() orcid: MetadataValue; + + /** + * The timestamp indicating when the ORCID was authenticated. + */ + @Input() authenticatedTimestamp: MetadataValue; + + /** + * The tooltip text to be displayed. + */ + orcidTooltip: string; + + /** + * Constructor to inject the TranslateService. + * @param translateService - Service for translation. + */ + constructor( + private translateService: TranslateService, + ) { } + + /** + * Initializes the component. + * Sets the tooltip text based on the presence of the authenticated timestamp. + */ + ngOnInit() { + this.orcidTooltip = this.authenticatedTimestamp ? + this.translateService.instant('person.orcid-tooltip.authenticated', { orcid: this.orcid.value }) : + this.translateService.instant('person.orcid-tooltip.not-authenticated', { orcid: this.orcid.value }); + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 9f05b1d3706..d6b6e861ce1 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -284,6 +284,7 @@ import { BitstreamListItemComponent } from './object-list/bitstream-list-item/bi import { NgxPaginationModule } from 'ngx-pagination'; import { ThemedLangSwitchComponent } from './lang-switch/themed-lang-switch.component'; import {ThemedUserMenuComponent} from './auth-nav-menu/user-menu/themed-user-menu.component'; +import { OrcidBadgeAndTooltipComponent } from './orcid-badge-and-tooltip/orcid-badge-and-tooltip.component'; const MODULES = [ CommonModule, @@ -404,6 +405,7 @@ const COMPONENTS = [ EpersonSearchBoxComponent, GroupSearchBoxComponent, ThemedItemPageTitleFieldComponent, + OrcidBadgeAndTooltipComponent, ]; const ENTRY_COMPONENTS = [ diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 0a1804fa5c3..3f85e8b687a 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5248,6 +5248,10 @@ "person.orcid.registry.auth": "ORCID Authorizations", + "person.orcid-tooltip.authenticated": "{{orcid}}", + + "person.orcid-tooltip.not-authenticated": "{{orcid}} (unconfirmed)", + "home.recent-submissions.head": "Recent Submissions", "listable-notification-object.default-message": "This object couldn't be retrieved", From e45b6af26dc8faf25774951fe9e3309fda46b3c1 Mon Sep 17 00:00:00 2001 From: nwoodward Date: Tue, 24 Sep 2024 09:46:58 -0500 Subject: [PATCH 082/822] updates isbot dependency to newest version --- package.json | 2 +- server.ts | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 82822316aa4..75c40857bc9 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "filesize": "^6.1.0", "http-proxy-middleware": "^1.0.5", "http-terminator": "^3.2.0", - "isbot": "^3.6.10", + "isbot": "^5.1.17", "js-cookie": "2.2.1", "js-yaml": "^4.1.0", "json5": "^2.2.3", diff --git a/server.ts b/server.ts index 22f34232874..032b79b8f25 100644 --- a/server.ts +++ b/server.ts @@ -27,7 +27,7 @@ import * as expressStaticGzip from 'express-static-gzip'; /* eslint-enable import/no-namespace */ import axios from 'axios'; import LRU from 'lru-cache'; -import isbot from 'isbot'; +import { isbot } from 'isbot'; import { createCertificate } from 'pem'; import { createServer } from 'https'; import { json } from 'body-parser'; diff --git a/yarn.lock b/yarn.lock index d923560e565..f42bb504fd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7282,10 +7282,10 @@ isbinaryfile@^4.0.8: resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== -isbot@^3.6.10: - version "3.8.0" - resolved "https://registry.yarnpkg.com/isbot/-/isbot-3.8.0.tgz#b1f8e3d19aca0961b5ed27b62bb8bb0a275781e4" - integrity sha512-vne1mzQUTR+qsMLeCBL9+/tgnDXRyc2pygLGl/WsgA+EZKIiB5Ehu0CiVTHIIk30zhJ24uGz4M5Ppse37aR0Hg== +isbot@^5.1.17: + version "5.1.17" + resolved "https://registry.yarnpkg.com/isbot/-/isbot-5.1.17.tgz#ad7da5690a61bbb19056a069975c9a73182682a0" + integrity sha512-/wch8pRKZE+aoVhRX/hYPY1C7dMCeeMyhkQLNLNlYAbGQn9bkvMB8fOUXNnk5I0m4vDYbBJ9ciVtkr9zfBJ7qA== isexe@^2.0.0: version "2.0.0" From 35946dcf7cefdaafb70a2ee5ee02a2b53c7e8817 Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Wed, 25 Sep 2024 08:13:21 +0300 Subject: [PATCH 083/822] Update isbot dependency Note that the minimum supported Node.js version is now v18, as v16 is now end of life. --- package.json | 2 +- server.ts | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 86959196d0e..78f0cc98872 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "filesize": "^6.1.0", "http-proxy-middleware": "^1.0.5", "http-terminator": "^3.2.0", - "isbot": "^3.6.10", + "isbot": "^5.1.17", "js-cookie": "2.2.1", "js-yaml": "^4.1.0", "json5": "^2.2.3", diff --git a/server.ts b/server.ts index 93f3e868763..23d29723c69 100644 --- a/server.ts +++ b/server.ts @@ -28,7 +28,7 @@ import * as expressStaticGzip from 'express-static-gzip'; /* eslint-enable import/no-namespace */ import axios from 'axios'; import LRU from 'lru-cache'; -import isbot from 'isbot'; +import { isbot } from 'isbot'; import { createCertificate } from 'pem'; import { createServer } from 'https'; import { json } from 'body-parser'; diff --git a/yarn.lock b/yarn.lock index efc65983c6e..2a4fd40b5aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7188,10 +7188,10 @@ isbinaryfile@^4.0.8: resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== -isbot@^3.6.10: - version "3.6.10" - resolved "https://registry.yarnpkg.com/isbot/-/isbot-3.6.10.tgz#7b66334e81794f0461794debb567975cf08eaf2b" - integrity sha512-+I+2998oyP4oW9+OTQD8TS1r9P6wv10yejukj+Ksj3+UR5pUhsZN3f8W7ysq0p1qxpOVNbl5mCuv0bCaF8y5iQ== +isbot@^5.1.17: + version "5.1.17" + resolved "https://registry.yarnpkg.com/isbot/-/isbot-5.1.17.tgz#ad7da5690a61bbb19056a069975c9a73182682a0" + integrity sha512-/wch8pRKZE+aoVhRX/hYPY1C7dMCeeMyhkQLNLNlYAbGQn9bkvMB8fOUXNnk5I0m4vDYbBJ9ciVtkr9zfBJ7qA== isexe@^2.0.0: version "2.0.0" From 29c1b510733a6081fb5bfa09a5c8f7c0c25de300 Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Wed, 25 Sep 2024 08:34:04 +0300 Subject: [PATCH 084/822] .github/workflows/build.yml: use Node.js v18 and v20 Node.js v16 LTS is end of life since October, 2023. See: https://nodejs.org/en/about/previous-releases --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 50b260b59ef..f6ffa5e004b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: strategy: # Create a matrix of Node versions to test against (in parallel) matrix: - node-version: [16.x, 18.x] + node-version: [18.x, 20.x] # Do NOT exit immediately if one matrix job fails fail-fast: false # These are the actual CI steps to perform per job From c1fa52ee64e7c50f38c0e671aa13757bc7a4c024 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 25 Sep 2024 09:50:33 +0200 Subject: [PATCH 085/822] 118220: Store messages with ID so clears can be targeted --- .../live-region/live-region.service.spec.ts | 34 +++++++++++++++- .../shared/live-region/live-region.service.ts | 39 ++++++++++++------- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/app/shared/live-region/live-region.service.spec.ts b/src/app/shared/live-region/live-region.service.spec.ts index fe5e8b8d8c5..858ef883134 100644 --- a/src/app/shared/live-region/live-region.service.spec.ts +++ b/src/app/shared/live-region/live-region.service.spec.ts @@ -1,12 +1,14 @@ import { LiveRegionService } from './live-region.service'; import { fakeAsync, tick, flush } from '@angular/core/testing'; +import { UUIDService } from '../../core/shared/uuid.service'; describe('liveRegionService', () => { let service: LiveRegionService; - beforeEach(() => { - service = new LiveRegionService(); + service = new LiveRegionService( + new UUIDService(), + ); }); describe('addMessage', () => { @@ -85,6 +87,34 @@ describe('liveRegionService', () => { expect(results[3]).toEqual([]); })); + it('should not pop messages added after clearing within timeOut period', fakeAsync(() => { + const results: string[][] = []; + + service.getMessages$().subscribe((messages) => { + results.push(messages); + }); + + expect(results.length).toEqual(1); + expect(results[0]).toEqual([]); + + service.addMessage('Message One'); + tick(10000); + service.clear(); + tick(15000); + service.addMessage('Message Two'); + + // Message Two should not be cleared after 5 more seconds + tick(5000); + + expect(results.length).toEqual(4); + expect(results[3]).toEqual(['Message Two']); + + // But should be cleared 30 seconds after it was added + tick(25000); + expect(results.length).toEqual(5); + expect(results[4]).toEqual([]); + })); + it('should respect configured timeOut', fakeAsync(() => { const results: string[][] = []; diff --git a/src/app/shared/live-region/live-region.service.ts b/src/app/shared/live-region/live-region.service.ts index 482d1ca1bbf..d89d72a9675 100644 --- a/src/app/shared/live-region/live-region.service.ts +++ b/src/app/shared/live-region/live-region.service.ts @@ -1,12 +1,18 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { environment } from '../../../environments/environment'; +import { UUIDService } from '../../core/shared/uuid.service'; @Injectable({ providedIn: 'root', }) export class LiveRegionService { + constructor( + protected uuidService: UUIDService, + ) { + } + /** * The duration after which the messages disappear in milliseconds * @protected @@ -14,10 +20,11 @@ export class LiveRegionService { protected messageTimeOutDurationMs: number = environment.liveRegion.messageTimeOutDurationMs; /** - * Array containing the messages that should be shown in the live region + * Array containing the messages that should be shown in the live region, + * together with a uuid, so they can be uniquely identified * @protected */ - protected messages: string[] = []; + protected messages: { message: string, uuid: string }[] = []; /** * BehaviorSubject emitting the array with messages every time the array updates @@ -34,27 +41,28 @@ export class LiveRegionService { /** * Returns a copy of the array with the current live region messages */ - getMessages() { - return [...this.messages]; + getMessages(): string[] { + return this.messages.map(messageObj => messageObj.message); } /** * Returns the BehaviorSubject emitting the array with messages every time the array updates */ - getMessages$() { + getMessages$(): BehaviorSubject { return this.messages$; } /** * Adds a message to the live-region messages array * @param message + * @return The uuid of the message */ - addMessage(message: string) { - this.messages.push(message); + addMessage(message: string): string { + const uuid = this.uuidService.generate(); + this.messages.push({ message, uuid }); + setTimeout(() => this.clearMessageByUUID(uuid), this.messageTimeOutDurationMs); this.emitCurrentMessages(); - - // Clear the message once the timeOut has passed - setTimeout(() => this.pop(), this.messageTimeOutDurationMs); + return uuid; } /** @@ -66,12 +74,15 @@ export class LiveRegionService { } /** - * Removes the longest living message from the array. + * Removes the message with the given UUID from the messages array + * @param uuid The uuid of the message to clear * @protected */ - protected pop() { - if (this.messages.length > 0) { - this.messages.shift(); + clearMessageByUUID(uuid: string) { + const index = this.messages.findIndex(messageObj => messageObj.uuid === uuid); + + if (index !== -1) { + this.messages.splice(index, 1); this.emitCurrentMessages(); } } From 8a5181a9a32df05fc52022244b34a525768fea7c Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Wed, 25 Sep 2024 14:55:37 +0200 Subject: [PATCH 086/822] documentation file --- .../rules/no-disabled-attribute-on-button.md | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 docs/lint/html/rules/no-disabled-attribute-on-button.md diff --git a/docs/lint/html/rules/no-disabled-attribute-on-button.md b/docs/lint/html/rules/no-disabled-attribute-on-button.md new file mode 100644 index 00000000000..d9d39ce82ca --- /dev/null +++ b/docs/lint/html/rules/no-disabled-attribute-on-button.md @@ -0,0 +1,78 @@ +[DSpace ESLint plugins](../../../../lint/README.md) > [HTML rules](../index.md) > `dspace-angular-html/no-disabled-attribute-on-button` +_______ + +Buttons should use the `dsBtnDisabled` directive instead of the HTML `disabled` attribute. + This should be done to ensure that users with a screen reader are able to understand that the a button button is present, and that it is disabled. + The native html disabled attribute does not allow users to navigate to the button by keyboard, and thus they have no way of knowing that the button is present. + +_______ + +[Source code](../../../../lint/src/rules/html/no-disabled-attribute-on-button.ts) + +### Examples + + +#### Valid code + +##### should use [dsBtnDisabled] in HTML templates + +```html + +``` + +##### disabled attribute is still valid on non-button elements + +```html + +``` + +##### [disabled] attribute is still valid on non-button elements + +```html + +``` + +##### angular dynamic attributes that use disabled are still valid + +```html + +``` + + + + +#### Invalid code & automatic fixes + +##### should not use disabled attribute in HTML templates + +```html + +``` +Will produce the following error(s): +``` +Buttons should use the `dsBtnDisabled` directive instead of the `disabled` attribute. +``` + +Result of `yarn lint --fix`: +```html + +``` + + +##### should not use [disabled] attribute in HTML templates + +```html + +``` +Will produce the following error(s): +``` +Buttons should use the `dsBtnDisabled` directive instead of the `disabled` attribute. +``` + +Result of `yarn lint --fix`: +```html + +``` + + + From aed97c9dccf5460897f5c24ea9473fa642468c0c Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 26 Jun 2024 14:46:13 +0200 Subject: [PATCH 087/822] added missing German translations (500 error) (cherry picked from commit 5f6b6ef9849e27eaf87e5b8b0f94ccde271d8043) --- src/assets/i18n/de.json5 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 8efda0390e4..d1ac01fe2a3 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -9,8 +9,6 @@ // "401.unauthorized": "unauthorized", "401.unauthorized": "unautorisiert", - - // "403.help": "You don't have permission to access this page. You can use the button below to get back to the home page.", "403.help": "Sie sind nicht berechtigt, auf diese Seite zuzugreifen. Über den Button unten auf der Seite gelangen Sie zurück zur Startseite.", @@ -20,8 +18,6 @@ // "403.forbidden": "forbidden", "403.forbidden": "verboten", - - // "404.help": "We can't find the page you're looking for. The page may have been moved or deleted. You can use the button below to get back to the home page. ", "404.help": "Die Seite konnte nicht gefunden werden. Eventuell wurde sie verschoben oder gelöscht. Über den Button unten auf der Seite gelangen Sie zurück zur Startseite.", @@ -31,6 +27,16 @@ // "404.page-not-found": "page not found", "404.page-not-found": "Seite nicht gefunden", + // "500.page-internal-server-error": "Service unavailable", + "500.page-internal-server-error": "Dienst nicht verfügbar", + + // "500.help": "The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.", + "500.help": "Der Dienst steht momentan nicht zur Verfügung. Bitte versuchen Sie es später noch einmal.", + + // "500.link.home-page": "Take me to the home page", + "500.link.home-page": "Zur Startseite", + + // "admin.access-control.epeople.breadcrumbs": "EPeople", "admin.access-control.epeople.breadcrumbs": "Personen suchen", From 48ec0cdc340ecf472688c6d606c3fb3643456663 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 9 Jul 2024 17:42:49 +0200 Subject: [PATCH 088/822] minor change: added missing periods in German translations (cherry picked from commit e26ab86dd33981ea4a9969b6043449619948a2b8) --- src/assets/i18n/de.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 8efda0390e4..c154ae91c98 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -5143,10 +5143,10 @@ "submission.sections.general.deposit_error_notice": "Beim Einreichen des Items ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal.", // "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", - "submission.sections.general.deposit_success_notice": "Veröffentlichung erfolgreich eingereicht", + "submission.sections.general.deposit_success_notice": "Veröffentlichung erfolgreich eingereicht.", // "submission.sections.general.discard_error_notice": "There was an issue when discarding the item, please try again later.", - "submission.sections.general.discard_error_notice": "Beim Verwerfen der Einreichung ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal", + "submission.sections.general.discard_error_notice": "Beim Verwerfen der Einreichung ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal.", // "submission.sections.general.discard_success_notice": "Submission discarded successfully.", "submission.sections.general.discard_success_notice": "Einreichung erfolgreich verworfen.", From 6b081ee470638d54ca856d6cd9219a715ddcd33c Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 9 Jul 2024 17:42:49 +0200 Subject: [PATCH 089/822] minor change: added missing periods in German translations (cherry picked from commit e26ab86dd33981ea4a9969b6043449619948a2b8) --- src/assets/i18n/de.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index dac2eb4a521..e1ebb489cf1 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -5560,10 +5560,10 @@ "submission.sections.general.deposit_error_notice": "Beim Einreichen des Items ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal.", // "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", - "submission.sections.general.deposit_success_notice": "Veröffentlichung erfolgreich eingereicht", + "submission.sections.general.deposit_success_notice": "Veröffentlichung erfolgreich eingereicht.", // "submission.sections.general.discard_error_notice": "There was an issue when discarding the item, please try again later.", - "submission.sections.general.discard_error_notice": "Beim Verwerfen der Einreichung ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal", + "submission.sections.general.discard_error_notice": "Beim Verwerfen der Einreichung ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal.", // "submission.sections.general.discard_success_notice": "Submission discarded successfully.", "submission.sections.general.discard_success_notice": "Einreichung erfolgreich verworfen.", From edc738ae3964fada0c6628ce1732f047ae24a603 Mon Sep 17 00:00:00 2001 From: Julia Date: Mon, 23 Sep 2024 15:53:55 -0400 Subject: [PATCH 090/822] Update en.json5 - fixed typo for occurred (cherry picked from commit ed5ac47f886fb0e2ad7ef29c2152abcbe414cca1) --- src/assets/i18n/en.json5 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 0a1804fa5c3..d00e16caa0f 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1240,7 +1240,7 @@ "community.edit.notifications.unauthorized": "You do not have privileges to make this change", - "community.edit.notifications.error": "An error occured while editing the community", + "community.edit.notifications.error": "An error occurred while editing the community", "community.edit.return": "Back", @@ -1448,7 +1448,7 @@ "curation.form.submit.error.head": "Running the curation task failed", - "curation.form.submit.error.content": "An error occured when trying to start the curation task.", + "curation.form.submit.error.content": "An error occurred when trying to start the curation task.", "curation.form.submit.error.invalid-handle": "Couldn't determine the handle for this object", @@ -1700,7 +1700,7 @@ "forgot-email.form.error.head": "Error when trying to reset password", - "forgot-email.form.error.content": "An error occured when attempting to reset the password for the account associated with the following email address: {{ email }}", + "forgot-email.form.error.content": "An error occurred when attempting to reset the password for the account associated with the following email address: {{ email }}", "forgot-password.title": "Forgot Password", @@ -3518,7 +3518,7 @@ "register-page.registration.error.head": "Error when trying to register email", - "register-page.registration.error.content": "An error occured when registering the following email address: {{ email }}", + "register-page.registration.error.content": "An error occurred when registering the following email address: {{ email }}", "register-page.registration.error.recaptcha": "Error when trying to authenticate with recaptcha", From c2e9d5453aa1c74526b90a2f00e8e22e45a781c9 Mon Sep 17 00:00:00 2001 From: Julia Date: Mon, 23 Sep 2024 15:53:55 -0400 Subject: [PATCH 091/822] Update en.json5 - fixed typo for occurred (cherry picked from commit ed5ac47f886fb0e2ad7ef29c2152abcbe414cca1) --- src/assets/i18n/en.json5 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 8f20c657f94..17fbf33b4ae 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1460,7 +1460,7 @@ "community.edit.notifications.unauthorized": "You do not have privileges to make this change", - "community.edit.notifications.error": "An error occured while editing the community", + "community.edit.notifications.error": "An error occurred while editing the community", "community.edit.return": "Back", @@ -1670,7 +1670,7 @@ "curation.form.submit.error.head": "Running the curation task failed", - "curation.form.submit.error.content": "An error occured when trying to start the curation task.", + "curation.form.submit.error.content": "An error occurred when trying to start the curation task.", "curation.form.submit.error.invalid-handle": "Couldn't determine the handle for this object", @@ -1932,7 +1932,7 @@ "forgot-email.form.error.head": "Error when trying to reset password", - "forgot-email.form.error.content": "An error occured when attempting to reset the password for the account associated with the following email address: {{ email }}", + "forgot-email.form.error.content": "An error occurred when attempting to reset the password for the account associated with the following email address: {{ email }}", "forgot-password.title": "Forgot Password", @@ -4108,7 +4108,7 @@ "register-page.registration.error.head": "Error when trying to register email", - "register-page.registration.error.content": "An error occured when registering the following email address: {{ email }}", + "register-page.registration.error.content": "An error occurred when registering the following email address: {{ email }}", "register-page.registration.error.recaptcha": "Error when trying to authenticate with recaptcha", From fe7d2a8a7e05bcdb3b63943261ab84cfdd9614d5 Mon Sep 17 00:00:00 2001 From: Elvi Nemiz Date: Sat, 29 Jun 2024 08:14:10 +0800 Subject: [PATCH 092/822] Fix to Mobile navbar hamburger menu for base (custom) theme https://github.com/DSpace/dspace-angular/pull/2444 only fixes the DSpace theme, not the base (and custom) theme. (cherry picked from commit a3b6aef66a81e93f537bf35647be97d14f5b1472) --- src/app/navbar/navbar.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/navbar/navbar.component.scss b/src/app/navbar/navbar.component.scss index b74408f0f59..bbf5feec156 100644 --- a/src/app/navbar/navbar.component.scss +++ b/src/app/navbar/navbar.component.scss @@ -10,7 +10,7 @@ /** Mobile menu styling **/ @media screen and (max-width: map-get($grid-breakpoints, md)-0.02) { .navbar { - width: 100%; + width: 100vw; background-color: var(--bs-white); position: absolute; overflow: hidden; From 0cff856bf5d4e3ad8087491973abf6516db776bc Mon Sep 17 00:00:00 2001 From: Elvi Nemiz Date: Sat, 29 Jun 2024 08:14:10 +0800 Subject: [PATCH 093/822] Fix to Mobile navbar hamburger menu for base (custom) theme https://github.com/DSpace/dspace-angular/pull/2444 only fixes the DSpace theme, not the base (and custom) theme. (cherry picked from commit a3b6aef66a81e93f537bf35647be97d14f5b1472) --- src/app/navbar/navbar.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/navbar/navbar.component.scss b/src/app/navbar/navbar.component.scss index b74408f0f59..bbf5feec156 100644 --- a/src/app/navbar/navbar.component.scss +++ b/src/app/navbar/navbar.component.scss @@ -10,7 +10,7 @@ /** Mobile menu styling **/ @media screen and (max-width: map-get($grid-breakpoints, md)-0.02) { .navbar { - width: 100%; + width: 100vw; background-color: var(--bs-white); position: absolute; overflow: hidden; From 751d689ff65b15fa4f8b2f898d43ecaa682e8085 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 27 Sep 2024 10:02:26 +0200 Subject: [PATCH 094/822] 118220: Add additional TypeDocs --- src/app/shared/live-region/live-region.component.ts | 6 ++++++ src/app/shared/live-region/live-region.service.ts | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app/shared/live-region/live-region.component.ts b/src/app/shared/live-region/live-region.component.ts index d7bd5eb806c..8a25c4657ca 100644 --- a/src/app/shared/live-region/live-region.component.ts +++ b/src/app/shared/live-region/live-region.component.ts @@ -2,6 +2,12 @@ import { Component, OnInit } from '@angular/core'; import { LiveRegionService } from './live-region.service'; import { Observable } from 'rxjs'; +/** + * The Live Region Component is an accessibility tool for screenreaders. When a change occurs on a page when the changed + * section is not in focus, a message should be displayed by this component so it can be announced by a screen reader. + * + * This component should not be used directly. Use the {@link LiveRegionService} to add messages. + */ @Component({ selector: `ds-live-region`, templateUrl: './live-region.component.html', diff --git a/src/app/shared/live-region/live-region.service.ts b/src/app/shared/live-region/live-region.service.ts index d89d72a9675..72940c1a0eb 100644 --- a/src/app/shared/live-region/live-region.service.ts +++ b/src/app/shared/live-region/live-region.service.ts @@ -3,6 +3,10 @@ import { BehaviorSubject } from 'rxjs'; import { environment } from '../../../environments/environment'; import { UUIDService } from '../../core/shared/uuid.service'; +/** + * The LiveRegionService is responsible for handling the messages that are shown by the {@link LiveRegionComponent}. + * Use this service to add or remove messages to the Live Region. + */ @Injectable({ providedIn: 'root', }) @@ -76,7 +80,6 @@ export class LiveRegionService { /** * Removes the message with the given UUID from the messages array * @param uuid The uuid of the message to clear - * @protected */ clearMessageByUUID(uuid: string) { const index = this.messages.findIndex(messageObj => messageObj.uuid === uuid); From cf54af2c22a8344d67573d7185401ade04cf5588 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 3 Sep 2024 13:43:02 +0200 Subject: [PATCH 095/822] 117803: Refactor Item Edit Bitstreams page to use HTML Table elements --- .../item-bitstreams.component.html | 11 +- .../item-bitstreams.component.scss | 20 +- .../item-edit-bitstream-bundle.component.html | 109 +++++++-- .../item-edit-bitstream-bundle.component.scss | 20 ++ .../item-edit-bitstream-bundle.component.ts | 216 +++++++++++++++++- ...-drag-and-drop-bitstream-list.component.ts | 4 + src/assets/i18n/en.json5 | 2 + 7 files changed, 336 insertions(+), 46 deletions(-) create mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index 4cb9577fcb5..70f6ca55e8f 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -23,16 +23,7 @@ -
-
-
- - {{'item.edit.bitstreams.headers.name' | translate}} -
-
{{'item.edit.bitstreams.headers.description' | translate}}
-
{{'item.edit.bitstreams.headers.format' | translate}}
-
{{'item.edit.bitstreams.headers.actions' | translate}}
-
+
-
-
- -
- {{'item.edit.bitstreams.bundle.name' | translate:{ name: dsoNameService.getName(bundle) } }} -
-
-
-
- -
-
-
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {{'item.edit.bitstreams.headers.name' | translate}} + + {{'item.edit.bitstreams.headers.description' | translate}} + + {{'item.edit.bitstreams.headers.format' | translate}} + + {{'item.edit.bitstreams.headers.actions' | translate}} +
+ {{'item.edit.bitstreams.bundle.name' | translate:{ name: bundleName } }} + + +
+ {{ entry.name }} + + {{ entry.description }} + + {{ (entry.format | async)?.shortDescription }} + +
+
+ + + + + + +
+
+
+ +
+
+ diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss new file mode 100644 index 00000000000..d344b1657a2 --- /dev/null +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss @@ -0,0 +1,20 @@ +.header-row { + color: var(--bs-table-dark-color); + background-color: var(--bs-table-dark-bg); + border-color: var(--bs-table-dark-border-color); +} + +.bundle-row { + color: var(--bs-table-head-color); + background-color: var(--bs-table-head-bg); + border-color: var(--bs-table-border-color); +} + +.row-element { + padding: 0.75em; + border-bottom: var(--bs-table-border-width) solid var(--bs-table-border-color); +} + +.bitstream-name { + font-weight: normal; +} diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 70f4b632178..ad009e7cb78 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -5,10 +5,65 @@ import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes'; import { getItemPageRoute } from '../../../item-page-routing-paths'; import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; +import { RemoteData } from 'src/app/core/data/remote-data'; +import { PaginatedList } from 'src/app/core/data/paginated-list.model'; +import { Bitstream } from 'src/app/core/shared/bitstream.model'; +import { Observable, BehaviorSubject, switchMap } from 'rxjs'; +import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; +import { FieldUpdates } from '../../../../core/data/object-updates/field-updates.model'; +import { PaginatedSearchOptions } from '../../../../shared/search/models/paginated-search-options.model'; +import { BundleDataService } from '../../../../core/data/bundle-data.service'; +import { followLink } from '../../../../shared/utils/follow-link-config.model'; +import { + getAllSucceededRemoteData, + paginatedListToArray, + getFirstSucceededRemoteDataPayload, getFirstSucceededRemoteData +} from '../../../../core/shared/operators'; +import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; +import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model'; +import { map } from 'rxjs/operators'; +import { getBitstreamDownloadRoute } from '../../../../app-routing-paths'; +import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; +import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; +import { PaginationService } from '../../../../core/pagination/pagination.service'; + +/** + * Interface storing all the information necessary to create a row in the bitstream edit table + */ +export interface BitstreamTableEntry { + /** + * The bitstream + */ + bitstream: Bitstream, + /** + * The uuid of the Bitstream + */ + id: string, + /** + * The name of the Bitstream + */ + name: string, + /** + * The name of the Bitstream with all whitespace removed + */ + nameStripped: string, + /** + * The description of the Bitstream + */ + description: string, + /** + * Observable emitting the Format of the Bitstream + */ + format: Observable, + /** + * The download url of the Bitstream + */ + downloadUrl: string, +} @Component({ selector: 'ds-item-edit-bitstream-bundle', - styleUrls: ['../item-bitstreams.component.scss'], + styleUrls: ['../item-bitstreams.component.scss', './item-edit-bitstream-bundle.component.scss'], templateUrl: './item-edit-bitstream-bundle.component.html', }) /** @@ -17,6 +72,7 @@ import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; * (which means it'll be added to the parents html without a wrapping ds-item-edit-bitstream-bundle element) */ export class ItemEditBitstreamBundleComponent implements OnInit { + protected readonly FieldChangeType = FieldChangeType; /** * The view on the bundle information and bitstreams @@ -56,9 +112,48 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ itemPageRoute: string; + /** + * The name of the bundle + */ + bundleName: string; + + /** + * The bitstreams to show in the table + */ + bitstreamsRD$: Observable>>; + + /** + * The data to show in the table + */ + tableEntries$: Observable; + + /** + * The initial page options to use for fetching the bitstreams + */ + paginationOptions: PaginationComponentOptions; + + /** + * The current page options + */ + currentPaginationOptions$: BehaviorSubject; + + /** + * The self url of the bundle, also used when retrieving fieldUpdates + */ + bundleUrl: string; + + /** + * The updates to the current bitstreams + */ + updates$: Observable; + + constructor( protected viewContainerRef: ViewContainerRef, public dsoNameService: DSONameService, + protected bundleService: BundleDataService, + protected objectUpdatesService: ObjectUpdatesService, + protected paginationService: PaginationService, ) { } @@ -66,5 +161,124 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.bundleNameColumn = this.columnSizes.combineColumns(0, 2); this.viewContainerRef.createEmbeddedView(this.bundleView); this.itemPageRoute = getItemPageRoute(this.item); + this.bundleName = this.dsoNameService.getName(this.bundle); + this.bundleUrl = this.bundle.self; + + this.initializePagination(); + this.initializeBitstreams(); + + // this.bitstreamsRD = this. + } + + protected initializePagination() { + this.paginationOptions = Object.assign(new PaginationComponentOptions(),{ + id: this.bundleName, // This might behave unexpectedly if the item contains two bundles with the same name + currentPage: 1, + pageSize: 10 + }); + + this.currentPaginationOptions$ = new BehaviorSubject(this.paginationOptions); + + this.paginationService.getCurrentPagination(this.paginationOptions.id, this.paginationOptions) + .subscribe((pagination) => { + this.currentPaginationOptions$.next(pagination); + }); + } + + protected initializeBitstreams() { + this.bitstreamsRD$ = this.currentPaginationOptions$.pipe( + switchMap((page: PaginationComponentOptions) => { + const paginatedOptions = new PaginatedSearchOptions({ pagination: Object.assign({}, page) }); + return this.bundleService.getBitstreams(this.bundle.id, paginatedOptions, followLink('format')); + }), + ); + + this.bitstreamsRD$.pipe( + getFirstSucceededRemoteData(), + paginatedListToArray(), + ).subscribe((bitstreams) => { + this.objectUpdatesService.initialize(this.bundleUrl, bitstreams, new Date()); + }); + + this.updates$ = this.bitstreamsRD$.pipe( + getAllSucceededRemoteData(), + paginatedListToArray(), + switchMap((bitstreams) => this.objectUpdatesService.getFieldUpdatesExclusive(this.bundleUrl, bitstreams)) + ); + + this.tableEntries$ = this.bitstreamsRD$.pipe( + getAllSucceededRemoteData(), + paginatedListToArray(), + map((bitstreams) => { + return bitstreams.map((bitstream) => { + const name = this.dsoNameService.getName(bitstream); + + return { + bitstream: bitstream, + id: bitstream.uuid, + name: name, + nameStripped: this.stripWhiteSpace(name), + description: bitstream.firstMetadataValue('dc.description'), + format: bitstream.format.pipe(getFirstSucceededRemoteDataPayload()), + downloadUrl: getBitstreamDownloadRoute(bitstream), + }; + }); + }), + ); + } + + /** + * Check if a user should be allowed to remove this field + */ + canRemove(fieldUpdate: FieldUpdate): boolean { + return fieldUpdate.changeType !== FieldChangeType.REMOVE; + } + + /** + * Check if a user should be allowed to cancel the update to this field + */ + canUndo(fieldUpdate: FieldUpdate): boolean { + return fieldUpdate.changeType >= 0; + } + + /** + * Sends a new remove update for this field to the object updates service + */ + remove(bitstream: Bitstream): void { + this.objectUpdatesService.saveRemoveFieldUpdate(this.bundleUrl, bitstream); + } + + /** + * Cancels the current update for this field in the object updates service + */ + undo(bitstream: Bitstream): void { + this.objectUpdatesService.removeSingleFieldUpdate(this.bundleUrl, bitstream.uuid); + } + + getRowClass(update: FieldUpdate): string { + switch (update.changeType) { + case FieldChangeType.UPDATE: + return 'table-warning'; + case FieldChangeType.ADD: + return 'table-success'; + case FieldChangeType.REMOVE: + return 'table-danger'; + default: + return 'bg-white'; + } + } + + /** + * Returns a string equal to the input string with all whitespace removed. + * @param str + */ + // Whitespace is stripped from the Bitstream names for accessibility reasons. + // To make it clear which headers are relevant for a specific field in the table, the 'headers' attribute is used to + // refer to specific headers. The Bitstream's name is used as header ID for the row containing information regarding + // that bitstream. As the 'headers' attribute contains a space-separated string of header IDs, the Bitstream's header + // ID can not contain strings itself. + stripWhiteSpace(str: string): string { + // '/\s+/g' matches all occurrences of any amount of whitespace characters + return str.replace(/\s+/g, ''); } } diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts index 2c81a4e2cb9..d5bb9eceea3 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts @@ -24,6 +24,10 @@ import { PaginationComponentOptions } from '../../../../../shared/pagination/pag * bitstreams within the paginated list. To drag and drop a bitstream between two pages, drag the row on top of the * page number you want the bitstream to end up at. Doing so will add the bitstream to the top of that page. */ +// NOTE: +// This component was used by the item-edit-bitstream-bundle.component, but this is no longer the case. It is left here +// as a reference for the drag-and-drop functionality. This component (and the abstract version it extends) should be +// removed once this reference is no longer useful. export class PaginatedDragAndDropBitstreamListComponent extends AbstractPaginatedDragAndDropListComponent implements OnInit { /** * The bundle to display bitstreams for diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 6c91bae4c16..4d5ef9ee1b6 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1934,6 +1934,8 @@ "item.edit.bitstreams.bundle.name": "BUNDLE: {{ name }}", + "item.edit.bitstreams.bundle.table.aria-label": "Bitstreams in the {{ bundle }} Bundle", + "item.edit.bitstreams.discard-button": "Discard", "item.edit.bitstreams.edit.buttons.download": "Download", From a11bfc80ad5b087aab9c6e283a08f0db2f87d5ed Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 3 Sep 2024 14:24:31 +0200 Subject: [PATCH 096/822] 117803: Hide table headers for subsequent bundle tables --- .../item-bitstreams/item-bitstreams.component.html | 3 ++- .../item-edit-bitstream-bundle.component.html | 14 +++++++++----- .../item-edit-bitstream-bundle.component.ts | 5 +++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index 70f6ca55e8f..f22dbe6a0e2 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -24,10 +24,11 @@
-
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index c11035e305b..a95a7921a4e 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -10,7 +10,7 @@ - + - - - - diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss index d344b1657a2..725d329936d 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss @@ -18,3 +18,12 @@ .bitstream-name { font-weight: normal; } + +.pagination-control-container { + display: flex; +} + +.pagination-control { + padding: 0 0.1rem; + vertical-align: center; +} diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index ae6bc0876c5..2a84c00c029 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -26,6 +26,8 @@ import { getBitstreamDownloadRoute } from '../../../../app-routing-paths'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; +import { SortDirection } from '../../../../core/cache/models/sort-options.model'; +import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; /** * Interface storing all the information necessary to create a row in the bitstream edit table @@ -79,6 +81,8 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ @ViewChild('bundleView', {static: true}) bundleView; + @ViewChild(PaginationComponent) paginationComponent: PaginationComponent; + /** * The bundle to display bitstreams for */ @@ -142,6 +146,16 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ currentPaginationOptions$: BehaviorSubject; + /** + * The available page size options + */ + pageSizeOptions: number[]; + + /** + * The currently selected page size + */ + pageSize$: BehaviorSubject; + /** * The self url of the bundle, also used when retrieving fieldUpdates */ @@ -182,11 +196,15 @@ export class ItemEditBitstreamBundleComponent implements OnInit { pageSize: 10 }); + this.pageSizeOptions = this.paginationOptions.pageSizeOptions; + this.currentPaginationOptions$ = new BehaviorSubject(this.paginationOptions); + this.pageSize$ = new BehaviorSubject(this.paginationOptions.pageSize); this.paginationService.getCurrentPagination(this.paginationOptions.id, this.paginationOptions) .subscribe((pagination) => { this.currentPaginationOptions$.next(pagination); + this.pageSize$.next(pagination.pageSize); }); } @@ -286,4 +304,9 @@ export class ItemEditBitstreamBundleComponent implements OnInit { // '/\s+/g' matches all occurrences of any amount of whitespace characters return str.replace(/\s+/g, ''); } + + public doPageSizeChange(pageSize: number) { + this.paginationComponent.doPageSizeChange(pageSize); + } + } From d85124c121db1ef88f3015cfdc333bfe1b8c9ce3 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 4 Sep 2024 14:32:29 +0200 Subject: [PATCH 098/822] 117803: Fix deleted bitstreams not being removed from list --- .../item-edit-bitstream-bundle.component.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 2a84c00c029..6ef15397b02 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -26,8 +26,8 @@ import { getBitstreamDownloadRoute } from '../../../../app-routing-paths'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; -import { SortDirection } from '../../../../core/cache/models/sort-options.model'; import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; +import { RequestService } from '../../../../core/data/request.service'; /** * Interface storing all the information necessary to create a row in the bitstream edit table @@ -173,6 +173,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { protected bundleService: BundleDataService, protected objectUpdatesService: ObjectUpdatesService, protected paginationService: PaginationService, + protected requestService: RequestService, ) { } @@ -212,7 +213,14 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.bitstreamsRD$ = this.currentPaginationOptions$.pipe( switchMap((page: PaginationComponentOptions) => { const paginatedOptions = new PaginatedSearchOptions({ pagination: Object.assign({}, page) }); - return this.bundleService.getBitstreams(this.bundle.id, paginatedOptions, followLink('format')); + return this.bundleService.getBitstreamsEndpoint(this.bundle.id, paginatedOptions).pipe( + switchMap((href) => this.requestService.hasByHref$(href)), + switchMap(() => this.bundleService.getBitstreams( + this.bundle.id, + paginatedOptions, + followLink('format') + )) + ); }), ); From 374a9ae14eb036c1bf91eec2891aa722722545ed Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 4 Sep 2024 15:46:04 +0200 Subject: [PATCH 099/822] 117803: Add item-bitstream service --- .../item-bitstreams.component.ts | 82 ++------- .../item-bitstreams.service.ts | 158 ++++++++++++++++++ .../item-edit-bitstream-bundle.component.ts | 41 +---- 3 files changed, 176 insertions(+), 105 deletions(-) create mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts index ee53bd919c2..9f27cf11b36 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts @@ -8,23 +8,19 @@ import { ActivatedRoute, Router } from '@angular/router'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { BitstreamDataService } from '../../../core/data/bitstream-data.service'; -import { hasValue, isNotEmpty } from '../../../shared/empty.util'; +import { hasValue } from '../../../shared/empty.util'; import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { RequestService } from '../../../core/data/request.service'; import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../../../core/shared/operators'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; import { Bundle } from '../../../core/shared/bundle.model'; -import { Bitstream } from '../../../core/shared/bitstream.model'; import { BundleDataService } from '../../../core/data/bundle-data.service'; import { PaginatedSearchOptions } from '../../../shared/search/models/paginated-search-options.model'; -import { ResponsiveColumnSizes } from '../../../shared/responsive-table-sizes/responsive-column-sizes'; import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes'; import { NoContent } from '../../../core/shared/NoContent.model'; import { Operation } from 'fast-json-patch'; -import { FieldUpdate } from '../../../core/data/object-updates/field-update.model'; -import { FieldUpdates } from '../../../core/data/object-updates/field-updates.model'; -import { FieldChangeType } from '../../../core/data/object-updates/field-change-type.model'; +import { ItemBitstreamsService } from './item-bitstreams.service'; @Component({ selector: 'ds-item-bitstreams', @@ -41,28 +37,10 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme */ bundles$: Observable; - /** - * The page options to use for fetching the bundles - */ - bundlesOptions = { - id: 'bundles-pagination-options', - currentPage: 1, - pageSize: 9999 - } as any; - /** * The bootstrap sizes used for the columns within this table */ - columnSizes = new ResponsiveTableSizes([ - // Name column - new ResponsiveColumnSizes(2, 2, 3, 4, 4), - // Description column - new ResponsiveColumnSizes(2, 3, 3, 3, 3), - // Format column - new ResponsiveColumnSizes(2, 2, 2, 2, 2), - // Actions column - new ResponsiveColumnSizes(6, 5, 4, 3, 3) - ]); + columnSizes: ResponsiveTableSizes; /** * Are we currently submitting the changes? @@ -88,16 +66,21 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme public requestService: RequestService, public cdRef: ChangeDetectorRef, public bundleService: BundleDataService, - public zone: NgZone + public zone: NgZone, + public itemBitstreamsService: ItemBitstreamsService, ) { super(itemService, objectUpdatesService, router, notificationsService, translateService, route); + + this.columnSizes = this.itemBitstreamsService.getColumnSizes(); } /** * Actions to perform after the item has been initialized */ postItemInit(): void { - this.bundles$ = this.itemService.getBundles(this.item.id, new PaginatedSearchOptions({pagination: this.bundlesOptions})).pipe( + const bundlesOptions = this.itemBitstreamsService.getInitialBundlesPaginationOptions(); + + this. bundles$ = this.itemService.getBundles(this.item.id, new PaginatedSearchOptions({pagination: bundlesOptions})).pipe( getFirstSucceededRemoteData(), getRemoteDataPayload(), map((bundlePage: PaginatedList) => bundlePage.page) @@ -119,30 +102,12 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme */ submit() { this.submitting = true; - const bundlesOnce$ = this.bundles$.pipe(take(1)); - - // Fetch all removed bitstreams from the object update service - const removedBitstreams$ = bundlesOnce$.pipe( - switchMap((bundles: Bundle[]) => observableZip( - ...bundles.map((bundle: Bundle) => this.objectUpdatesService.getFieldUpdates(bundle.self, [], true)) - )), - map((fieldUpdates: FieldUpdates[]) => ([] as FieldUpdate[]).concat( - ...fieldUpdates.map((updates: FieldUpdates) => Object.values(updates).filter((fieldUpdate: FieldUpdate) => fieldUpdate.changeType === FieldChangeType.REMOVE)) - )), - map((fieldUpdates: FieldUpdate[]) => fieldUpdates.map((fieldUpdate: FieldUpdate) => fieldUpdate.field)) - ); - // Send out delete requests for all deleted bitstreams - const removedResponses$: Observable> = removedBitstreams$.pipe( - take(1), - switchMap((removedBitstreams: Bitstream[]) => { - return this.bitstreamService.removeMultiple(removedBitstreams); - }) - ); + const removedResponses$ = this.itemBitstreamsService.removeMarkedBitstreams(this.bundles$); // Perform the setup actions from above in order and display notifications removedResponses$.subscribe((responses: RemoteData) => { - this.displayNotifications('item.edit.bitstreams.notifications.remove', [responses]); + this.itemBitstreamsService.displayNotifications('item.edit.bitstreams.notifications.remove', [responses]); this.submitting = false; }); } @@ -164,7 +129,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme } as Operation; this.bundleService.patch(bundle, [moveOperation]).pipe(take(1)).subscribe((response: RemoteData) => { this.zone.run(() => { - this.displayNotifications('item.edit.bitstreams.notifications.move', [response]); + this.itemBitstreamsService.displayNotifications('item.edit.bitstreams.notifications.move', [response]); // Remove all cached requests from this bundle and call the event's callback when the requests are cleared this.requestService.removeByHrefSubstring(bundle.self).pipe( filter((isCached) => isCached), @@ -176,27 +141,6 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme }); } - /** - * Display notifications - * - Error notification for each failed response with their message - * - Success notification in case there's at least one successful response - * @param key The i18n key for the notification messages - * @param responses The returned responses to display notifications for - */ - displayNotifications(key: string, responses: RemoteData[]) { - if (isNotEmpty(responses)) { - const failedResponses = responses.filter((response: RemoteData) => hasValue(response) && response.hasFailed); - const successfulResponses = responses.filter((response: RemoteData) => hasValue(response) && response.hasSucceeded); - - failedResponses.forEach((response: RemoteData) => { - this.notificationsService.error(this.translateService.instant(`${key}.failed.title`), response.errorMessage); - }); - if (successfulResponses.length > 0) { - this.notificationsService.success(this.translateService.instant(`${key}.saved.title`), this.translateService.instant(`${key}.saved.content`)); - } - } - } - /** * Request the object updates service to discard all current changes to this item * Shows a notification to remind the user that they can undo this diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts new file mode 100644 index 00000000000..487df77b28e --- /dev/null +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts @@ -0,0 +1,158 @@ +import { Injectable } from '@angular/core'; +import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; +import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes'; +import { ResponsiveColumnSizes } from '../../../shared/responsive-table-sizes/responsive-column-sizes'; +import { RemoteData } from '../../../core/data/remote-data'; +import { isNotEmpty, hasValue } from '../../../shared/empty.util'; +import { Bundle } from '../../../core/shared/bundle.model'; +import { NotificationsService } from '../../../shared/notifications/notifications.service'; +import { TranslateService } from '@ngx-translate/core'; +import { Observable, zip as observableZip } from 'rxjs'; +import { NoContent } from '../../../core/shared/NoContent.model'; +import { take, switchMap, map } from 'rxjs/operators'; +import { FieldUpdates } from '../../../core/data/object-updates/field-updates.model'; +import { FieldUpdate } from '../../../core/data/object-updates/field-update.model'; +import { FieldChangeType } from '../../../core/data/object-updates/field-change-type.model'; +import { Bitstream } from '../../../core/shared/bitstream.model'; +import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; +import { BitstreamDataService } from '../../../core/data/bitstream-data.service'; +import { BitstreamTableEntry } from './item-edit-bitstream-bundle/item-edit-bitstream-bundle.component'; +import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators'; +import { getBitstreamDownloadRoute } from '../../../app-routing-paths'; +import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; + +@Injectable( + { providedIn: 'root' }, +) +export class ItemBitstreamsService { + + constructor( + protected notificationsService: NotificationsService, + protected translateService: TranslateService, + protected objectUpdatesService: ObjectUpdatesService, + protected bitstreamService: BitstreamDataService, + protected dsoNameService: DSONameService, + ) { + } + + /** + * Returns the pagination options to use when fetching the bundles + */ + getInitialBundlesPaginationOptions(): PaginationComponentOptions { + return Object.assign(new PaginationComponentOptions(), { + id: 'bundles-pagination-options', + currentPage: 1, + pageSize: 9999 + }); + } + + getInitialBitstreamsPaginationOptions(bundleName: string): PaginationComponentOptions { + return Object.assign(new PaginationComponentOptions(),{ + id: bundleName, // This might behave unexpectedly if the item contains two bundles with the same name + currentPage: 1, + pageSize: 10 + }); + } + + /** + * Returns the {@link ResponsiveTableSizes} for use in the columns of the edit bitstreams table + */ + getColumnSizes(): ResponsiveTableSizes { + return new ResponsiveTableSizes([ + // Name column + new ResponsiveColumnSizes(2, 2, 3, 4, 4), + // Description column + new ResponsiveColumnSizes(2, 3, 3, 3, 3), + // Format column + new ResponsiveColumnSizes(2, 2, 2, 2, 2), + // Actions column + new ResponsiveColumnSizes(6, 5, 4, 3, 3) + ]); + } + + /** + * Display notifications + * - Error notification for each failed response with their message + * - Success notification in case there's at least one successful response + * @param key The i18n key for the notification messages + * @param responses The returned responses to display notifications for + */ + displayNotifications(key: string, responses: RemoteData[]) { + if (isNotEmpty(responses)) { + const failedResponses = responses.filter((response: RemoteData) => hasValue(response) && response.hasFailed); + const successfulResponses = responses.filter((response: RemoteData) => hasValue(response) && response.hasSucceeded); + + failedResponses.forEach((response: RemoteData) => { + this.notificationsService.error(this.translateService.instant(`${key}.failed.title`), response.errorMessage); + }); + if (successfulResponses.length > 0) { + this.notificationsService.success(this.translateService.instant(`${key}.saved.title`), this.translateService.instant(`${key}.saved.content`)); + } + } + } + + /** + * Removes the bitstreams marked for deletion from the Bundles emitted by the provided observable. + * @param bundles$ + */ + removeMarkedBitstreams(bundles$: Observable): Observable> { + const bundlesOnce$ = bundles$.pipe(take(1)); + + // Fetch all removed bitstreams from the object update service + const removedBitstreams$ = bundlesOnce$.pipe( + switchMap((bundles: Bundle[]) => observableZip( + ...bundles.map((bundle: Bundle) => this.objectUpdatesService.getFieldUpdates(bundle.self, [], true)) + )), + map((fieldUpdates: FieldUpdates[]) => ([] as FieldUpdate[]).concat( + ...fieldUpdates.map((updates: FieldUpdates) => Object.values(updates).filter((fieldUpdate: FieldUpdate) => fieldUpdate.changeType === FieldChangeType.REMOVE)) + )), + map((fieldUpdates: FieldUpdate[]) => fieldUpdates.map((fieldUpdate: FieldUpdate) => fieldUpdate.field)) + ); + + // Send out delete requests for all deleted bitstreams + return removedBitstreams$.pipe( + take(1), + switchMap((removedBitstreams: Bitstream[]) => { + return this.bitstreamService.removeMultiple(removedBitstreams); + }) + ); + } + + mapBitstreamsToTableEntries(bitstreams: Bitstream[]): BitstreamTableEntry[] { + return bitstreams.map((bitstream) => { + const name = this.dsoNameService.getName(bitstream); + + return { + bitstream: bitstream, + id: bitstream.uuid, + name: name, + nameStripped: this.nameToHeader(name), + description: bitstream.firstMetadataValue('dc.description'), + format: bitstream.format.pipe(getFirstSucceededRemoteDataPayload()), + downloadUrl: getBitstreamDownloadRoute(bitstream), + }; + }); + } + + /** + * Returns a string appropriate to be used as header ID + * @param name + */ + nameToHeader(name: string): string { + // Whitespace is stripped from the Bitstream names for accessibility reasons. + // To make it clear which headers are relevant for a specific field in the table, the 'headers' attribute is used to + // refer to specific headers. The Bitstream's name is used as header ID for the row containing information regarding + // that bitstream. As the 'headers' attribute contains a space-separated string of header IDs, the Bitstream's header + // ID can not contain strings itself. + return this.stripWhiteSpace(name); + } + + /** + * Returns a string equal to the input string with all whitespace removed. + * @param str + */ + stripWhiteSpace(str: string): string { + // '/\s+/g' matches all occurrences of any amount of whitespace characters + return str.replace(/\s+/g, ''); + } +} diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 6ef15397b02..9c62fe06e7c 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -17,17 +17,17 @@ import { followLink } from '../../../../shared/utils/follow-link-config.model'; import { getAllSucceededRemoteData, paginatedListToArray, - getFirstSucceededRemoteDataPayload, getFirstSucceededRemoteData + getFirstSucceededRemoteData } from '../../../../core/shared/operators'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model'; import { map } from 'rxjs/operators'; -import { getBitstreamDownloadRoute } from '../../../../app-routing-paths'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; import { RequestService } from '../../../../core/data/request.service'; +import { ItemBitstreamsService } from '../item-bitstreams.service'; /** * Interface storing all the information necessary to create a row in the bitstream edit table @@ -174,6 +174,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { protected objectUpdatesService: ObjectUpdatesService, protected paginationService: PaginationService, protected requestService: RequestService, + protected itemBitstreamsService: ItemBitstreamsService, ) { } @@ -191,11 +192,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { } protected initializePagination() { - this.paginationOptions = Object.assign(new PaginationComponentOptions(),{ - id: this.bundleName, // This might behave unexpectedly if the item contains two bundles with the same name - currentPage: 1, - pageSize: 10 - }); + this.paginationOptions = this.itemBitstreamsService.getInitialBitstreamsPaginationOptions(this.bundleName); this.pageSizeOptions = this.paginationOptions.pageSizeOptions; @@ -240,21 +237,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.tableEntries$ = this.bitstreamsRD$.pipe( getAllSucceededRemoteData(), paginatedListToArray(), - map((bitstreams) => { - return bitstreams.map((bitstream) => { - const name = this.dsoNameService.getName(bitstream); - - return { - bitstream: bitstream, - id: bitstream.uuid, - name: name, - nameStripped: this.stripWhiteSpace(name), - description: bitstream.firstMetadataValue('dc.description'), - format: bitstream.format.pipe(getFirstSucceededRemoteDataPayload()), - downloadUrl: getBitstreamDownloadRoute(bitstream), - }; - }); - }), + map((bitstreams) => this.itemBitstreamsService.mapBitstreamsToTableEntries(bitstreams)), ); } @@ -299,20 +282,6 @@ export class ItemEditBitstreamBundleComponent implements OnInit { } } - /** - * Returns a string equal to the input string with all whitespace removed. - * @param str - */ - // Whitespace is stripped from the Bitstream names for accessibility reasons. - // To make it clear which headers are relevant for a specific field in the table, the 'headers' attribute is used to - // refer to specific headers. The Bitstream's name is used as header ID for the row containing information regarding - // that bitstream. As the 'headers' attribute contains a space-separated string of header IDs, the Bitstream's header - // ID can not contain strings itself. - stripWhiteSpace(str: string): string { - // '/\s+/g' matches all occurrences of any amount of whitespace characters - return str.replace(/\s+/g, ''); - } - public doPageSizeChange(pageSize: number) { this.paginationComponent.doPageSizeChange(pageSize); } From 3f4bf7ce0fdf73494bcb28045ef6d7cb8a4634dd Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 4 Sep 2024 16:32:30 +0200 Subject: [PATCH 100/822] 117803: Fix existing tests --- ...em-edit-bitstream-bundle.component.spec.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts index c26f99eb8fa..1502ad23113 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts @@ -6,6 +6,15 @@ import { Item } from '../../../../core/shared/item.model'; import { Bundle } from '../../../../core/shared/bundle.model'; import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes'; import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes/responsive-column-sizes'; +import { BundleDataService } from '../../../../core/data/bundle-data.service'; +import { of as observableOf } from 'rxjs'; +import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; +import { PaginationServiceStub } from '../../../../shared/testing/pagination-service.stub'; +import { RequestService } from '../../../../core/data/request.service'; +import { getMockRequestService } from '../../../../shared/mocks/request.service.mock'; +import { ItemBitstreamsService } from '../item-bitstreams.service'; +import { PaginationService } from '../../../../core/pagination/pagination.service'; +import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; describe('ItemEditBitstreamBundleComponent', () => { let comp: ItemEditBitstreamBundleComponent; @@ -31,10 +40,37 @@ describe('ItemEditBitstreamBundleComponent', () => { } }); + const restEndpoint = 'fake-rest-endpoint'; + const bundleService = jasmine.createSpyObj('bundleService', { + getBitstreamsEndpoint: observableOf(restEndpoint), + getBitstreams: null, + }); + + const objectUpdatesService = { + initialize: () => { + // do nothing + }, + }; + + const itemBitstreamsService = jasmine.createSpyObj('itemBitstreamsService', { + getInitialBitstreamsPaginationOptions: Object.assign(new PaginationComponentOptions(), { + id: 'bundles-pagination-options', + currentPage: 1, + pageSize: 9999 + }), + }); + beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], declarations: [ItemEditBitstreamBundleComponent], + providers: [ + { provide: BundleDataService, useValue: bundleService }, + { provide: ObjectUpdatesService, useValue: objectUpdatesService }, + { provide: PaginationService, useValue: new PaginationServiceStub() }, + { provide: RequestService, useValue: getMockRequestService() }, + { provide: ItemBitstreamsService, useValue: itemBitstreamsService }, + ], schemas: [ NO_ERRORS_SCHEMA ] From d8b426d7458da47320447a85e3c2fb4c7028f20c Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Thu, 5 Sep 2024 10:52:02 +0200 Subject: [PATCH 101/822] 117803: Add ItemBitsreamsService tests --- .../object-updates.service.stub.ts | 28 ++++ .../item-bitstreams.service.spec.ts | 129 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 src/app/core/data/object-updates/object-updates.service.stub.ts create mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts diff --git a/src/app/core/data/object-updates/object-updates.service.stub.ts b/src/app/core/data/object-updates/object-updates.service.stub.ts new file mode 100644 index 00000000000..c41728a338e --- /dev/null +++ b/src/app/core/data/object-updates/object-updates.service.stub.ts @@ -0,0 +1,28 @@ +export class ObjectUpdatesServiceStub { + + initialize = jasmine.createSpy('initialize'); + saveFieldUpdate = jasmine.createSpy('saveFieldUpdate'); + getObjectEntry = jasmine.createSpy('getObjectEntry'); + getFieldState = jasmine.createSpy('getFieldState'); + getFieldUpdates = jasmine.createSpy('getFieldUpdates'); + getFieldUpdatesExclusive = jasmine.createSpy('getFieldUpdatesExclusive'); + isValid = jasmine.createSpy('isValid'); + isValidPage = jasmine.createSpy('isValidPage'); + saveAddFieldUpdate = jasmine.createSpy('saveAddFieldUpdate'); + saveRemoveFieldUpdate = jasmine.createSpy('saveRemoveFieldUpdate'); + saveChangeFieldUpdate = jasmine.createSpy('saveChangeFieldUpdate'); + isSelectedVirtualMetadata = jasmine.createSpy('isSelectedVirtualMetadata'); + setSelectedVirtualMetadata = jasmine.createSpy('setSelectedVirtualMetadata'); + setEditableFieldUpdate = jasmine.createSpy('setEditableFieldUpdate'); + setValidFieldUpdate = jasmine.createSpy('setValidFieldUpdate'); + discardFieldUpdates = jasmine.createSpy('discardFieldUpdates'); + discardAllFieldUpdates = jasmine.createSpy('discardAllFieldUpdates'); + reinstateFieldUpdates = jasmine.createSpy('reinstateFieldUpdates'); + removeSingleFieldUpdate = jasmine.createSpy('removeSingleFieldUpdate'); + getUpdateFields = jasmine.createSpy('getUpdateFields'); + hasUpdates = jasmine.createSpy('hasUpdates'); + isReinstatable = jasmine.createSpy('isReinstatable'); + getLastModified = jasmine.createSpy('getLastModified'); + createPatch = jasmine.createSpy('getPatch'); + +} diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts new file mode 100644 index 00000000000..89ecfb518f9 --- /dev/null +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts @@ -0,0 +1,129 @@ +import { ItemBitstreamsService } from './item-bitstreams.service'; +import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub'; +import { getMockTranslateService } from '../../../shared/mocks/translate.service.mock'; +import { ObjectUpdatesServiceStub } from '../../../core/data/object-updates/object-updates.service.stub'; +import { BitstreamDataServiceStub } from '../../../shared/testing/bitstream-data-service.stub'; +import { DSONameServiceMock } from '../../../shared/mocks/dso-name.service.mock'; +import { NotificationsService } from '../../../shared/notifications/notifications.service'; +import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; +import { TranslateService } from '@ngx-translate/core'; +import { BitstreamDataService } from '../../../core/data/bitstream-data.service'; +import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; +import { Bitstream } from '../../../core/shared/bitstream.model'; +import { BitstreamFormat } from '../../../core/shared/bitstream-format.model'; +import { + createSuccessfulRemoteDataObject$, + createFailedRemoteDataObject, + createSuccessfulRemoteDataObject +} from '../../../shared/remote-data.utils'; + +describe('ItemBitstreamsService', () => { + let service: ItemBitstreamsService; + let notificationsService: NotificationsService; + let translateService: TranslateService; + let objectUpdatesService: ObjectUpdatesService; + let bitstreamDataService: BitstreamDataService; + let dsoNameService: DSONameService; + + beforeEach(() => { + notificationsService = new NotificationsServiceStub() as any; + translateService = getMockTranslateService(); + objectUpdatesService = new ObjectUpdatesServiceStub() as any; + bitstreamDataService = new BitstreamDataServiceStub() as any; + dsoNameService = new DSONameServiceMock() as any; + + service = new ItemBitstreamsService( + notificationsService, + translateService, + objectUpdatesService, + bitstreamDataService, + dsoNameService, + ); + }); + + describe('displayNotifications', () => { + it('should display an error notification if a response failed', () => { + const responses = [ + createFailedRemoteDataObject(), + ]; + + const key = 'some.key'; + + service.displayNotifications(key, responses); + + expect(notificationsService.success).not.toHaveBeenCalled(); + expect(notificationsService.error).toHaveBeenCalled(); + expect(translateService.instant).toHaveBeenCalledWith('some.key.failed.title'); + }); + + it('should display a success notification if a response succeeded', () => { + const responses = [ + createSuccessfulRemoteDataObject(undefined), + ]; + + const key = 'some.key'; + + service.displayNotifications(key, responses); + + expect(notificationsService.success).toHaveBeenCalled(); + expect(notificationsService.error).not.toHaveBeenCalled(); + expect(translateService.instant).toHaveBeenCalledWith('some.key.saved.title'); + }); + + it('should display both notifications if some failed and some succeeded', () => { + const responses = [ + createFailedRemoteDataObject(), + createSuccessfulRemoteDataObject(undefined), + ]; + + const key = 'some.key'; + + service.displayNotifications(key, responses); + + expect(notificationsService.success).toHaveBeenCalled(); + expect(notificationsService.error).toHaveBeenCalled(); + expect(translateService.instant).toHaveBeenCalledWith('some.key.saved.title'); + expect(translateService.instant).toHaveBeenCalledWith('some.key.saved.title'); + }); + }); + + describe('mapBitstreamsToTableEntries', () => { + it('should correctly map a Bitstream to a BitstreamTableEntry', () => { + const format: BitstreamFormat = new BitstreamFormat(); + + const bitstream: Bitstream = Object.assign(new Bitstream(), { + uuid: 'testUUID', + format: createSuccessfulRemoteDataObject$(format), + }); + + spyOn(dsoNameService, 'getName').and.returnValue('Test Name'); + spyOn(bitstream, 'firstMetadataValue').and.returnValue('description'); + + const tableEntry = service.mapBitstreamsToTableEntries([bitstream])[0]; + + expect(tableEntry.name).toEqual('Test Name'); + expect(tableEntry.nameStripped).toEqual('TestName'); + expect(tableEntry.bitstream).toBe(bitstream); + expect(tableEntry.id).toEqual('testUUID'); + expect(tableEntry.description).toEqual('description'); + expect(tableEntry.downloadUrl).toEqual('/bitstreams/testUUID/download'); + }); + }); + + describe('nameToHeader', () => { + it('should correctly transform a string to an appropriate header ID', () => { + const stringA = 'Test String'; + const stringAResult = 'TestString'; + expect(service.nameToHeader(stringA)).toEqual(stringAResult); + + const stringB = 'Test String Two'; + const stringBResult = 'TestStringTwo'; + expect(service.nameToHeader(stringB)).toEqual(stringBResult); + + const stringC = 'Test String Three'; + const stringCResult = 'TestStringThree'; + expect(service.nameToHeader(stringC)).toEqual(stringCResult); + }); + }); + +}); From cc5b841a65ee396a2622ca3eceb1f2d9bbce07c7 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 10 Sep 2024 13:36:27 +0200 Subject: [PATCH 102/822] 117803: Only visually hide header rows --- .../item-edit-bitstream-bundle.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index 6a505b9274b..2eb1a151b73 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -10,7 +10,7 @@
{{'item.edit.bitstreams.headers.name' | translate}} @@ -45,16 +45,20 @@
+ {{ entry.name }} + {{ entry.description }} + {{ (entry.format | async)?.shortDescription }} + - + +
+ +
+ + + +
+
+
- + - + @@ -31,7 +31,7 @@

{{"item.version.history.head" | translate}}< (versionsHistoryChange)="getAllVersions($event)" > -

+ (cdkDragStarted)="dragStart(entry.name)" (cdkDragEnded)="dragEnd(entry.name)">
{{'item.edit.bitstreams.headers.name' | translate}} From 8481604b1eb63acdc152fc9b7061bb9cd464294e Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 10 Sep 2024 14:14:58 +0200 Subject: [PATCH 103/822] 117803: Fix table & pagination margin --- .../item-bitstreams/item-bitstreams.component.scss | 4 ++++ .../item-edit-bitstream-bundle.component.scss | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss index 480bf56cc74..662c999461a 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss @@ -42,3 +42,7 @@ .table-border { border: 1px solid #dee2e6; } + +:host ::ng-deep .pagination { + padding-top: 0.5rem; +} diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss index 725d329936d..ae4eac8d524 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss @@ -27,3 +27,7 @@ padding: 0 0.1rem; vertical-align: center; } + +.table { + margin-bottom: 0; +} From 79f3a3116e2e358d5d7b778324d15c4977c7d55f Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 10 Sep 2024 14:35:05 +0200 Subject: [PATCH 104/822] 117803: Set header border to background color --- .../item-edit-bitstream-bundle.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss index ae4eac8d524..7088c3978e2 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss @@ -1,7 +1,7 @@ .header-row { color: var(--bs-table-dark-color); background-color: var(--bs-table-dark-bg); - border-color: var(--bs-table-dark-border-color); + border-color: var(--bs-table-dark-bg); } .bundle-row { From 6a8095d456167a139d320c4ad5c3a3d8a20a365e Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 10 Sep 2024 15:00:18 +0200 Subject: [PATCH 105/822] 117803: Change pagination settings styling --- .../item-edit-bitstream-bundle.component.html | 4 ++-- .../item-edit-bitstream-bundle.component.scss | 9 --------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index 2eb1a151b73..f434bf0f8fb 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -41,8 +41,8 @@ title="{{'item.edit.bitstreams.bundle.edit.buttons.upload' | translate}}"> -
- diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss index 7088c3978e2..bbd4e1e75ce 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.scss @@ -19,15 +19,6 @@ font-weight: normal; } -.pagination-control-container { - display: flex; -} - -.pagination-control { - padding: 0 0.1rem; - vertical-align: center; -} - .table { margin-bottom: 0; } From a230eee76d931a5b55046587c0fe06fcdd383a90 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 10 Sep 2024 16:06:44 +0200 Subject: [PATCH 106/822] 117803: Add negative top-margin to subsequent tables --- .../item-bitstreams/item-bitstreams.component.html | 2 +- .../item-edit-bitstream-bundle.component.html | 4 ++-- .../item-edit-bitstream-bundle.component.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index f22dbe6a0e2..3527f2f5b8c 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -28,7 +28,7 @@ [bundle]="bundle" [item]="item" [columnSizes]="columnSizes" - [hideHeader]="!isFirst" + [isFirstTable]="isFirst" (dropObject)="dropBitstream(bundle, $event)">
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index f434bf0f8fb..3d6ee4fa476 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -8,9 +8,9 @@ [collectionSize]="bitstreamsList.totalElements"> - - + - + - + - + - +
{{'item.edit.bitstreams.headers.name' | translate}} diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 9c62fe06e7c..0974da3f8cd 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -99,9 +99,9 @@ export class ItemEditBitstreamBundleComponent implements OnInit { @Input() columnSizes: ResponsiveTableSizes; /** - * Whether to hide the table headers + * Whether this is the first in a series of bundle tables */ - @Input() hideHeader = false; + @Input() isFirstTable = false; /** * Send an event when the user drops an object on the pagination From be99cc5c23763240869697798b95608e4ff1e319 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 11 Sep 2024 10:09:03 +0200 Subject: [PATCH 107/822] 118219: Allow dragging of table rows --- .../item-bitstreams/item-bitstreams.component.scss | 7 ------- .../item-edit-bitstream-bundle.component.html | 7 +++++-- .../item-edit-bitstream-bundle.component.ts | 5 +++++ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss index 662c999461a..0ee56fe67e7 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss @@ -1,7 +1,4 @@ - - .drag-handle { - visibility: hidden; &:hover { cursor: move; } @@ -11,10 +8,6 @@ cursor: move; } -:host ::ng-deep .bitstream-row:hover .drag-handle, :host ::ng-deep .bitstream-row-drag-handle:focus .drag-handle { - visibility: visible !important; -} - .cdk-drag-preview { margin-left: 0; box-sizing: border-box; diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index 3d6ee4fa476..b79518a7632 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -27,7 +27,7 @@
{{'item.edit.bitstreams.bundle.name' | translate:{ name: bundleName } }} @@ -65,10 +65,13 @@
+
+ +
{{ entry.name }}
) { + console.log('dropEvent:', event); + } + } From eadbcdbe14108b6c47f9e623e8b99c10d03ff5bd Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 11 Sep 2024 16:25:42 +0200 Subject: [PATCH 108/822] 118219: Store result of drag & dropping bitstream --- .../item-bitstreams.component.ts | 15 +++-- .../item-edit-bitstream-bundle.component.ts | 60 ++++++++++++++++--- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts index 9f27cf11b36..e7c846b5da2 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectorRef, Component, NgZone, OnDestroy } from '@angular/core'; import { AbstractItemUpdateComponent } from '../abstract-item-update/abstract-item-update.component'; -import { filter, map, switchMap, take } from 'rxjs/operators'; +import { map, switchMap, take } from 'rxjs/operators'; import { Observable, Subscription, zip as observableZip } from 'rxjs'; import { ItemDataService } from '../../../core/data/item-data.service'; import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; @@ -11,7 +11,11 @@ import { BitstreamDataService } from '../../../core/data/bitstream-data.service' import { hasValue } from '../../../shared/empty.util'; import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { RequestService } from '../../../core/data/request.service'; -import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../../../core/shared/operators'; +import { + getFirstSucceededRemoteData, + getRemoteDataPayload, + getFirstCompletedRemoteData +} from '../../../core/shared/operators'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; import { Bundle } from '../../../core/shared/bundle.model'; @@ -127,12 +131,13 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme from: `/_links/bitstreams/${event.fromIndex}/href`, path: `/_links/bitstreams/${event.toIndex}/href` } as Operation; - this.bundleService.patch(bundle, [moveOperation]).pipe(take(1)).subscribe((response: RemoteData) => { + this.bundleService.patch(bundle, [moveOperation]).pipe( + getFirstCompletedRemoteData(), + ).subscribe((response: RemoteData) => { this.zone.run(() => { this.itemBitstreamsService.displayNotifications('item.edit.bitstreams.notifications.move', [response]); // Remove all cached requests from this bundle and call the event's callback when the requests are cleared - this.requestService.removeByHrefSubstring(bundle.self).pipe( - filter((isCached) => isCached), + this.requestService.setStaleByHrefSubstring(bundle.self).pipe( take(1) ).subscribe(() => event.finish()); }); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index c0c4e302310..0293a1daea2 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -28,7 +28,8 @@ import { PaginationService } from '../../../../core/pagination/pagination.servic import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; import { RequestService } from '../../../../core/data/request.service'; import { ItemBitstreamsService } from '../item-bitstreams.service'; -import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { hasValue } from '../../../../shared/empty.util'; /** * Interface storing all the information necessary to create a row in the bitstream edit table @@ -135,7 +136,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { /** * The data to show in the table */ - tableEntries$: Observable; + tableEntries$: BehaviorSubject = new BehaviorSubject(null); /** * The initial page options to use for fetching the bitstreams @@ -165,7 +166,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { /** * The updates to the current bitstreams */ - updates$: Observable; + updates$: BehaviorSubject = new BehaviorSubject(null); constructor( @@ -229,17 +230,17 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.objectUpdatesService.initialize(this.bundleUrl, bitstreams, new Date()); }); - this.updates$ = this.bitstreamsRD$.pipe( + this.bitstreamsRD$.pipe( getAllSucceededRemoteData(), paginatedListToArray(), switchMap((bitstreams) => this.objectUpdatesService.getFieldUpdatesExclusive(this.bundleUrl, bitstreams)) - ); + ).subscribe((updates) => this.updates$.next(updates)); - this.tableEntries$ = this.bitstreamsRD$.pipe( + this.bitstreamsRD$.pipe( getAllSucceededRemoteData(), paginatedListToArray(), map((bitstreams) => this.itemBitstreamsService.mapBitstreamsToTableEntries(bitstreams)), - ); + ).subscribe((tableEntries) => this.tableEntries$.next(tableEntries)); } /** @@ -288,7 +289,50 @@ export class ItemEditBitstreamBundleComponent implements OnInit { } drop(event: CdkDragDrop) { - console.log('dropEvent:', event); + const dragIndex = event.previousIndex; + let dropIndex = event.currentIndex; + const dragPage = this.currentPaginationOptions$.value.currentPage - 1; + let dropPage = this.currentPaginationOptions$.value.currentPage - 1; + + // Check if the user is hovering over any of the pagination's pages at the time of dropping the object + const droppedOnElement = document.elementFromPoint(event.dropPoint.x, event.dropPoint.y); + if (hasValue(droppedOnElement) && hasValue(droppedOnElement.textContent) && droppedOnElement.classList.contains('page-link')) { + // The user is hovering over a page, fetch the page's number from the element + const droppedPage = Number(droppedOnElement.textContent); + if (hasValue(droppedPage) && !Number.isNaN(droppedPage)) { + dropPage = droppedPage - 1; + dropIndex = 0; + } + } + + const isNewPage = dragPage !== dropPage; + // Move the object in the custom order array if the drop happened within the same page + // This allows us to instantly display a change in the order, instead of waiting for the REST API's response first + if (!isNewPage && dragIndex !== dropIndex) { + const currentEntries = [...this.tableEntries$.value]; + moveItemInArray(currentEntries, dragIndex, dropIndex); + this.tableEntries$.next(currentEntries); + } + + const pageSize = this.currentPaginationOptions$.value.pageSize; + const redirectPage = dropPage + 1; + const fromIndex = (dragPage * pageSize) + dragIndex; + const toIndex = (dropPage * pageSize) + dropIndex; + // Send out a drop event (and navigate to the new page) when the "from" and "to" indexes are different from each other + if (fromIndex !== toIndex) { + // if (isNewPage) { + // this.loading$.next(true); + // } + this.dropObject.emit(Object.assign({ + fromIndex, + toIndex, + finish: () => { + if (isNewPage) { + this.paginationComponent.doPageChange(redirectPage); + } + } + })); + } } } From 6a2c7d09d69e6275d5e29d06a2672ce9b79e52fb Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Thu, 12 Sep 2024 10:01:55 +0200 Subject: [PATCH 109/822] 118219: Add dragging tooltip explaining how to drag to other page --- .../item-edit-bitstream-bundle.component.html | 7 +++-- .../item-edit-bitstream-bundle.component.ts | 30 ++++++++++++++++++- src/assets/i18n/en.json5 | 2 ++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index b79518a7632..0338055df51 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -27,7 +27,9 @@
{{'item.edit.bitstreams.bundle.name' | translate:{ name: bundleName } }} @@ -65,7 +67,8 @@
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 0293a1daea2..bd99fc1a09a 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -21,7 +21,7 @@ import { } from '../../../../core/shared/operators'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model'; -import { map } from 'rxjs/operators'; +import { map, take, filter } from 'rxjs/operators'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; @@ -83,8 +83,16 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ @ViewChild('bundleView', {static: true}) bundleView; + /** + * The view on the pagination component + */ @ViewChild(PaginationComponent) paginationComponent: PaginationComponent; + /** + * The view on the drag tooltip + */ + @ViewChild('dragTooltip') dragTooltip; + /** * The bundle to display bitstreams for */ @@ -158,6 +166,11 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ pageSize$: BehaviorSubject; + /** + * Whether the table has multiple pages + */ + hasMultiplePages = false; + /** * The self url of the bundle, also used when retrieving fieldUpdates */ @@ -288,6 +301,21 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.paginationComponent.doPageSizeChange(pageSize); } + dragStart() { + // Only open the drag tooltip when there are multiple pages + this.paginationComponent.shouldShowBottomPager.pipe( + take(1), + filter((hasMultiplePages) => hasMultiplePages), + ).subscribe(() => { + this.dragTooltip.open(); + }); + } + + dragEnd() { + this.dragTooltip.close(); + } + + drop(event: CdkDragDrop) { const dragIndex = event.previousIndex; let dropIndex = event.currentIndex; diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 4d5ef9ee1b6..f2dbf9b2d1c 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1936,6 +1936,8 @@ "item.edit.bitstreams.bundle.table.aria-label": "Bitstreams in the {{ bundle }} Bundle", + "item.edit.bitstreams.bundle.tooltip": "You can move a bitstream to a different page by dropping it on the page number.", + "item.edit.bitstreams.discard-button": "Discard", "item.edit.bitstreams.edit.buttons.download": "Download", From 8a16597b6958f99f949a413028ee2d5dee2905dc Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Thu, 12 Sep 2024 10:33:21 +0200 Subject: [PATCH 110/822] 118219: Fix tests --- .../item-bitstreams.component.spec.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts index 10e18121313..6ce73944739 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts @@ -18,7 +18,6 @@ import { ObjectValuesPipe } from '../../../shared/utils/object-values-pipe'; import { VarDirective } from '../../../shared/utils/var.directive'; import { BundleDataService } from '../../../core/data/bundle-data.service'; import { Bundle } from '../../../core/shared/bundle.model'; -import { RestResponse } from '../../../core/cache/response.models'; import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; import { RouterStub } from '../../../shared/testing/router.stub'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; @@ -145,7 +144,7 @@ describe('ItemBitstreamsComponent', () => { url: url }); bundleService = jasmine.createSpyObj('bundleService', { - patch: observableOf(new RestResponse(true, 200, 'OK')) + patch: createSuccessfulRemoteDataObject$({}), }); TestBed.configureTestingModule({ @@ -191,20 +190,6 @@ describe('ItemBitstreamsComponent', () => { }); }); - describe('when dropBitstream is called', () => { - const event = { - fromIndex: 0, - toIndex: 50, - // eslint-disable-next-line no-empty,@typescript-eslint/no-empty-function - finish: () => { - } - }; - - beforeEach(() => { - comp.dropBitstream(bundle, event); - }); - }); - describe('when dropBitstream is called', () => { beforeEach((done) => { comp.dropBitstream(bundle, { From a207fb51e9159c0076bb8a76cd5a73944a11655b Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Thu, 12 Sep 2024 10:38:38 +0200 Subject: [PATCH 111/822] 118219: Remove unused paginated-drag-and-drop components --- .../edit-item-page/edit-item-page.module.ts | 4 - ...rag-and-drop-bitstream-list.component.html | 33 --- ...-and-drop-bitstream-list.component.spec.ts | 150 ----------- ...-drag-and-drop-bitstream-list.component.ts | 80 ------ ...-edit-bitstream-drag-handle.component.html | 5 - ...em-edit-bitstream-drag-handle.component.ts | 26 -- ...nated-drag-and-drop-list.component.spec.ts | 136 ---------- ...-paginated-drag-and-drop-list.component.ts | 239 ------------------ 8 files changed, 673 deletions(-) delete mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html delete mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts delete mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts delete mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component.html delete mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component.ts delete mode 100644 src/app/shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component.spec.ts delete mode 100644 src/app/shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component.ts diff --git a/src/app/item-page/edit-item-page/edit-item-page.module.ts b/src/app/item-page/edit-item-page/edit-item-page.module.ts index 0a75394dddc..4ae5ebe6667 100644 --- a/src/app/item-page/edit-item-page/edit-item-page.module.ts +++ b/src/app/item-page/edit-item-page/edit-item-page.module.ts @@ -26,8 +26,6 @@ import { ItemMoveComponent } from './item-move/item-move.component'; import { ItemEditBitstreamBundleComponent } from './item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component'; import { BundleDataService } from '../../core/data/bundle-data.service'; import { DragDropModule } from '@angular/cdk/drag-drop'; -import { ItemEditBitstreamDragHandleComponent } from './item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component'; -import { PaginatedDragAndDropBitstreamListComponent } from './item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component'; import { VirtualMetadataComponent } from './virtual-metadata/virtual-metadata.component'; import { ItemVersionHistoryComponent } from './item-version-history/item-version-history.component'; import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component'; @@ -82,12 +80,10 @@ import { ItemVersionHistoryComponent, ItemEditBitstreamComponent, ItemEditBitstreamBundleComponent, - PaginatedDragAndDropBitstreamListComponent, EditRelationshipComponent, EditRelationshipListComponent, ItemCollectionMapperComponent, ItemMoveComponent, - ItemEditBitstreamDragHandleComponent, VirtualMetadataComponent, ItemAuthorizationsComponent, IdentifierDataComponent, diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html deleted file mode 100644 index f54aa73597d..00000000000 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html +++ /dev/null @@ -1,33 +0,0 @@ - - -
- -
- -
- -
-
-
-
-
-
- -
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts deleted file mode 100644 index 7317eb93be0..00000000000 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { Bundle } from '../../../../../core/shared/bundle.model'; -import { TranslateModule } from '@ngx-translate/core'; -import { PaginatedDragAndDropBitstreamListComponent } from './paginated-drag-and-drop-bitstream-list.component'; -import { VarDirective } from '../../../../../shared/utils/var.directive'; -import { ObjectValuesPipe } from '../../../../../shared/utils/object-values-pipe'; -import { ObjectUpdatesService } from '../../../../../core/data/object-updates/object-updates.service'; -import { BundleDataService } from '../../../../../core/data/bundle-data.service'; -import { Bitstream } from '../../../../../core/shared/bitstream.model'; -import { BitstreamFormat } from '../../../../../core/shared/bitstream-format.model'; -import { of as observableOf } from 'rxjs'; -import { take } from 'rxjs/operators'; -import { ResponsiveTableSizes } from '../../../../../shared/responsive-table-sizes/responsive-table-sizes'; -import { ResponsiveColumnSizes } from '../../../../../shared/responsive-table-sizes/responsive-column-sizes'; -import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; -import { RequestService } from '../../../../../core/data/request.service'; -import { PaginationService } from '../../../../../core/pagination/pagination.service'; -import { PaginationServiceStub } from '../../../../../shared/testing/pagination-service.stub'; - -describe('PaginatedDragAndDropBitstreamListComponent', () => { - let comp: PaginatedDragAndDropBitstreamListComponent; - let fixture: ComponentFixture; - let objectUpdatesService: ObjectUpdatesService; - let bundleService: BundleDataService; - let objectValuesPipe: ObjectValuesPipe; - let requestService: RequestService; - let paginationService; - - const columnSizes = new ResponsiveTableSizes([ - new ResponsiveColumnSizes(2, 2, 3, 4, 4), - new ResponsiveColumnSizes(2, 3, 3, 3, 3), - new ResponsiveColumnSizes(2, 2, 2, 2, 2), - new ResponsiveColumnSizes(6, 5, 4, 3, 3) - ]); - - const bundle = Object.assign(new Bundle(), { - id: 'bundle-1', - uuid: 'bundle-1', - _links: { - self: { href: 'bundle-1-selflink' } - } - }); - const date = new Date(); - const format = Object.assign(new BitstreamFormat(), { - shortDescription: 'PDF' - }); - const bitstream1 = Object.assign(new Bitstream(), { - uuid: 'bitstreamUUID1', - name: 'Fake Bitstream 1', - bundleName: 'ORIGINAL', - description: 'Description', - format: createSuccessfulRemoteDataObject$(format) - }); - const fieldUpdate1 = { - field: bitstream1, - changeType: undefined - }; - const bitstream2 = Object.assign(new Bitstream(), { - uuid: 'bitstreamUUID2', - name: 'Fake Bitstream 2', - bundleName: 'ORIGINAL', - description: 'Description', - format: createSuccessfulRemoteDataObject$(format) - }); - const fieldUpdate2 = { - field: bitstream2, - changeType: undefined - }; - - beforeEach(waitForAsync(() => { - objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', - { - getFieldUpdates: observableOf({ - [bitstream1.uuid]: fieldUpdate1, - [bitstream2.uuid]: fieldUpdate2, - }), - getFieldUpdatesExclusive: observableOf({ - [bitstream1.uuid]: fieldUpdate1, - [bitstream2.uuid]: fieldUpdate2, - }), - getFieldUpdatesByCustomOrder: observableOf({ - [bitstream1.uuid]: fieldUpdate1, - [bitstream2.uuid]: fieldUpdate2, - }), - saveMoveFieldUpdate: {}, - saveRemoveFieldUpdate: {}, - removeSingleFieldUpdate: {}, - saveAddFieldUpdate: {}, - discardFieldUpdates: {}, - reinstateFieldUpdates: observableOf(true), - initialize: {}, - getUpdatedFields: observableOf([bitstream1, bitstream2]), - getLastModified: observableOf(date), - hasUpdates: observableOf(true), - isReinstatable: observableOf(false), - isValidPage: observableOf(true), - initializeWithCustomOrder: {}, - addPageToCustomOrder: {} - } - ); - - bundleService = jasmine.createSpyObj('bundleService', { - getBitstreams: createSuccessfulRemoteDataObject$(createPaginatedList([bitstream1, bitstream2])), - getBitstreamsEndpoint: observableOf('') - }); - - objectValuesPipe = new ObjectValuesPipe(); - - requestService = jasmine.createSpyObj('requestService', { - hasByHref$: observableOf(true) - }); - - paginationService = new PaginationServiceStub(); - - TestBed.configureTestingModule({ - imports: [TranslateModule.forRoot()], - declarations: [PaginatedDragAndDropBitstreamListComponent, VarDirective], - providers: [ - { provide: ObjectUpdatesService, useValue: objectUpdatesService }, - { provide: BundleDataService, useValue: bundleService }, - { provide: ObjectValuesPipe, useValue: objectValuesPipe }, - { provide: RequestService, useValue: requestService }, - { provide: PaginationService, useValue: paginationService } - ], schemas: [ - NO_ERRORS_SCHEMA - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(PaginatedDragAndDropBitstreamListComponent); - comp = fixture.componentInstance; - comp.bundle = bundle; - comp.columnSizes = columnSizes; - fixture.detectChanges(); - }); - - it('should initialize the objectsRD$', (done) => { - comp.objectsRD$.pipe(take(1)).subscribe((objects) => { - expect(objects.payload.page).toEqual([bitstream1, bitstream2]); - done(); - }); - }); - - it('should initialize the URL', () => { - expect(comp.url).toEqual(bundle.self); - }); -}); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts deleted file mode 100644 index d5bb9eceea3..00000000000 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { AbstractPaginatedDragAndDropListComponent } from '../../../../../shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component'; -import { Component, ElementRef, Input, OnInit } from '@angular/core'; -import { Bundle } from '../../../../../core/shared/bundle.model'; -import { Bitstream } from '../../../../../core/shared/bitstream.model'; -import { ObjectUpdatesService } from '../../../../../core/data/object-updates/object-updates.service'; -import { BundleDataService } from '../../../../../core/data/bundle-data.service'; -import { switchMap } from 'rxjs/operators'; -import { PaginatedSearchOptions } from '../../../../../shared/search/models/paginated-search-options.model'; -import { ResponsiveTableSizes } from '../../../../../shared/responsive-table-sizes/responsive-table-sizes'; -import { followLink } from '../../../../../shared/utils/follow-link-config.model'; -import { ObjectValuesPipe } from '../../../../../shared/utils/object-values-pipe'; -import { RequestService } from '../../../../../core/data/request.service'; -import { PaginationService } from '../../../../../core/pagination/pagination.service'; -import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model'; - -@Component({ - selector: 'ds-paginated-drag-and-drop-bitstream-list', - styleUrls: ['../../item-bitstreams.component.scss'], - templateUrl: './paginated-drag-and-drop-bitstream-list.component.html', -}) -/** - * A component listing edit-bitstream rows for each bitstream within the given bundle. - * This component makes use of the AbstractPaginatedDragAndDropListComponent, allowing for users to drag and drop - * bitstreams within the paginated list. To drag and drop a bitstream between two pages, drag the row on top of the - * page number you want the bitstream to end up at. Doing so will add the bitstream to the top of that page. - */ -// NOTE: -// This component was used by the item-edit-bitstream-bundle.component, but this is no longer the case. It is left here -// as a reference for the drag-and-drop functionality. This component (and the abstract version it extends) should be -// removed once this reference is no longer useful. -export class PaginatedDragAndDropBitstreamListComponent extends AbstractPaginatedDragAndDropListComponent implements OnInit { - /** - * The bundle to display bitstreams for - */ - @Input() bundle: Bundle; - - /** - * The bootstrap sizes used for the columns within this table - */ - @Input() columnSizes: ResponsiveTableSizes; - - constructor(protected objectUpdatesService: ObjectUpdatesService, - protected elRef: ElementRef, - protected objectValuesPipe: ObjectValuesPipe, - protected bundleService: BundleDataService, - protected paginationService: PaginationService, - protected requestService: RequestService) { - super(objectUpdatesService, elRef, objectValuesPipe, paginationService); - } - - ngOnInit() { - super.ngOnInit(); - } - - /** - * Initialize the bitstreams observable depending on currentPage$ - */ - initializeObjectsRD(): void { - this.objectsRD$ = this.currentPage$.pipe( - switchMap((page: PaginationComponentOptions) => { - const paginatedOptions = new PaginatedSearchOptions({pagination: Object.assign({}, page)}); - return this.bundleService.getBitstreamsEndpoint(this.bundle.id, paginatedOptions).pipe( - switchMap((href) => this.requestService.hasByHref$(href)), - switchMap(() => this.bundleService.getBitstreams( - this.bundle.id, - paginatedOptions, - followLink('format') - )) - ); - }) - ); - } - - /** - * Initialize the URL used for the field-update store, in this case the bundle's self-link - */ - initializeURL(): void { - this.url = this.bundle.self; - } -} diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component.html deleted file mode 100644 index 1bce8667ee1..00000000000 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component.html +++ /dev/null @@ -1,5 +0,0 @@ - -
- -
-
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component.ts deleted file mode 100644 index e5cb9ba4034..00000000000 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-drag-handle/item-edit-bitstream-drag-handle.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Component, OnInit, ViewChild, ViewContainerRef } from '@angular/core'; - -@Component({ - selector: 'ds-item-edit-bitstream-drag-handle', - styleUrls: ['../item-bitstreams.component.scss'], - templateUrl: './item-edit-bitstream-drag-handle.component.html', -}) -/** - * Component displaying a drag handle for the item-edit-bitstream page - * Creates an embedded view of the contents - * (which means it'll be added to the parents html without a wrapping ds-item-edit-bitstream-drag-handle element) - */ -export class ItemEditBitstreamDragHandleComponent implements OnInit { - /** - * The view on the drag-handle - */ - @ViewChild('handleView', {static: true}) handleView; - - constructor(private viewContainerRef: ViewContainerRef) { - } - - ngOnInit(): void { - this.viewContainerRef.createEmbeddedView(this.handleView); - } - -} diff --git a/src/app/shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component.spec.ts b/src/app/shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component.spec.ts deleted file mode 100644 index bac6b89583f..00000000000 --- a/src/app/shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component.spec.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { AbstractPaginatedDragAndDropListComponent } from './abstract-paginated-drag-and-drop-list.component'; -import { DSpaceObject } from '../../core/shared/dspace-object.model'; -import { ObjectUpdatesService } from '../../core/data/object-updates/object-updates.service'; -import { Component, ElementRef } from '@angular/core'; -import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; -import { PaginatedList } from '../../core/data/paginated-list.model'; -import { RemoteData } from '../../core/data/remote-data'; -import { take } from 'rxjs/operators'; -import { PaginationComponent } from '../pagination/pagination.component'; -import { createSuccessfulRemoteDataObject } from '../remote-data.utils'; -import { createPaginatedList } from '../testing/utils.test'; -import { ObjectValuesPipe } from '../utils/object-values-pipe'; -import { PaginationService } from '../../core/pagination/pagination.service'; -import { PaginationServiceStub } from '../testing/pagination-service.stub'; -import { FieldUpdates } from '../../core/data/object-updates/field-updates.model'; - -@Component({ - selector: 'ds-mock-paginated-drag-drop-abstract', - template: '' -}) -class MockAbstractPaginatedDragAndDropListComponent extends AbstractPaginatedDragAndDropListComponent { - - constructor(protected objectUpdatesService: ObjectUpdatesService, - protected elRef: ElementRef, - protected objectValuesPipe: ObjectValuesPipe, - protected mockUrl: string, - protected paginationService: PaginationService, - protected mockObjectsRD$: Observable>>) { - super(objectUpdatesService, elRef, objectValuesPipe, paginationService); - } - - initializeObjectsRD(): void { - this.objectsRD$ = this.mockObjectsRD$; - } - - initializeURL(): void { - this.url = this.mockUrl; - } -} - -describe('AbstractPaginatedDragAndDropListComponent', () => { - let component: MockAbstractPaginatedDragAndDropListComponent; - let objectUpdatesService: ObjectUpdatesService; - let elRef: ElementRef; - let objectValuesPipe: ObjectValuesPipe; - - const url = 'mock-abstract-paginated-drag-and-drop-list-component'; - - - const object1 = Object.assign(new DSpaceObject(), { uuid: 'object-1' }); - const object2 = Object.assign(new DSpaceObject(), { uuid: 'object-2' }); - const objectsRD = createSuccessfulRemoteDataObject(createPaginatedList([object1, object2])); - let objectsRD$: BehaviorSubject>>; - let paginationService; - - const updates = { - [object1.uuid]: { field: object1, changeType: undefined }, - [object2.uuid]: { field: object2, changeType: undefined } - } as FieldUpdates; - - let paginationComponent: PaginationComponent; - - beforeEach(() => { - objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', { - initialize: {}, - getFieldUpdatesExclusive: observableOf(updates) - }); - elRef = { - nativeElement: jasmine.createSpyObj('nativeElement', { - querySelector: {} - }) - }; - objectValuesPipe = new ObjectValuesPipe(); - paginationComponent = jasmine.createSpyObj('paginationComponent', { - doPageChange: {} - }); - paginationService = new PaginationServiceStub(); - objectsRD$ = new BehaviorSubject(objectsRD); - component = new MockAbstractPaginatedDragAndDropListComponent(objectUpdatesService, elRef, objectValuesPipe, url, paginationService, objectsRD$); - component.paginationComponent = paginationComponent; - component.ngOnInit(); - }); - - it('should call initialize to initialize the objects in the store', () => { - expect(objectUpdatesService.initialize).toHaveBeenCalled(); - }); - - it('should initialize the updates correctly', (done) => { - component.updates$.pipe(take(1)).subscribe((fieldUpdates) => { - expect(fieldUpdates).toEqual(updates); - done(); - }); - }); - - describe('drop', () => { - const event = { - previousIndex: 0, - currentIndex: 1, - item: { element: { nativeElement: { id: object1.uuid } } } - } as any; - - describe('when the user is hovering over a new page', () => { - const hoverPage = 3; - const hoverElement = { textContent: '' + hoverPage }; - - beforeEach(() => { - elRef.nativeElement.querySelector.and.returnValue(hoverElement); - spyOn(component.dropObject, 'emit'); - component.drop(event); - }); - - it('should send out a dropObject event with the expected processed paginated indexes', () => { - expect(component.dropObject.emit).toHaveBeenCalledWith(Object.assign({ - fromIndex: ((component.currentPage$.value.currentPage - 1) * component.pageSize) + event.previousIndex, - toIndex: ((hoverPage - 1) * component.pageSize), - finish: jasmine.anything() - })); - }); - }); - - describe('when the user is not hovering over a new page', () => { - beforeEach(() => { - spyOn(component.dropObject, 'emit'); - component.drop(event); - }); - - it('should send out a dropObject event with the expected properties', () => { - expect(component.dropObject.emit).toHaveBeenCalledWith(Object.assign({ - fromIndex: event.previousIndex, - toIndex: event.currentIndex, - finish: jasmine.anything() - })); - }); - }); - }); -}); diff --git a/src/app/shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component.ts b/src/app/shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component.ts deleted file mode 100644 index 8dba47566fa..00000000000 --- a/src/app/shared/pagination-drag-and-drop/abstract-paginated-drag-and-drop-list.component.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { BehaviorSubject, Observable, Subscription } from 'rxjs'; -import { RemoteData } from '../../core/data/remote-data'; -import { PaginatedList } from '../../core/data/paginated-list.model'; -import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; -import { ObjectUpdatesService } from '../../core/data/object-updates/object-updates.service'; -import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; -import { hasValue } from '../empty.util'; -import { - paginatedListToArray, - getFirstSucceededRemoteData, - getAllSucceededRemoteData -} from '../../core/shared/operators'; -import { DSpaceObject } from '../../core/shared/dspace-object.model'; -import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; -import { Component, ElementRef, EventEmitter, OnDestroy, Output, ViewChild } from '@angular/core'; -import { PaginationComponent } from '../pagination/pagination.component'; -import { ObjectValuesPipe } from '../utils/object-values-pipe'; -import { compareArraysUsing } from '../../item-page/simple/item-types/shared/item-relationships-utils'; -import { PaginationService } from '../../core/pagination/pagination.service'; -import { FieldUpdate } from '../../core/data/object-updates/field-update.model'; -import { FieldUpdates } from '../../core/data/object-updates/field-updates.model'; - -/** - * Operator used for comparing {@link FieldUpdate}s by their field's UUID - */ -export const compareArraysUsingFieldUuids = () => - compareArraysUsing((fieldUpdate: FieldUpdate) => (hasValue(fieldUpdate) && hasValue(fieldUpdate.field)) ? fieldUpdate.field.uuid : undefined); - -/** - * An abstract component containing general methods and logic to be able to drag and drop objects within a paginated - * list. This implementation supports being able to drag and drop objects between pages. - * Dragging an object on top of a page number will automatically detect the page it's being dropped on and send a - * dropObject event to the parent component containing detailed information about the indexes the object was dropped from - * and to. - * - * To extend this component, it is important to make sure to: - * - Initialize objectsRD$ within the initializeObjectsRD() method - * - Initialize a unique URL for this component/page within the initializeURL() method - * - Add (cdkDropListDropped)="drop($event)" to the cdkDropList element in your template - * - Add (pageChange)="switchPage($event)" to the ds-pagination element in your template - * - Use the updates$ observable for building your list of cdkDrag elements in your template - * - * An example component extending from this abstract component: PaginatedDragAndDropBitstreamListComponent - */ -@Component({ - selector: 'ds-paginated-drag-drop-abstract', - template: '' -}) -export abstract class AbstractPaginatedDragAndDropListComponent implements OnDestroy { - /** - * A view on the child pagination component - */ - @ViewChild(PaginationComponent) paginationComponent: PaginationComponent; - - /** - * Send an event when the user drops an object on the pagination - * The event contains details about the index the object came from and is dropped to (across the entirety of the list, - * not just within a single page) - */ - @Output() dropObject: EventEmitter = new EventEmitter(); - - /** - * The URL to use for accessing the object updates from this list - */ - url: string; - - /** - * The objects to retrieve data for and transform into field updates - */ - objectsRD$: Observable>>; - - /** - * The updates to the current list - */ - updates$: Observable; - - /** - * A list of object UUIDs - * This is the order the objects will be displayed in - */ - customOrder: string[]; - - /** - * The amount of objects to display per page - */ - pageSize = 10; - - /** - * The page options to use for fetching the objects - * Start at page 1 and always use the set page size - */ - options = Object.assign(new PaginationComponentOptions(),{ - id: 'dad', - currentPage: 1, - pageSize: this.pageSize - }); - - /** - * The current page being displayed - */ - currentPage$ = new BehaviorSubject(this.options); - - /** - * Whether or not we should display a loading animation - * This is used to display a loading page when the user drops a bitstream onto a new page. The loading animation - * should stop once the bitstream has moved to the new page and the new page's response has loaded and contains the - * dropped object on top (see this.stopLoadingWhenFirstIs below) - */ - loading$: BehaviorSubject = new BehaviorSubject(false); - - /** - * List of subscriptions - */ - subs: Subscription[] = []; - - protected constructor(protected objectUpdatesService: ObjectUpdatesService, - protected elRef: ElementRef, - protected objectValuesPipe: ObjectValuesPipe, - protected paginationService: PaginationService - ) { - } - - /** - * Initialize the observables - */ - ngOnInit() { - this.initializeObjectsRD(); - this.initializeURL(); - this.initializeUpdates(); - this.initializePagination(); - } - - /** - * Overwrite this method to define how the list of objects is initialized and updated - */ - abstract initializeObjectsRD(): void; - - /** - * Overwrite this method to define how the URL is set - */ - abstract initializeURL(): void; - - /** - * Initialize the current pagination retrieval from the paginationService and push to the currentPage$ - */ - initializePagination() { - this.paginationService.getCurrentPagination(this.options.id, this.options).subscribe((currentPagination) => { - this.currentPage$.next(currentPagination); - }); - } - - /** - * Initialize the field-updates in the store - */ - initializeUpdates(): void { - this.objectsRD$.pipe( - getFirstSucceededRemoteData(), - paginatedListToArray(), - ).subscribe((objects: T[]) => { - this.objectUpdatesService.initialize(this.url, objects, new Date()); - }); - this.updates$ = this.objectsRD$.pipe( - getAllSucceededRemoteData(), - paginatedListToArray(), - switchMap((objects: T[]) => this.objectUpdatesService.getFieldUpdatesExclusive(this.url, objects)) - ); - this.subs.push( - this.updates$.pipe( - map((fieldUpdates) => this.objectValuesPipe.transform(fieldUpdates)), - distinctUntilChanged(compareArraysUsingFieldUuids()) - ).subscribe((updateValues) => { - this.customOrder = updateValues.map((fieldUpdate) => fieldUpdate.field.uuid); - // We received new values, stop displaying a loading indicator if it's present - this.loading$.next(false); - }), - // Disable the pagination when objects are loading - this.loading$.subscribe((loading) => this.options.disabled = loading) - ); - } - - /** - * An object was moved, send updates to the dropObject EventEmitter - * When the object is dropped on a page within the pagination of this component, the object moves to the top of that - * page and the pagination automatically loads and switches the view to that page (this is done by calling the event's - * finish() method after sending patch requests to the REST API) - * @param event - */ - drop(event: CdkDragDrop) { - const dragIndex = event.previousIndex; - let dropIndex = event.currentIndex; - const dragPage = this.currentPage$.value.currentPage - 1; - let dropPage = this.currentPage$.value.currentPage - 1; - - // Check if the user is hovering over any of the pagination's pages at the time of dropping the object - const droppedOnElement = this.elRef.nativeElement.querySelector('.page-item:hover'); - if (hasValue(droppedOnElement) && hasValue(droppedOnElement.textContent)) { - // The user is hovering over a page, fetch the page's number from the element - const droppedPage = Number(droppedOnElement.textContent); - if (hasValue(droppedPage) && !Number.isNaN(droppedPage)) { - dropPage = droppedPage - 1; - dropIndex = 0; - } - } - - const isNewPage = dragPage !== dropPage; - // Move the object in the custom order array if the drop happened within the same page - // This allows us to instantly display a change in the order, instead of waiting for the REST API's response first - if (!isNewPage && dragIndex !== dropIndex) { - moveItemInArray(this.customOrder, dragIndex, dropIndex); - } - - const redirectPage = dropPage + 1; - const fromIndex = (dragPage * this.pageSize) + dragIndex; - const toIndex = (dropPage * this.pageSize) + dropIndex; - // Send out a drop event (and navigate to the new page) when the "from" and "to" indexes are different from each other - if (fromIndex !== toIndex) { - if (isNewPage) { - this.loading$.next(true); - } - this.dropObject.emit(Object.assign({ - fromIndex, - toIndex, - finish: () => { - if (isNewPage) { - this.paginationComponent.doPageChange(redirectPage); - } - } - })); - } - } - - /** - * unsub all subscriptions - */ - ngOnDestroy(): void { - this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe()); - this.paginationService.clearPagination(this.options.id); - } -} From 85f1ba21769a6fe2df07c6840fc63e5a0862ea7d Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 1 Oct 2024 13:12:10 +0200 Subject: [PATCH 112/822] Always sanitize HTML in dsMarkdown even if markdown disabled Instead of setting innerHTML directly to value, sanitize the value, even if not passing to renderMarkdown/Mathjax (cherry picked from commit 8fb4772b6c6308d2ba9e358e2858244105064c7f) --- .../shared/utils/markdown.directive.spec.ts | 58 +++++++++++++++++-- src/app/shared/utils/markdown.directive.ts | 2 +- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/app/shared/utils/markdown.directive.spec.ts b/src/app/shared/utils/markdown.directive.spec.ts index 79e795be876..b984543c40d 100644 --- a/src/app/shared/utils/markdown.directive.spec.ts +++ b/src/app/shared/utils/markdown.directive.spec.ts @@ -8,21 +8,20 @@ import { } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; +import { environment } from '../../../environments/environment.test'; import { MathService } from '../../core/shared/math.service'; import { MockMathService } from '../../core/shared/math.service.spec'; import { MarkdownDirective } from './markdown.directive'; @Component({ - template: `
`, + template: `
`, standalone: true, imports: [ MarkdownDirective ], }) class TestComponent {} describe('MarkdownDirective', () => { - let component: TestComponent; let fixture: ComponentFixture; - let divEl: DebugElement; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -32,12 +31,61 @@ describe('MarkdownDirective', () => { }).compileComponents(); spyOn(MarkdownDirective.prototype, 'render'); fixture = TestBed.createComponent(TestComponent); - component = fixture.componentInstance; - divEl = fixture.debugElement.query(By.css('div')); }); it('should call render method', () => { fixture.detectChanges(); expect(MarkdownDirective.prototype.render).toHaveBeenCalled(); }); + +}); + +describe('MarkdownDirective sanitization with markdown disabled', () => { + let fixture: ComponentFixture; + let divEl: DebugElement; + // Disable markdown + environment.markdown.enabled = false; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + providers: [ + { provide: MathService, useClass: MockMathService }, + ], + }).compileComponents(); + fixture = TestBed.createComponent(TestComponent); + divEl = fixture.debugElement.query(By.css('div')); + + }); + + it('should sanitize the script element out of innerHTML (markdown disabled)',() => { + fixture.detectChanges(); + divEl = fixture.debugElement.query(By.css('div')); + expect(divEl.nativeElement.innerHTML).toEqual('test'); + }); + +}); + +describe('MarkdownDirective sanitization with markdown enabled', () => { + let fixture: ComponentFixture; + let divEl: DebugElement; + // Enable markdown + environment.markdown.enabled = true; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + providers: [ + { provide: MathService, useClass: MockMathService }, + ], + }).compileComponents(); + fixture = TestBed.createComponent(TestComponent); + divEl = fixture.debugElement.query(By.css('div')); + + }); + + it('should sanitize the script element out of innerHTML (markdown enabled)',() => { + fixture.detectChanges(); + divEl = fixture.debugElement.query(By.css('div')); + expect(divEl.nativeElement.innerHTML).toEqual('test'); + }); + }); diff --git a/src/app/shared/utils/markdown.directive.ts b/src/app/shared/utils/markdown.directive.ts index 0540e25cc54..de13acb3036 100644 --- a/src/app/shared/utils/markdown.directive.ts +++ b/src/app/shared/utils/markdown.directive.ts @@ -55,7 +55,7 @@ export class MarkdownDirective implements OnInit, OnDestroy { async render(value: string, forcePreview = false): Promise { if (isEmpty(value) || (!environment.markdown.enabled && !forcePreview)) { - this.el.innerHTML = value; + this.el.innerHTML = this.sanitizer.sanitize(SecurityContext.HTML, value); return; } else { if (environment.markdown.mathjax) { From 876d94e124cf11477a5548f11f095bc129c4b313 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Wed, 2 Oct 2024 09:23:26 +0200 Subject: [PATCH 113/822] 115284: Add tests for isRepeatable --- .../edit-relationship-list.component.spec.ts | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts index 312f2936ac7..69a2340fd56 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts @@ -78,7 +78,7 @@ describe('EditRelationshipListComponent', () => { fixture.detectChanges(); }; - function init(leftType: string, rightType: string): void { + function init(leftType: string, rightType: string, leftMaxCardinality?: number, rightMaxCardinality?: number): void { entityTypeLeft = Object.assign(new ItemType(), { id: leftType, uuid: leftType, @@ -98,6 +98,8 @@ describe('EditRelationshipListComponent', () => { rightType: createSuccessfulRemoteDataObject$(entityTypeRight), leftwardType: `is${rightType}Of${leftType}`, rightwardType: `is${leftType}Of${rightType}`, + leftMaxCardinality: leftMaxCardinality, + rightMaxCardinality: rightMaxCardinality, }); paginationOptions = Object.assign(new PaginationComponentOptions(), { @@ -367,4 +369,31 @@ describe('EditRelationshipListComponent', () => { })); }); }); + + describe('Is repeatable relationship', () => { + beforeEach(waitForAsync(() => { + currentItemIsLeftItem$ = new BehaviorSubject(true); + })); + describe('when max cardinality is 1', () => { + beforeEach(waitForAsync(() => init('Publication', 'OrgUnit', 1, undefined))); + it('should return false', () => { + const result = (comp as any).isRepeatable(); + expect(result).toBeFalse(); + }); + }); + describe('when max cardinality is 2', () => { + beforeEach(waitForAsync(() => init('Publication', 'OrgUnit', 2, undefined))); + it('should return true', () => { + const result = (comp as any).isRepeatable(); + expect(result).toBeTrue(); + }); + }); + describe('when max cardinality is undefined', () => { + beforeEach(waitForAsync(() => init('Publication', 'OrgUnit', undefined, undefined))); + it('should return true', () => { + const result = (comp as any).isRepeatable(); + expect(result).toBeTrue(); + }); + }); + }); }); From 01d09810ba045affc083fdf0398930231a80d51a Mon Sep 17 00:00:00 2001 From: root Date: Wed, 26 Jun 2024 08:29:32 -0300 Subject: [PATCH 114/822] Resolution of issue #1190 - Improving the accessibility of the status page using the item-operation component (cherry picked from commit e06b67fd73358ac52e2e71fa96d708520de33f3e) --- .../item-operation/item-operation.component.html | 4 ++-- .../item-operation/item-operation.component.scss | 9 +++++++++ .../item-operation/item-operation.component.ts | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/app/item-page/edit-item-page/item-operation/item-operation.component.scss diff --git a/src/app/item-page/edit-item-page/item-operation/item-operation.component.html b/src/app/item-page/edit-item-page/item-operation/item-operation.component.html index 85c6a2cca18..e2820173152 100644 --- a/src/app/item-page/edit-item-page/item-operation/item-operation.component.html +++ b/src/app/item-page/edit-item-page/item-operation/item-operation.component.html @@ -1,9 +1,9 @@ -
+
{{'item.edit.tabs.status.buttons.' + operation.operationKey + '.label' | translate}}
-
+
{{tableEntry.info}} diff --git a/src/styles/_global-styles.scss b/src/styles/_global-styles.scss index 765b50ae866..b3120c08cd1 100644 --- a/src/styles/_global-styles.scss +++ b/src/styles/_global-styles.scss @@ -466,3 +466,11 @@ ngb-accordion { .mt-ncs { margin-top: calc(var(--ds-content-spacing) * -1); } .mb-ncs { margin-bottom: calc(var(--ds-content-spacing) * -1); } .my-ncs { margin-top: calc(var(--ds-content-spacing) * -1); margin-bottom: calc(var(--ds-content-spacing) * -1); } + + +.link-contrast { + // Rules for accessibility to meet minimum contrast and have an identifiable link between other texts + color: darken($link-color, 5%); + // We use underline to discern link from text as we can't make color lighter on a white bg + text-decoration: underline; +} From 75981cf46e5f10d3186b45c363b86f2749c6a0d9 Mon Sep 17 00:00:00 2001 From: FrancescoMolinaro Date: Tue, 23 Jul 2024 17:13:20 +0200 Subject: [PATCH 129/822] [CST-15592] improve tests, add attributes for testing, fix wrong references (cherry picked from commit 69f618e8566445b800b83bcc4604bd2e59a98b28) --- cypress/e2e/admin-add-new-modals.cy.ts | 6 ++-- cypress/e2e/admin-edit-modals.cy.ts | 6 ++-- cypress/e2e/admin-export-modals.cy.ts | 4 +-- cypress/e2e/admin-search-page.cy.ts | 3 ++ cypress/e2e/admin-workflow-page.cy.ts | 3 ++ cypress/e2e/bulk-access.cy.ts | 7 +++++ cypress/e2e/health-page.cy.ts | 29 +++++++++++++++---- .../health-page/health-page.component.html | 4 +-- .../onclick-menu-item.component.html | 3 +- 9 files changed, 49 insertions(+), 16 deletions(-) diff --git a/cypress/e2e/admin-add-new-modals.cy.ts b/cypress/e2e/admin-add-new-modals.cy.ts index 6e2e8e69708..565ae154f1e 100644 --- a/cypress/e2e/admin-add-new-modals.cy.ts +++ b/cypress/e2e/admin-add-new-modals.cy.ts @@ -14,7 +14,7 @@ describe('Admin Add New Modals', () => { // Click on entry of menu cy.get('#admin-menu-section-new-title').click(); - cy.get('a[title="menu.section.new_community"]').click(); + cy.get('a[data-test="menu.section.new_community"]').click(); // Analyze for accessibility testA11y('ds-create-community-parent-selector'); @@ -27,7 +27,7 @@ describe('Admin Add New Modals', () => { // Click on entry of menu cy.get('#admin-menu-section-new-title').click(); - cy.get('a[title="menu.section.new_collection"]').click(); + cy.get('a[data-test="menu.section.new_collection"]').click(); // Analyze for accessibility testA11y('ds-create-collection-parent-selector'); @@ -40,7 +40,7 @@ describe('Admin Add New Modals', () => { // Click on entry of menu cy.get('#admin-menu-section-new-title').click(); - cy.get('a[title="menu.section.new_item"]').click(); + cy.get('a[data-test="menu.section.new_item"]').click(); // Analyze for accessibility testA11y('ds-create-item-parent-selector'); diff --git a/cypress/e2e/admin-edit-modals.cy.ts b/cypress/e2e/admin-edit-modals.cy.ts index 256a6d89cb3..e96d6ce898c 100644 --- a/cypress/e2e/admin-edit-modals.cy.ts +++ b/cypress/e2e/admin-edit-modals.cy.ts @@ -14,7 +14,7 @@ describe('Admin Edit Modals', () => { // Click on entry of menu cy.get('#admin-menu-section-edit-title').click(); - cy.get('a[title="menu.section.edit_community"]').click(); + cy.get('a[data-test="menu.section.edit_community"]').click(); // Analyze for accessibility testA11y('ds-edit-community-selector'); @@ -27,7 +27,7 @@ describe('Admin Edit Modals', () => { // Click on entry of menu cy.get('#admin-menu-section-edit-title').click(); - cy.get('a[title="menu.section.edit_collection"]').click(); + cy.get('a[data-test="menu.section.edit_collection"]').click(); // Analyze for accessibility testA11y('ds-edit-collection-selector'); @@ -40,7 +40,7 @@ describe('Admin Edit Modals', () => { // Click on entry of menu cy.get('#admin-menu-section-edit-title').click(); - cy.get('a[title="menu.section.edit_item"]').click(); + cy.get('a[data-test="menu.section.edit_item"]').click(); // Analyze for accessibility testA11y('ds-edit-item-selector'); diff --git a/cypress/e2e/admin-export-modals.cy.ts b/cypress/e2e/admin-export-modals.cy.ts index b611bb8fd51..9f69764d197 100644 --- a/cypress/e2e/admin-export-modals.cy.ts +++ b/cypress/e2e/admin-export-modals.cy.ts @@ -14,7 +14,7 @@ describe('Admin Export Modals', () => { // Click on entry of menu cy.get('#admin-menu-section-export-title').click(); - cy.get('a[title="menu.section.export_metadata"]').click(); + cy.get('a[data-test="menu.section.export_metadata"]').click(); // Analyze for accessibility testA11y('ds-export-metadata-selector'); @@ -27,7 +27,7 @@ describe('Admin Export Modals', () => { // Click on entry of menu cy.get('#admin-menu-section-export-title').click(); - cy.get('a[title="menu.section.export_batch"]').click(); + cy.get('a[data-test="menu.section.export_batch"]').click(); // Analyze for accessibility testA11y('ds-export-batch-selector'); diff --git a/cypress/e2e/admin-search-page.cy.ts b/cypress/e2e/admin-search-page.cy.ts index 2e1d13aa132..4fbf8939fe4 100644 --- a/cypress/e2e/admin-search-page.cy.ts +++ b/cypress/e2e/admin-search-page.cy.ts @@ -12,6 +12,9 @@ describe('Admin Search Page', () => { cy.get('ds-admin-search-page').should('be.visible'); // At least one search result should be displayed cy.get('[data-test="list-object"]').should('be.visible'); + // Click each filter toggle to open *every* filter + // (As we want to scan filter section for accessibility issues as well) + cy.get('[data-test="filter-toggle"]').click({ multiple: true }); // Analyze for accessibility issues testA11y('ds-admin-search-page'); }); diff --git a/cypress/e2e/admin-workflow-page.cy.ts b/cypress/e2e/admin-workflow-page.cy.ts index cd2275f5845..c3c235e346d 100644 --- a/cypress/e2e/admin-workflow-page.cy.ts +++ b/cypress/e2e/admin-workflow-page.cy.ts @@ -12,6 +12,9 @@ describe('Admin Workflow Page', () => { cy.get('ds-admin-workflow-page').should('be.visible'); // At least one search result should be displayed cy.get('[data-test="list-object"]').should('be.visible'); + // Click each filter toggle to open *every* filter + // (As we want to scan filter section for accessibility issues as well) + cy.get('[data-test="filter-toggle"]').click({ multiple: true }); // Analyze for accessibility issues testA11y('ds-admin-workflow-page'); }); diff --git a/cypress/e2e/bulk-access.cy.ts b/cypress/e2e/bulk-access.cy.ts index 4d199f53f9c..87033e13e4f 100644 --- a/cypress/e2e/bulk-access.cy.ts +++ b/cypress/e2e/bulk-access.cy.ts @@ -11,6 +11,11 @@ describe('Bulk Access', () => { it('should pass accessibility tests', () => { // Page must first be visible cy.get('ds-bulk-access').should('be.visible'); + // At least one search result should be displayed + cy.get('[data-test="list-object"]').should('be.visible'); + // Click each filter toggle to open *every* filter + // (As we want to scan filter section for accessibility issues as well) + cy.get('[data-test="filter-toggle"]').click({ multiple: true }); // Analyze for accessibility issues testA11y('ds-bulk-access', { rules: { @@ -18,6 +23,8 @@ describe('Bulk Access', () => { // Seem to require updating ng-bootstrap and https://github.com/DSpace/dspace-angular/issues/2216 'aria-required-children': { enabled: false }, 'nested-interactive': { enabled: false }, + // Card titles fail this test currently + 'heading-order': { enabled: false }, }, } as Options); }); diff --git a/cypress/e2e/health-page.cy.ts b/cypress/e2e/health-page.cy.ts index 91c68638eac..79ebf4bc047 100644 --- a/cypress/e2e/health-page.cy.ts +++ b/cypress/e2e/health-page.cy.ts @@ -1,16 +1,35 @@ import { testA11y } from 'cypress/support/utils'; import { Options } from 'cypress-axe'; -describe('Health Page', () => { - beforeEach(() => { - // Must login as an Admin to see the page - cy.visit('/health'); - cy.loginViaForm(Cypress.env('DSPACE_TEST_ADMIN_USER'), Cypress.env('DSPACE_TEST_ADMIN_PASSWORD')); + +beforeEach(() => { + // Must login as an Admin to see the page + cy.visit('/health'); + cy.loginViaForm(Cypress.env('DSPACE_TEST_ADMIN_USER'), Cypress.env('DSPACE_TEST_ADMIN_PASSWORD')); +}); + +describe('Health Page > Status Tab', () => { + it('should pass accessibility tests', () => { + // Page must first be visible + cy.get('ds-health-page').should('be.visible'); + // Analyze for accessibility issues + testA11y('ds-health-page', { + rules: { + // All panels are accordians & fail "aria-required-children" and "nested-interactive". + // Seem to require updating ng-bootstrap and https://github.com/DSpace/dspace-angular/issues/2216 + 'aria-required-children': { enabled: false }, + 'nested-interactive': { enabled: false }, + }, + } as Options); }); +}); +describe('Health Page > Info Tab', () => { it('should pass accessibility tests', () => { // Page must first be visible cy.get('ds-health-page').should('be.visible'); + cy.get('a[data-test="health-page.info-tab"]').click(); + // Analyze for accessibility issues testA11y('ds-health-page', { rules: { diff --git a/src/app/health-page/health-page.component.html b/src/app/health-page/health-page.component.html index d8cba1d46d7..797ca0bc6e2 100644 --- a/src/app/health-page/health-page.component.html +++ b/src/app/health-page/health-page.component.html @@ -3,7 +3,7 @@

{{'health-page.heading' | translate}}

-
* {{ "item.version.history.selected" | translate }}
+
* {{"item.version.history.selected" | translate}}
From 5619d6bc4c7c259a9b72c2f37710c3bf3932d117 Mon Sep 17 00:00:00 2001 From: Andrea Barbasso <´andrea.barbasso@4science.com´> Date: Mon, 15 Apr 2024 09:43:38 +0200 Subject: [PATCH 173/822] [DURACOM-248] set function call result in a class attribute (cherry picked from commit 87cff6c90792553b2170e6a9326fdabdd478456c) --- src/app/item-page/versions/item-versions.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/item-page/versions/item-versions.component.html b/src/app/item-page/versions/item-versions.component.html index 745f8354923..6184b42aa8b 100644 --- a/src/app/item-page/versions/item-versions.component.html +++ b/src/app/item-page/versions/item-versions.component.html @@ -15,7 +15,7 @@

{{"item.version.history.head" | translate}}<

{{ "item.version.history.table.version" | translate }}{{ "item.version.history.table.editor" | translate }}{{ "item.version.history.table.editor" | translate }} {{ "item.version.history.table.date" | translate }} {{ "item.version.history.table.summary" | translate }}
+ {{ versionDTO.version.submitterName }} From b709ee03000086cd52f5de9bc67d5619a64df29d Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 11 Oct 2024 14:59:34 +0200 Subject: [PATCH 174/822] 118944: Embed the accessStatus link on collection, browse, recent item submissions & the item page related items & delete tab when enabled --- .../collection-page.component.ts | 4 +-- .../breadcrumbs/item-breadcrumb.resolver.ts | 4 +-- src/app/core/browse/browse.service.spec.ts | 12 -------- src/app/core/browse/browse.service.ts | 19 ++++++++----- .../data/relationship-data.service.spec.ts | 4 ++- .../core/data/relationship-data.service.ts | 4 ++- .../recent-item-list.component.ts | 3 ++ .../abstract-item-update.component.ts | 4 +-- .../item-delete/item-delete.component.ts | 4 +-- .../edit-relationship-list.component.spec.ts | 5 ++-- .../edit-relationship-list.component.ts | 2 +- src/app/item-page/item.resolver.ts | 27 +++++++++++------- ...ynamic-form-control-container.component.ts | 2 +- src/app/shared/utils/relation-query.utils.ts | 28 +++++++++++-------- 14 files changed, 67 insertions(+), 55 deletions(-) diff --git a/src/app/collection-page/collection-page.component.ts b/src/app/collection-page/collection-page.component.ts index 16704cef52e..e74db09f248 100644 --- a/src/app/collection-page/collection-page.component.ts +++ b/src/app/collection-page/collection-page.component.ts @@ -28,7 +28,7 @@ import { AuthorizationDataService } from '../core/data/feature-authorization/aut import { FeatureID } from '../core/data/feature-authorization/feature-id'; import { getCollectionPageRoute } from './collection-page-routing-paths'; import { redirectOn4xx } from '../core/shared/authorized.operators'; -import { BROWSE_LINKS_TO_FOLLOW } from '../core/browse/browse.service'; +import { getBrowseLinksToFollow } from '../core/browse/browse.service'; import { DSONameService } from '../core/breadcrumbs/dso-name.service'; import { APP_CONFIG, AppConfig } from '../../../src/config/app-config.interface'; @@ -115,7 +115,7 @@ export class CollectionPageComponent implements OnInit { pagination: currentPagination, sort: currentSort, dsoTypes: [DSpaceObjectType.ITEM] - }), null, true, true, ...BROWSE_LINKS_TO_FOLLOW) + }), null, true, true, ...getBrowseLinksToFollow()) .pipe(toDSpaceObjectListRD()) as Observable>>; }), startWith(undefined) // Make sure switching pages shows loading component diff --git a/src/app/core/breadcrumbs/item-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/item-breadcrumb.resolver.ts index 3005b6f09ac..f396fd08dda 100644 --- a/src/app/core/breadcrumbs/item-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/item-breadcrumb.resolver.ts @@ -4,7 +4,7 @@ import { ItemDataService } from '../data/item-data.service'; import { Item } from '../shared/item.model'; import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; -import { ITEM_PAGE_LINKS_TO_FOLLOW } from '../../item-page/item.resolver'; +import { getItemPageLinksToFollow } from '../../item-page/item.resolver'; /** * The class that resolves the BreadcrumbConfig object for an Item @@ -23,6 +23,6 @@ export class ItemBreadcrumbResolver extends DSOBreadcrumbResolver { * Requesting them as embeds will limit the number of requests */ get followLinks(): FollowLinkConfig[] { - return ITEM_PAGE_LINKS_TO_FOLLOW; + return getItemPageLinksToFollow(); } } diff --git a/src/app/core/browse/browse.service.spec.ts b/src/app/core/browse/browse.service.spec.ts index 9f166e3d19d..f7027fc91e1 100644 --- a/src/app/core/browse/browse.service.spec.ts +++ b/src/app/core/browse/browse.service.spec.ts @@ -1,10 +1,8 @@ import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { of as observableOf } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; -import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; -import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RequestService } from '../data/request.service'; import { BrowseEntrySearchOptions } from './browse-entry-search-options.model'; import { BrowseService } from './browse.service'; @@ -20,7 +18,6 @@ describe('BrowseService', () => { let scheduler: TestScheduler; let service: BrowseService; let requestService: RequestService; - let rdbService: RemoteDataBuildService; const browsesEndpointURL = 'https://rest.api/browses'; const halService: any = new HALEndpointServiceStub(browsesEndpointURL); @@ -118,7 +115,6 @@ describe('BrowseService', () => { halService, browseDefinitionDataService, hrefOnlyDataService, - rdbService ); } @@ -130,11 +126,9 @@ describe('BrowseService', () => { beforeEach(() => { requestService = getMockRequestService(getRequestEntry$(true)); - rdbService = getMockRemoteDataBuildService(); service = initTestService(); spyOn(halService, 'getEndpoint').and .returnValue(hot('--a-', { a: browsesEndpointURL })); - spyOn(rdbService, 'buildList').and.callThrough(); }); it('should call BrowseDefinitionDataService to create the RemoteData Observable', () => { @@ -151,9 +145,7 @@ describe('BrowseService', () => { beforeEach(() => { requestService = getMockRequestService(getRequestEntry$(true)); - rdbService = getMockRemoteDataBuildService(); service = initTestService(); - spyOn(rdbService, 'buildList').and.callThrough(); }); describe('when getBrowseEntriesFor is called with a valid browse definition id', () => { @@ -204,7 +196,6 @@ describe('BrowseService', () => { describe('if getBrowseDefinitions fires', () => { beforeEach(() => { requestService = getMockRequestService(getRequestEntry$(true)); - rdbService = getMockRemoteDataBuildService(); service = initTestService(); spyOn(service, 'getBrowseDefinitions').and .returnValue(hot('--a-', { @@ -259,7 +250,6 @@ describe('BrowseService', () => { describe('if getBrowseDefinitions doesn\'t fire', () => { it('should return undefined', () => { requestService = getMockRequestService(getRequestEntry$(true)); - rdbService = getMockRemoteDataBuildService(); service = initTestService(); spyOn(service, 'getBrowseDefinitions').and .returnValue(hot('----')); @@ -277,9 +267,7 @@ describe('BrowseService', () => { describe('getFirstItemFor', () => { beforeEach(() => { requestService = getMockRequestService(); - rdbService = getMockRemoteDataBuildService(); service = initTestService(); - spyOn(rdbService, 'buildList').and.callThrough(); }); describe('when getFirstItemFor is called with a valid browse definition id', () => { diff --git a/src/app/core/browse/browse.service.ts b/src/app/core/browse/browse.service.ts index b210b349494..2d8dd4b80f6 100644 --- a/src/app/core/browse/browse.service.ts +++ b/src/app/core/browse/browse.service.ts @@ -2,7 +2,6 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { distinctUntilChanged, map, startWith } from 'rxjs/operators'; import { hasValue, hasValueOperator, isEmpty, isNotEmpty } from '../../shared/empty.util'; -import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { PaginatedList } from '../data/paginated-list.model'; import { RemoteData } from '../data/remote-data'; import { RequestService } from '../data/request.service'; @@ -24,11 +23,18 @@ import { HrefOnlyDataService } from '../data/href-only-data.service'; import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { BrowseDefinitionDataService } from './browse-definition-data.service'; import { SortDirection } from '../cache/models/sort-options.model'; +import { environment } from '../../../environments/environment'; -export const BROWSE_LINKS_TO_FOLLOW: FollowLinkConfig[] = [ - followLink('thumbnail') -]; +export function getBrowseLinksToFollow(): FollowLinkConfig[] { + const followLinks = [ + followLink('thumbnail'), + ]; + if (environment.item.showAccessStatuses) { + followLinks.push(followLink('accessStatus')); + } + return followLinks; +} /** * The service handling all browse requests @@ -55,7 +61,6 @@ export class BrowseService { protected halService: HALEndpointService, private browseDefinitionDataService: BrowseDefinitionDataService, private hrefOnlyDataService: HrefOnlyDataService, - private rdb: RemoteDataBuildService, ) { } @@ -105,7 +110,7 @@ export class BrowseService { }) ); if (options.fetchThumbnail ) { - return this.hrefOnlyDataService.findListByHref(href$, {}, null, null, ...BROWSE_LINKS_TO_FOLLOW); + return this.hrefOnlyDataService.findListByHref(href$, {}, null, null, ...getBrowseLinksToFollow()); } return this.hrefOnlyDataService.findListByHref(href$); } @@ -153,7 +158,7 @@ export class BrowseService { }), ); if (options.fetchThumbnail) { - return this.hrefOnlyDataService.findListByHref(href$, {}, null, null, ...BROWSE_LINKS_TO_FOLLOW); + return this.hrefOnlyDataService.findListByHref(href$, {}, null, null, ...getBrowseLinksToFollow()); } return this.hrefOnlyDataService.findListByHref(href$); } diff --git a/src/app/core/data/relationship-data.service.spec.ts b/src/app/core/data/relationship-data.service.spec.ts index 4432d5213ae..fd24c0665bc 100644 --- a/src/app/core/data/relationship-data.service.spec.ts +++ b/src/app/core/data/relationship-data.service.spec.ts @@ -23,6 +23,7 @@ import { FindListOptions } from './find-list-options.model'; import { testSearchDataImplementation } from './base/search-data.spec'; import { MetadataValue } from '../shared/metadata.models'; import { MetadataRepresentationType } from '../shared/metadata-representation/metadata-representation.model'; +import { environment } from '../../../environments/environment.test'; describe('RelationshipDataService', () => { let service: RelationshipDataService; @@ -137,6 +138,7 @@ describe('RelationshipDataService', () => { itemService, null, jasmine.createSpy('paginatedRelationsToItems').and.returnValue((v) => v), + environment, ); } @@ -152,7 +154,7 @@ describe('RelationshipDataService', () => { }); describe('composition', () => { - const initService = () => new RelationshipDataService(null, null, null, null, null, null, null); + const initService = () => new RelationshipDataService(null, null, null, null, null, null, null, environment); testSearchDataImplementation(initService); }); diff --git a/src/app/core/data/relationship-data.service.ts b/src/app/core/data/relationship-data.service.ts index 46a51a2d010..7620f8ab756 100644 --- a/src/app/core/data/relationship-data.service.ts +++ b/src/app/core/data/relationship-data.service.ts @@ -51,6 +51,7 @@ import { MetadataRepresentation } from '../shared/metadata-representation/metada import { MetadatumRepresentation } from '../shared/metadata-representation/metadatum/metadatum-representation.model'; import { ItemMetadataRepresentation } from '../shared/metadata-representation/item/item-metadata-representation.model'; import { DSpaceObject } from '../shared/dspace-object.model'; +import { APP_CONFIG, AppConfig } from '../../../config/app-config.interface'; const relationshipListsStateSelector = (state: AppState) => state.relationshipLists; @@ -92,6 +93,7 @@ export class RelationshipDataService extends IdentifiableDataService, @Inject(PAGINATED_RELATIONS_TO_ITEMS_OPERATOR) private paginatedRelationsToItems: (thisId: string) => (source: Observable>>) => Observable>>, + @Inject(APP_CONFIG) private appConfig: AppConfig, ) { super('relationships', requestService, rdbService, objectCache, halService, 15 * 60 * 1000); @@ -264,7 +266,7 @@ export class RelationshipDataService extends IdentifiableDataService>> { - let linksToFollow: FollowLinkConfig[] = itemLinksToFollow(options.fetchThumbnail); + let linksToFollow: FollowLinkConfig[] = itemLinksToFollow(options.fetchThumbnail, this.appConfig.item.showAccessStatuses); linksToFollow.push(followLink('relationshipType')); return this.getItemRelationshipsByLabel(item, label, options, true, true, ...linksToFollow).pipe(this.paginatedRelationsToItems(item.uuid)); diff --git a/src/app/home-page/recent-item-list/recent-item-list.component.ts b/src/app/home-page/recent-item-list/recent-item-list.component.ts index 9a8535d970a..da7d8141e36 100644 --- a/src/app/home-page/recent-item-list/recent-item-list.component.ts +++ b/src/app/home-page/recent-item-list/recent-item-list.component.ts @@ -64,6 +64,9 @@ export class RecentItemListComponent implements OnInit { if (this.appConfig.browseBy.showThumbnails) { linksToFollow.push(followLink('thumbnail')); } + if (this.appConfig.item.showAccessStatuses) { + linksToFollow.push(followLink('accessStatus')); + } this.itemRD$ = this.searchService.search( new PaginatedSearchOptions({ diff --git a/src/app/item-page/edit-item-page/abstract-item-update/abstract-item-update.component.ts b/src/app/item-page/edit-item-page/abstract-item-update/abstract-item-update.component.ts index 80002f614b6..3a076323460 100644 --- a/src/app/item-page/edit-item-page/abstract-item-update/abstract-item-update.component.ts +++ b/src/app/item-page/edit-item-page/abstract-item-update/abstract-item-update.component.ts @@ -13,7 +13,7 @@ import { environment } from '../../../../environments/environment'; import { getItemPageRoute } from '../../item-page-routing-paths'; import { getAllSucceededRemoteData } from '../../../core/shared/operators'; import { hasValue } from '../../../shared/empty.util'; -import { ITEM_PAGE_LINKS_TO_FOLLOW } from '../../item.resolver'; +import { getItemPageLinksToFollow } from '../../item.resolver'; import { FieldUpdate } from '../../../core/data/object-updates/field-update.model'; import { FieldUpdates } from '../../../core/data/object-updates/field-updates.model'; @@ -72,7 +72,7 @@ export class AbstractItemUpdateComponent extends AbstractTrackableComponent impl this.item = rd.payload; }), switchMap((rd: RemoteData) => { - return this.itemService.findByHref(rd.payload._links.self.href, true, true, ...ITEM_PAGE_LINKS_TO_FOLLOW); + return this.itemService.findByHref(rd.payload._links.self.href, true, true, ...getItemPageLinksToFollow()); }), getAllSucceededRemoteData() ).subscribe((rd: RemoteData) => { diff --git a/src/app/item-page/edit-item-page/item-delete/item-delete.component.ts b/src/app/item-page/edit-item-page/item-delete/item-delete.component.ts index 9012ebe7d75..8b26b71fef3 100644 --- a/src/app/item-page/edit-item-page/item-delete/item-delete.component.ts +++ b/src/app/item-page/edit-item-page/item-delete/item-delete.component.ts @@ -236,8 +236,8 @@ export class ItemDeleteComponent this.linkService.resolveLinks( relationship, followLink('relationshipType'), - followLink('leftItem'), - followLink('rightItem'), + followLink('leftItem', undefined, followLink('accessStatus')), + followLink('rightItem', undefined, followLink('accessStatus')), ); return relationship.relationshipType.pipe( getFirstSucceededRemoteData(), diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts index 4cd663f0fbc..29851c9e936 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts @@ -32,6 +32,7 @@ import { ConfigurationProperty } from '../../../../core/shared/configuration-pro import { Router } from '@angular/router'; import { RouterMock } from '../../../../shared/mocks/router.mock'; import { APP_CONFIG } from '../../../../../config/app-config.interface'; +import { environment } from '../../../../../environments/environment.test'; let comp: EditRelationshipListComponent; let fixture: ComponentFixture; @@ -202,11 +203,11 @@ describe('EditRelationshipListComponent', () => { })) }); - const environmentUseThumbs = { + const environmentUseThumbs = Object.assign({}, environment, { browseBy: { showThumbnails: true } - }; + }); TestBed.configureTestingModule({ imports: [SharedModule, TranslateModule.forRoot()], diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts index b8542f5806f..b27e57f7738 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts @@ -493,7 +493,7 @@ export class EditRelationshipListComponent implements OnInit, OnDestroy { ); // this adds thumbnail images when required by configuration - let linksToFollow: FollowLinkConfig[] = itemLinksToFollow(this.fetchThumbnail); + let linksToFollow: FollowLinkConfig[] = itemLinksToFollow(this.fetchThumbnail, this.appConfig.item.showAccessStatuses); this.subs.push( observableCombineLatest([ diff --git a/src/app/item-page/item.resolver.ts b/src/app/item-page/item.resolver.ts index ca6a6c5958c..ffeef57ecb0 100644 --- a/src/app/item-page/item.resolver.ts +++ b/src/app/item-page/item.resolver.ts @@ -8,20 +8,27 @@ import { followLink, FollowLinkConfig } from '../shared/utils/follow-link-config import { getFirstCompletedRemoteData } from '../core/shared/operators'; import { Store } from '@ngrx/store'; import { ResolvedAction } from '../core/resolving/resolver.actions'; +import { environment } from '../../environments/environment'; /** * The self links defined in this list are expected to be requested somewhere in the near future * Requesting them as embeds will limit the number of requests */ -export const ITEM_PAGE_LINKS_TO_FOLLOW: FollowLinkConfig[] = [ - followLink('owningCollection', {}, - followLink('parentCommunity', {}, - followLink('parentCommunity')) - ), - followLink('relationships'), - followLink('version', {}, followLink('versionhistory')), - followLink('thumbnail') -]; +export function getItemPageLinksToFollow(): FollowLinkConfig[] { + const followLinks: FollowLinkConfig[] = [ + followLink('owningCollection', {}, + followLink('parentCommunity', {}, + followLink('parentCommunity')) + ), + followLink('relationships'), + followLink('version', {}, followLink('versionhistory')), + followLink('thumbnail'), + ]; + if (environment.item.showAccessStatuses) { + followLinks.push(followLink('accessStatus')); + } + return followLinks; +} /** * This class represents a resolver that requests a specific item before the route is activated @@ -46,7 +53,7 @@ export class ItemResolver implements Resolve> { const itemRD$ = this.itemService.findById(route.params.id, true, false, - ...ITEM_PAGE_LINKS_TO_FOLLOW + ...getItemPageLinksToFollow(), ).pipe( getFirstCompletedRemoteData(), ); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts index ff5a119b6fc..a04c10bf3a5 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts @@ -328,7 +328,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo const relationship$ = this.relationshipService.findById(this.value.virtualValue, true, true, - ... itemLinksToFollow(this.fetchThumbnail)).pipe( + ... itemLinksToFollow(this.fetchThumbnail, this.appConfig.item.showAccessStatuses)).pipe( getAllSucceededRemoteData(), getRemoteDataPayload()); this.relationshipValue$ = observableCombineLatest([this.item$.pipe(take(1)), relationship$]).pipe( diff --git a/src/app/shared/utils/relation-query.utils.ts b/src/app/shared/utils/relation-query.utils.ts index 62a69075fcb..635ae946da3 100644 --- a/src/app/shared/utils/relation-query.utils.ts +++ b/src/app/shared/utils/relation-query.utils.ts @@ -1,5 +1,6 @@ import { followLink, FollowLinkConfig } from './follow-link-config.model'; import { Relationship } from '../../core/shared/item-relationships/relationship.model'; +import { Item } from '../../core/shared/item.model'; /** * Get the query for looking up items by relation type @@ -21,19 +22,22 @@ export function getFilterByRelation(relationType: string, itemUUID: string): str } /** - * Creates links to follow for the leftItem and rightItem. Links will include - * @param showThumbnail thumbnail image configuration - * @returns followLink array + * Creates links to follow for the leftItem and rightItem. Optionally additional links for `thumbnail` & `accessStatus` + * can be embedded as well. + * + * @param showThumbnail Whether the `thumbnail` needs to be embedded on the {@link Item} + * @param showAccessStatus Whether the `accessStatus` needs to be embedded on the {@link Item} */ -export function itemLinksToFollow(showThumbnail: boolean): FollowLinkConfig[] { - let linksToFollow: FollowLinkConfig[]; +export function itemLinksToFollow(showThumbnail: boolean, showAccessStatus: boolean): FollowLinkConfig[] { + const conditionalLinksToFollow: FollowLinkConfig[] = []; if (showThumbnail) { - linksToFollow = [ - followLink('leftItem',{}, followLink('thumbnail')), - followLink('rightItem',{}, followLink('thumbnail')) - ]; - } else { - linksToFollow = [followLink('leftItem'), followLink('rightItem')]; + conditionalLinksToFollow.push(followLink('thumbnail')); } - return linksToFollow; + if (showAccessStatus) { + conditionalLinksToFollow.push(followLink('accessStatus')); + } + return [ + followLink('leftItem', undefined, ...conditionalLinksToFollow), + followLink('rightItem', undefined, ...conditionalLinksToFollow), + ]; } From 4de3c58e06daef1753645691782857b5b0c8cee2 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Thu, 10 Oct 2024 22:12:10 +0200 Subject: [PATCH 175/822] 119207: Reinitialize the BrowseByComponent's objectInjector when startsWithOptions don't exist yet OnInit --- .../browse-by/browse-by.component.spec.ts | 2 ++ .../shared/browse-by/browse-by.component.ts | 30 ++++++++++++------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/app/shared/browse-by/browse-by.component.spec.ts b/src/app/shared/browse-by/browse-by.component.spec.ts index 9317a68007a..260e27c8cb4 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -142,6 +142,8 @@ describe('BrowseByComponent', () => { { provide: RouteService, useValue: routeServiceStub}, { provide: SelectableListService, useValue: {} }, { provide: HostWindowService, useValue: new HostWindowServiceStub(800) }, + { provide: 'startsWithOptions', useValue: [] }, + { provide: 'paginationId', useValue: 'bbm' }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/shared/browse-by/browse-by.component.ts b/src/app/shared/browse-by/browse-by.component.ts index 0dc20033f85..0e4c8cdca90 100644 --- a/src/app/shared/browse-by/browse-by.component.ts +++ b/src/app/shared/browse-by/browse-by.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Injector, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Injector, Input, OnDestroy, OnInit, Output, SimpleChanges, OnChanges } from '@angular/core'; import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; @@ -26,7 +26,7 @@ import { TranslateService } from '@ngx-translate/core'; /** * Component to display a browse-by page for any ListableObject */ -export class BrowseByComponent implements OnInit, OnDestroy { +export class BrowseByComponent implements OnInit, OnDestroy, OnChanges { /** * ViewMode that should be passed to {@link ListableObjectComponentLoaderComponent}. @@ -182,14 +182,7 @@ export class BrowseByComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.objectInjector = Injector.create({ - providers: [ - { provide: 'startsWithOptions', useFactory: () => (this.startsWithOptions), deps:[] }, - { provide: 'paginationId', useFactory: () => (this.paginationConfig?.id), deps:[] } - ], - parent: this.injector - }); - + this.generateInjector(); const startsWith$ = this.routeService.getQueryParameterValue('startsWith'); const value$ = this.routeService.getQueryParameterValue('value'); @@ -199,9 +192,26 @@ export class BrowseByComponent implements OnInit, OnDestroy { this.sub = this.routeService.getQueryParameterValue(this.paginationConfig.id + '.return').subscribe(this.previousPage$); } + ngOnChanges(changes: SimpleChanges): void { + if (changes.startsWithOptions || changes.paginationId) { + this.generateInjector(); + } + } + ngOnDestroy(): void { if (this.sub) { this.sub.unsubscribe(); } } + + generateInjector(): void { + this.objectInjector = Injector.create({ + providers: [ + { provide: 'startsWithOptions', useFactory: () => (this.startsWithOptions), deps:[] }, + { provide: 'paginationId', useFactory: () => (this.paginationConfig?.id), deps:[] } + ], + parent: this.injector + }); + } + } From 0657517915cd1d81c542a31737e9dc2428ea0018 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:14:58 +0000 Subject: [PATCH 176/822] Bump body-parser from 1.20.2 to 1.20.3 Bumps [body-parser](https://github.com/expressjs/body-parser) from 1.20.2 to 1.20.3. - [Release notes](https://github.com/expressjs/body-parser/releases) - [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/body-parser/compare/1.20.2...1.20.3) --- updated-dependencies: - dependency-name: body-parser dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/yarn.lock b/yarn.lock index 368a89a5f0b..3888a2384ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3946,7 +3946,7 @@ bluebird@^3.7.2: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -body-parser@1.20.3: +body-parser@1.20.3, body-parser@^1.19.0: version "1.20.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== @@ -3964,24 +3964,6 @@ body-parser@1.20.3: type-is "~1.6.18" unpipe "1.0.0" -body-parser@^1.19.0: - version "1.20.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== - dependencies: - bytes "3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.2" - type-is "~1.6.18" - unpipe "1.0.0" - bonjour-service@^1.0.11: version "1.2.1" resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.2.1.tgz#eb41b3085183df3321da1264719fbada12478d02" @@ -5603,11 +5585,9 @@ eslint-plugin-deprecation@^1.4.1: "eslint-plugin-dspace-angular-html@link:./lint/dist/src/rules/html": version "0.0.0" - uid "" "eslint-plugin-dspace-angular-ts@link:./lint/dist/src/rules/ts": version "0.0.0" - uid "" eslint-plugin-import-newlines@^1.3.1: version "1.4.0" @@ -9727,13 +9707,6 @@ qjobs@^1.2.0: resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== -qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - qs@6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" From aee7f0f89932e612ece5ee28c51e5c20050df79c Mon Sep 17 00:00:00 2001 From: Mohamed Ali <66433220+mohamedali654321@users.noreply.github.com> Date: Wed, 26 Jun 2024 00:51:14 -0700 Subject: [PATCH 177/822] Update Arabic Translation Update Arabic Translation Update ar.json5 translation (cherry picked from commit f5f40c3dc75563bbd67ef98307e58ef33c8b2789) --- src/assets/i18n/ar.json5 | 11229 ++++++++++++++++++++++++++++++------- 1 file changed, 9246 insertions(+), 1983 deletions(-) diff --git a/src/assets/i18n/ar.json5 b/src/assets/i18n/ar.json5 index 6d97effb4cc..cf7f7b05bda 100644 --- a/src/assets/i18n/ar.json5 +++ b/src/assets/i18n/ar.json5 @@ -1,3383 +1,10646 @@ { - "401.help": "غير مصرح لك بالوصول إلى هذه الصفحة. ", + + // "401.help": "You're not authorized to access this page. You can use the button below to get back to the home page.", + "401.help": "غير مصرح لك بالوصول إلى هذه الصفحة. يمكنك استخدام الزر أدناه للعودة إلى الصفحة الرئيسية.", + + // "401.link.home-page": "Take me to the home page", "401.link.home-page": "اذهب إلى الصفحة الرئيسية", - "401.unauthorized": "بدون كمية كافية", - "403.help": "ليس لديك إمكانية الوصول إلى هذه الصفحة. ", + + // "401.unauthorized": "Unauthorized", + "401.unauthorized": "بدون تصريح", + + // "403.help": "You don't have permission to access this page. You can use the button below to get back to the home page.", + "403.help": "ليس لديك صلاحية الوصول إلى هذه الصفحة. يمكنك استخدام الزر أدناه للعودة إلى الصفحة الرئيسية.", + + // "403.link.home-page": "Take me to the home page", "403.link.home-page": "اذهب إلى الصفحة الرئيسية", + + // "403.forbidden": "Forbidden", "403.forbidden": "ممنوع", - "500.page-internal-server-error": "الخدمة غير دائمة", - "500.help": "خادم غير قادر على الرد على سؤالك بسبب توقف التوفير أو وجود مشاكل في السعة. ", + + // "500.page-internal-server-error": "Service unavailable", + "500.page-internal-server-error": "الخدمة غير متاحة", + + // "500.help": "The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.", + "500.help": "الخادم غير قادر مؤقتًا على تلبية طلبك بسبب توقف الصيانة أو وجود مشاكل في السعة. يرجى إعادة المحاولة في وقت لاحق.", + + // "500.link.home-page": "Take me to the home page", "500.link.home-page": "اذهب إلى الصفحة الرئيسية", - "404.help": "يمكنك العثور على الصفحة التي تبحث عنها. ", + + // "404.help": "We can't find the page you're looking for. The page may have been moved or deleted. You can use the button below to get back to the home page. ", + "404.help": "تعذر العثور على الصفحة التي تبحث عنها. ربما تمت إزالتها أو حذفها. يمكنك استخدام الزر أدناه للعودة إلى الصفحة الرئيسية. ", + + // "404.link.home-page": "Take me to the home page", "404.link.home-page": "اذهب إلى الصفحة الرئيسية", - "404.page-not-found": "لم يتم العثور عليها على الصفحة", - "error-page.description.401": "بدون كمية كافية", + + // "404.page-not-found": "Page not found", + "404.page-not-found": "لم يتم العثور على الصفحة", + + // "error-page.description.401": "Unauthorized", + "error-page.description.401": "بدون تصريح", + + // "error-page.description.403": "Forbidden", "error-page.description.403": "ممنوع", - "error-page.description.500": "الخدمة غير دائمة", - "error-page.description.404": "لم يتم العثور عليها على الصفحة", - "error-page.orcid.generic-error": "حدث خطأ أثناء تسجيل الدخول عبر أوركيد. ", + + // "error-page.description.500": "Service unavailable", + "error-page.description.500": "الخدمة غير متاحة", + + // "error-page.description.404": "Page not found", + "error-page.description.404": "لم يتم العثور على الصفحة", + + // "error-page.orcid.generic-error": "An error occurred during login via ORCID. Make sure you have shared your ORCID account email address with DSpace. If the error persists, contact the administrator", + "error-page.orcid.generic-error": "حدث خطأ أثناء تسجيل الدخول عبر أوركيد. يرجى التأكد من أنك قمت بمشاركة عنوان البريد الإلكتروني الخاص بحساب أوركيد الخاص بك مع دي سبيس. إذا استمر الخطأ، فاتصل بالمسؤول", + + // "access-status.embargo.listelement.badge": "Embargo", "access-status.embargo.listelement.badge": "حظر", + + // "access-status.metadata.only.listelement.badge": "Metadata only", "access-status.metadata.only.listelement.badge": "ميتاداتا فقط", + + // "access-status.open.access.listelement.badge": "Open Access", "access-status.open.access.listelement.badge": "وصول حر", + + // "access-status.restricted.listelement.badge": "Restricted", "access-status.restricted.listelement.badge": "مقيد", + + // "access-status.unknown.listelement.badge": "Unknown", "access-status.unknown.listelement.badge": "غير معروف", - "admin.curation-tasks.breadcrumbs": "واجبات النظام", - "admin.curation-tasks.title": "واجبات النظام", - "admin.curation-tasks.header": "واجبات النظام", - "admin.registries.bitstream-formats.breadcrumbs": "قم بالتسجيل", + + // "admin.curation-tasks.breadcrumbs": "System curation tasks", + "admin.curation-tasks.breadcrumbs": "مهام أكرتة النظام", + + // "admin.curation-tasks.title": "System curation tasks", + "admin.curation-tasks.title": "مهام أكرتة النظام", + + // "admin.curation-tasks.header": "System curation tasks", + "admin.curation-tasks.header": "مهام أكرتة النظام", + + // "admin.registries.bitstream-formats.breadcrumbs": "Format registry", + "admin.registries.bitstream-formats.breadcrumbs": "سجل التنسيق", + + // "admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format", "admin.registries.bitstream-formats.create.breadcrumbs": "تنسيق تدفق البت", - "admin.registries.bitstream-formats.create.failure.content": "حدث خطأ أثناء إنشاء تدفق البت الجديد.", + + // "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", + "admin.registries.bitstream-formats.create.failure.content": "حدث خطأ أثناء إنشاء تنسيق تدفق البت الجديد.", + + // "admin.registries.bitstream-formats.create.failure.head": "Failure", "admin.registries.bitstream-formats.create.failure.head": "فشل", - "admin.registries.bitstream-formats.create.head": "إنشاء تدفق بت", - "admin.registries.bitstream-formats.create.new": "تمت إضافة تدفق بت جديد", - "admin.registries.bitstream-formats.create.success.content": "تم إنشاء تدفق البت الجديد الفعال.", + + // "admin.registries.bitstream-formats.create.head": "Create bitstream format", + "admin.registries.bitstream-formats.create.head": "إنشاء تنسيق تدفق بت", + + // "admin.registries.bitstream-formats.create.new": "Add a new bitstream format", + "admin.registries.bitstream-formats.create.new": "إضافة تنسيق تدفق بت جديد", + + // "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", + "admin.registries.bitstream-formats.create.success.content": "تم إنشاء تنسيق تدفق البت الجديد بنجاح.", + + // "admin.registries.bitstream-formats.create.success.head": "Success", "admin.registries.bitstream-formats.create.success.head": "نجاح", - "admin.registries.bitstream-formats.delete.failure.amount": "فشل في إزالة {{ amount }} تنسيقًا", + + // "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", + "admin.registries.bitstream-formats.delete.failure.amount": "فشل إزالة {{ amount }} تنسيقًا", + + // "admin.registries.bitstream-formats.delete.failure.head": "Failure", "admin.registries.bitstream-formats.delete.failure.head": "فشل", - "admin.registries.bitstream-formats.delete.success.amount": "بعد إزالة {{ amount }} فعالة", + + // "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", + "admin.registries.bitstream-formats.delete.success.amount": "تمت إزالة {{ amount }} تنسيقًا بنجاح", + + // "admin.registries.bitstream-formats.delete.success.head": "Success", "admin.registries.bitstream-formats.delete.success.head": "نجاح", - "admin.registries.bitstream-formats.description": "مطلوب قائمة تدفق المعلومات الأساسية حول ما هو مطلوب ومستوى دعمها.", + + // "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", + "admin.registries.bitstream-formats.description": "توفر قائمة تنسيقات تدفق البت معلومات حول التنسيقات المعروفة ومستوى دعمها.", + + // "admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format", "admin.registries.bitstream-formats.edit.breadcrumbs": "تنسيق تدفق البت", + + // "admin.registries.bitstream-formats.edit.description.hint": "", "admin.registries.bitstream-formats.edit.description.hint": "", + + // "admin.registries.bitstream-formats.edit.description.label": "Description", "admin.registries.bitstream-formats.edit.description.label": "الوصف", - "admin.registries.bitstream-formats.edit.extensions.hint": "الامتدادات هي امتدادات الملفات التي تستخدم لتعريف الملفات المرفوعة الأصلية. ", + + // "admin.registries.bitstream-formats.edit.extensions.hint": "Extensions are file extensions that are used to automatically identify the format of uploaded files. You can enter several extensions for each format.", + "admin.registries.bitstream-formats.edit.extensions.hint": "الامتدادات هي امتدادات الملفات التي تستخدم لتعريف تنسيق الملفات المرفوعة تلقائيًا. يمكنك إدخال عدة امتدادات لكل تنسيق.", + + // "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", "admin.registries.bitstream-formats.edit.extensions.label": "امتدادات الملفات", - "admin.registries.bitstream-formats.edit.extensions.placeholder": "قم بتوسعة ملف بدون النقطة", - "admin.registries.bitstream-formats.edit.failure.content": "حدث خطأ أثناء تحرير تدفق البت.", + + // "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", + "admin.registries.bitstream-formats.edit.extensions.placeholder": "قم بإدخال امتداد ملف بدون النقطة", + + // "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", + "admin.registries.bitstream-formats.edit.failure.content": "حدث خطأ أثناء تحرير تنسيق تدفق البت.", + + // "admin.registries.bitstream-formats.edit.failure.head": "Failure", "admin.registries.bitstream-formats.edit.failure.head": "فشل", - "admin.registries.bitstream-formats.edit.head": "تدفق البت: {{ format }}", - "admin.registries.bitstream-formats.edit.internal.hint": "لاغراض إدارية خالية من المستخدم، لأغراض إدارية.", + + // "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", + "admin.registries.bitstream-formats.edit.head": "تنسيق تدفق البت: {{ format }}", + + // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", + "admin.registries.bitstream-formats.edit.internal.hint": "التنسيقات الداخلية مخفية من المستخدم، وتستخدم لأغراض إدارية.", + + // "admin.registries.bitstream-formats.edit.internal.label": "Internal", "admin.registries.bitstream-formats.edit.internal.label": "داخلي", - "admin.registries.bitstream-formats.edit.mimetype.hint": "نوع الميمات المرغوبة لذلك، لا يجب أن يكون فريدًا.", - "admin.registries.bitstream-formats.edit.mimetype.label": "نوع الميم", - "admin.registries.bitstream-formats.edit.shortDescription.hint": "اسم فريد لهذا الغرض، (مثال: ميكروسوفت وورد إكس بي أو ميكروسوفت وورد 200)", + + // "admin.registries.bitstream-formats.edit.mimetype.hint": "The MIME type associated with this format, does not have to be unique.", + "admin.registries.bitstream-formats.edit.mimetype.hint": "نوع المايم المرتبط بهذا التنسيق، لا يجب أن يكون فريدًا.", + + // "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", + "admin.registries.bitstream-formats.edit.mimetype.label": "نوع المايم", + + // "admin.registries.bitstream-formats.edit.shortDescription.hint": "A unique name for this format, (e.g. Microsoft Word XP or Microsoft Word 2000)", + "admin.registries.bitstream-formats.edit.shortDescription.hint": "اسم فريد لهذا التنسيق، (مثال: ميكروسوفت وورد إكس بي أو ميكروسوفت وورد 200)", + + // "admin.registries.bitstream-formats.edit.shortDescription.label": "Name", "admin.registries.bitstream-formats.edit.shortDescription.label": "الاسم", - "admin.registries.bitstream-formats.edit.success.content": "تم تحرير الجذر التدفق الفعال.", + + // "admin.registries.bitstream-formats.edit.success.content": "The bitstream format was successfully edited.", + "admin.registries.bitstream-formats.edit.success.content": "تم تحرير تنسيق تدفق البت بنجاح.", + + // "admin.registries.bitstream-formats.edit.success.head": "Success", "admin.registries.bitstream-formats.edit.success.head": "نجاح", - "admin.registries.bitstream-formats.edit.supportLevel.hint": "مستوى الدعم الذي تعهد به مؤسستك لهذا الغرض.", + + // "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", + "admin.registries.bitstream-formats.edit.supportLevel.hint": "مستوى الدعم التي تتعهد به مؤسستك لهذا التنسيق.", + + // "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", "admin.registries.bitstream-formats.edit.supportLevel.label": "مستوى الدعم", - "admin.registries.bitstream-formats.head": "سجل تدفق البت", + + // "admin.registries.bitstream-formats.head": "Bitstream Format Registry", + "admin.registries.bitstream-formats.head": "سجل تنسيق تدفق البت", + + // "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", "admin.registries.bitstream-formats.no-items": "لا توجد تنسيقات لتدفق البت.", - "admin.registries.bitstream-formats.table.delete": "حذف", + + // "admin.registries.bitstream-formats.table.delete": "Delete selected", + "admin.registries.bitstream-formats.table.delete": "حذف المحدد", + + // "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", "admin.registries.bitstream-formats.table.deselect-all": "إلغاء تحديد الكل", + + // "admin.registries.bitstream-formats.table.internal": "internal", "admin.registries.bitstream-formats.table.internal": "داخلي", - "admin.registries.bitstream-formats.table.mimetype": "نوع الميم", + + // "admin.registries.bitstream-formats.table.mimetype": "MIME Type", + "admin.registries.bitstream-formats.table.mimetype": "نوع المايم", + + // "admin.registries.bitstream-formats.table.name": "Name", "admin.registries.bitstream-formats.table.name": "الاسم", - "admin.registries.bitstream-formats.table.selected": "تنسيقات تدفقات البتات الأولية", + + // "admin.registries.bitstream-formats.table.selected": "Selected bitstream formats", + "admin.registries.bitstream-formats.table.selected": "تنسيقات تدفقات البت المحددة", + + // "admin.registries.bitstream-formats.table.id": "ID", "admin.registries.bitstream-formats.table.id": "المعرّف", + + // "admin.registries.bitstream-formats.table.return": "Back", "admin.registries.bitstream-formats.table.return": "رجوع", + + // "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Known", "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "معروف", + + // "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Supported", "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "مدعوم", + + // "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Unknown", "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "غير معروف", + + // "admin.registries.bitstream-formats.table.supportLevel.head": "Support Level", "admin.registries.bitstream-formats.table.supportLevel.head": "مستوى الدعم", - "admin.registries.bitstream-formats.title": "سجل تدفق البت", + + // "admin.registries.bitstream-formats.title": "Bitstream Format Registry", + "admin.registries.bitstream-formats.title": "سجل تنسيق تدفق البت", + + // "admin.registries.bitstream-formats.select": "Select", "admin.registries.bitstream-formats.select": "تحديد", - "admin.registries.bitstream-formats.deselect": "قم بإلغاء التحديد", - "admin.registries.metadata.breadcrumbs": "سجل المذكرات", - "admin.registries.metadata.description": "تدعو إلى تسجيل النداءات بقائمة شاملة لتغطية النداءات المتاحة في المستودع. ", - "admin.registries.metadata.form.create": "إنشاء مخطط ميتاماتا", + + // "admin.registries.bitstream-formats.deselect": "Deselect", + "admin.registries.bitstream-formats.deselect": "إلغاء تحديد", + + // "admin.registries.metadata.breadcrumbs": "Metadata registry", + "admin.registries.metadata.breadcrumbs": "سجل الميتاداتا", + + // "admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.", + "admin.registries.metadata.description": "يحتفظ سجل الميتاداتا بقائمة بجميع حقول الميتاداتا المتاحة في المستودع. يمكن تقسيم تلك الحقول بين عدة تخطيطات، يتطلب دي سبيس مخطط دبلن كور المؤهل.", + + // "admin.registries.metadata.form.create": "Create metadata schema", + "admin.registries.metadata.form.create": "إنشاء مخطط ميتاداتا", + + // "admin.registries.metadata.form.edit": "Edit metadata schema", "admin.registries.metadata.form.edit": "تحرير مخطط الميتاداتا", + + // "admin.registries.metadata.form.name": "Name", "admin.registries.metadata.form.name": "الاسم", - "admin.registries.metadata.form.namespace": "اسم بعيد", - "admin.registries.metadata.head": "سجل المذكرات", - "admin.registries.metadata.schemas.no-items": "لا يوجد مخططات ميتاداتا للعرض.", + + // "admin.registries.metadata.form.namespace": "Namespace", + "admin.registries.metadata.form.namespace": "مسافة الاسم", + + // "admin.registries.metadata.head": "Metadata Registry", + "admin.registries.metadata.head": "سجل الميتاداتا", + + // "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", + "admin.registries.metadata.schemas.no-items": "لا توجد مخططات ميتاداتا للعرض.", + + // "admin.registries.metadata.schemas.select": "Select", "admin.registries.metadata.schemas.select": "تحديد", - "admin.registries.metadata.schemas.deselect": "قم بإلغاء التحديد", - "admin.registries.metadata.schemas.table.delete": "حذف", - "admin.registries.metadata.schemas.table.selected": "التصنيفات المحددة", + + // "admin.registries.metadata.schemas.deselect": "Deselect", + "admin.registries.metadata.schemas.deselect": "إلغاء تحديد", + + // "admin.registries.metadata.schemas.table.delete": "Delete selected", + "admin.registries.metadata.schemas.table.delete": "حذف المحدد", + + // "admin.registries.metadata.schemas.table.selected": "Selected schemas", + "admin.registries.metadata.schemas.table.selected": "المخططات المحددة", + + // "admin.registries.metadata.schemas.table.id": "ID", "admin.registries.metadata.schemas.table.id": "المعرّف", + + // "admin.registries.metadata.schemas.table.name": "Name", "admin.registries.metadata.schemas.table.name": "الاسم", - "admin.registries.metadata.schemas.table.namespace": "اسم بعيد", - "admin.registries.metadata.title": "سجل المذكرات", + + // "admin.registries.metadata.schemas.table.namespace": "Namespace", + "admin.registries.metadata.schemas.table.namespace": "مسافة الاسم", + + // "admin.registries.metadata.title": "Metadata Registry", + "admin.registries.metadata.title": "سجل الميتاداتا", + + // "admin.registries.schema.breadcrumbs": "Metadata schema", "admin.registries.schema.breadcrumbs": "مخطط الميتاداتا", - "admin.registries.schema.description": "هذا هو مخطط الميتاداتا لـ \"{{namespace}}\".", + + // "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", + "admin.registries.schema.description": "هذا هو مخطط الميتاداتا لـ \"{{namespace}}\".", + + // "admin.registries.schema.fields.select": "Select", "admin.registries.schema.fields.select": "تحديد", - "admin.registries.schema.fields.deselect": "قم بإلغاء التحديد", - "admin.registries.schema.fields.head": "يغطي مخطط الميتاداتا", - "admin.registries.schema.fields.no-items": "لا توجد مشكلة ميتاداتا للعرض.", - "admin.registries.schema.fields.table.delete": "حذف", - "admin.registries.schema.fields.table.field": "بحث متقدم", - "admin.registries.schema.fields.table.selected": "تكفير الميتاداتا المحددة", + + // "admin.registries.schema.fields.deselect": "Deselect", + "admin.registries.schema.fields.deselect": "إلغاء تحديد", + + // "admin.registries.schema.fields.head": "Schema metadata fields", + "admin.registries.schema.fields.head": "حقول مخطط الميتاداتا", + + // "admin.registries.schema.fields.no-items": "No metadata fields to show.", + "admin.registries.schema.fields.no-items": "لا توجد حقول ميتاداتا للعرض.", + + // "admin.registries.schema.fields.table.delete": "Delete selected", + "admin.registries.schema.fields.table.delete": "حذف المحدد", + + // "admin.registries.schema.fields.table.field": "Field", + "admin.registries.schema.fields.table.field": "حقل", + + // "admin.registries.schema.fields.table.selected": "Selected metadata fields", + "admin.registries.schema.fields.table.selected": "حقول الميتاداتا المحددة", + + // "admin.registries.schema.fields.table.id": "ID", "admin.registries.schema.fields.table.id": "المعرّف", - "admin.registries.schema.fields.table.scopenote": "لاحظ النطاق", - "admin.registries.schema.form.create": "إنشاء بحث ميتا", - "admin.registries.schema.form.edit": "تحرير البحث ميتا", + + // "admin.registries.schema.fields.table.scopenote": "Scope Note", + "admin.registries.schema.fields.table.scopenote": "ملاحظة النطاق", + + // "admin.registries.schema.form.create": "Create metadata field", + "admin.registries.schema.form.create": "إنشاء حقل ميتاداتا", + + // "admin.registries.schema.form.edit": "Edit metadata field", + "admin.registries.schema.form.edit": "تحرير حقل ميتاداتا", + + // "admin.registries.schema.form.element": "Element", "admin.registries.schema.form.element": "عنصر", + + // "admin.registries.schema.form.qualifier": "Qualifier", "admin.registries.schema.form.qualifier": "مؤهل", - "admin.registries.schema.form.scopenote": "لاحظ النطاق", + + // "admin.registries.schema.form.scopenote": "Scope Note", + "admin.registries.schema.form.scopenote": "ملاحظة النطاق", + + // "admin.registries.schema.head": "Metadata Schema", "admin.registries.schema.head": "مخطط الميتاداتا", - "admin.registries.schema.notification.created": "تم إنشاء مخطط الميتاداتا \"{{prefix}}\"", - "admin.registries.schema.notification.deleted.failure": "فشل الحذف {{amount}} مخططات ميتا", - "admin.registries.schema.notification.deleted.success": "تم الحذف {{amount}} مخططات ميتا فعالة", - "admin.registries.schema.notification.edited": "تم فعالية تحرير مخطط الميتاداتا \"{{prefix}}\"", + + // "admin.registries.schema.notification.created": "Successfully created metadata schema \"{{prefix}}\"", + "admin.registries.schema.notification.created": "تم بنجاح إنشاء مخطط الميتاداتا \"{{prefix}}\"", + + // "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", + "admin.registries.schema.notification.deleted.failure": "فشل حذف {{amount}} مخطط ميتاداتا", + + // "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", + "admin.registries.schema.notification.deleted.success": "تم حذف {{amount}} مخطط ميتاداتا بنجاح", + + // "admin.registries.schema.notification.edited": "Successfully edited metadata schema \"{{prefix}}\"", + "admin.registries.schema.notification.edited": "تم بنجاح تحرير مخطط الميتاداتا \"{{prefix}}\"", + + // "admin.registries.schema.notification.failure": "Error", "admin.registries.schema.notification.failure": "خطأ", - "admin.registries.schema.notification.field.created": "تم إنشاء البحث العلمي \"{{field}}\"", - "admin.registries.schema.notification.field.deleted.failure": "فشل الحذف {{amount}} بحث ميتا", - "admin.registries.schema.notification.field.deleted.success": "تم الحذف {{amount}} بحثت عن نتائج ميتا فعالة", - "admin.registries.schema.notification.field.edited": "تم البحث الفعال عن البحث في الميتاداتا \"{{field}}\"", + + // "admin.registries.schema.notification.field.created": "Successfully created metadata field \"{{field}}\"", + "admin.registries.schema.notification.field.created": "تم بنجاح إنشاء حقل الميتاداتا \"{{field}}\"", + + // "admin.registries.schema.notification.field.deleted.failure": "Failed to delete {{amount}} metadata fields", + "admin.registries.schema.notification.field.deleted.failure": "فشل حذف {{amount}} حقل ميتاداتا", + + // "admin.registries.schema.notification.field.deleted.success": "Successfully deleted {{amount}} metadata fields", + "admin.registries.schema.notification.field.deleted.success": "تم حذف {{amount}} حقل ميتاداتا بنجاح", + + // "admin.registries.schema.notification.field.edited": "Successfully edited metadata field \"{{field}}\"", + "admin.registries.schema.notification.field.edited": "تم بنجاح تحرير حقل الميتاداتا \"{{field}}\"", + + // "admin.registries.schema.notification.success": "Success", "admin.registries.schema.notification.success": "نجاح", + + // "admin.registries.schema.return": "Back", "admin.registries.schema.return": "رجوع", + + // "admin.registries.schema.title": "Metadata Schema Registry", "admin.registries.schema.title": "سجل مخطط الميتاداتا", + + // "admin.access-control.bulk-access.breadcrumbs": "Bulk Access Management", "admin.access-control.bulk-access.breadcrumbs": "إدارة الوصول بالجملة", + + // "administrativeBulkAccess.search.results.head": "Search Results", "administrativeBulkAccess.search.results.head": "نتائج البحث", + + // "admin.access-control.bulk-access": "Bulk Access Management", "admin.access-control.bulk-access": "إدارة الوصول بالجملة", + + // "admin.access-control.bulk-access.title": "Bulk Access Management", "admin.access-control.bulk-access.title": "إدارة الوصول بالجملة", - "admin.access-control.bulk-access-browse.header": "الخطوة الأولى: قم بإنشاء الكائنات الحية", + + // "admin.access-control.bulk-access-browse.header": "Step 1: Select Objects", + "admin.access-control.bulk-access-browse.header": "الخطوة الأولى: قم بتحديد الكائنات", + + // "admin.access-control.bulk-access-browse.search.header": "Search", "admin.access-control.bulk-access-browse.search.header": "بحث", - "admin.access-control.bulk-access-browse.selected.header": "التحديد الفعلي({{number}})", - "admin.access-control.bulk-access-settings.header": "الثانية: المراد بإجرائها", - "admin.access-control.epeople.actions.delete": "حذف الالكترونيات الشخصية", + + // "admin.access-control.bulk-access-browse.selected.header": "Current selection({{number}})", + "admin.access-control.bulk-access-browse.selected.header": "التحديد الحالي({{number}})", + + // "admin.access-control.bulk-access-settings.header": "Step 2: Operation to Perform", + "admin.access-control.bulk-access-settings.header": "الخطوة الثانية: العملية المراد إجراؤها", + + // "admin.access-control.epeople.actions.delete": "Delete EPerson", + "admin.access-control.epeople.actions.delete": "حذف شخص إلكتروني", + + // "admin.access-control.epeople.actions.impersonate": "Impersonate EPerson", "admin.access-control.epeople.actions.impersonate": "التصرف كشخص إلكتروني", + + // "admin.access-control.epeople.actions.reset": "Reset password", "admin.access-control.epeople.actions.reset": "إعادة تعيين كلمة المرور", - "admin.access-control.epeople.actions.stop-impersonating": "ضبط التصرف كشخص إلكتروني", - "admin.access-control.epeople.breadcrumbs": "يأتي إليكين", - "admin.access-control.epeople.title": "يأتي إليكين", - "admin.access-control.epeople.edit.breadcrumbs": "شخصي إلكتروني جديد", - "admin.access-control.epeople.edit.title": "شخصي إلكتروني جديد", - "admin.access-control.epeople.add.breadcrumbs": "إضافة خاصة إلكترونيات", - "admin.access-control.epeople.add.title": "إضافة خاصة إلكترونيات", - "admin.access-control.epeople.head": "يأتي إليكين", + + // "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", + "admin.access-control.epeople.actions.stop-impersonating": "التوقف عن التصرف كشخص إلكتروني", + + // "admin.access-control.epeople.breadcrumbs": "EPeople", + "admin.access-control.epeople.breadcrumbs": "أشخاص إلكترونيين", + + // "admin.access-control.epeople.title": "EPeople", + "admin.access-control.epeople.title": "أشخاص إلكترونيين", + + // "admin.access-control.epeople.edit.breadcrumbs": "New EPerson", + "admin.access-control.epeople.edit.breadcrumbs": "شخص إلكتروني جديد", + + // "admin.access-control.epeople.edit.title": "New EPerson", + "admin.access-control.epeople.edit.title": "شخص إلكتروني جديد", + + // "admin.access-control.epeople.add.breadcrumbs": "Add EPerson", + "admin.access-control.epeople.add.breadcrumbs": "إضافة شخص إلكتروني", + + // "admin.access-control.epeople.add.title": "Add EPerson", + "admin.access-control.epeople.add.title": "إضافة شخص إلكتروني", + + // "admin.access-control.epeople.head": "EPeople", + "admin.access-control.epeople.head": "أشخاص إلكترونيين", + + // "admin.access-control.epeople.search.head": "Search", "admin.access-control.epeople.search.head": "بحث", - "admin.access-control.epeople.button.see-all": "مراجعة الكل", - "admin.access-control.epeople.search.scope.metadata": "ميداداتا", + + // "admin.access-control.epeople.button.see-all": "Browse All", + "admin.access-control.epeople.button.see-all": "استعراض الكل", + + // "admin.access-control.epeople.search.scope.metadata": "Metadata", + "admin.access-control.epeople.search.scope.metadata": "الميتاداتا", + + // "admin.access-control.epeople.search.scope.email": "Email (exact)", "admin.access-control.epeople.search.scope.email": "البريد الإلكتروني (بالضبط)", + + // "admin.access-control.epeople.search.button": "Search", "admin.access-control.epeople.search.button": "بحث", - "admin.access-control.epeople.search.placeholder": "بحث الناس...", - "admin.access-control.epeople.button.add": "إضافة خاصة إلكترونيات", + + // "admin.access-control.epeople.search.placeholder": "Search people...", + "admin.access-control.epeople.search.placeholder": "بحث الأشخاص...", + + // "admin.access-control.epeople.button.add": "Add EPerson", + "admin.access-control.epeople.button.add": "إضافة شخص إلكتروني", + + // "admin.access-control.epeople.table.id": "ID", "admin.access-control.epeople.table.id": "المعرّف", + + // "admin.access-control.epeople.table.name": "Name", "admin.access-control.epeople.table.name": "الاسم", + + // "admin.access-control.epeople.table.email": "Email (exact)", "admin.access-control.epeople.table.email": "البريد الإلكتروني (بالضبط)", + + // "admin.access-control.epeople.table.edit": "Edit", "admin.access-control.epeople.table.edit": "تحرير", + + // "admin.access-control.epeople.table.edit.buttons.edit": "Edit \"{{name}}\"", "admin.access-control.epeople.table.edit.buttons.edit": "تحرير \"{{name}}\"", - "admin.access-control.epeople.table.edit.buttons.edit-disabled": "غير مصرح لك لتحرير هذه المجموعة", + + // "admin.access-control.epeople.table.edit.buttons.edit-disabled": "You are not authorized to edit this group", + "admin.access-control.epeople.table.edit.buttons.edit-disabled": "غير مصرح لك بتحرير هذه المجموعة", + + // "admin.access-control.epeople.table.edit.buttons.remove": "Delete \"{{name}}\"", "admin.access-control.epeople.table.edit.buttons.remove": "حذف \"{{name}}\"", - "admin.access-control.epeople.no-items": "لا يوجد رجل إلكترونين للعرض.", + + // "admin.access-control.epeople.no-items": "No EPeople to show.", + "admin.access-control.epeople.no-items": "لا يوجد أشخاص إلكترونيين للعرض.", + + // "admin.access-control.epeople.form.create": "Create EPerson", "admin.access-control.epeople.form.create": "إنشاء شخص إلكتروني", - "admin.access-control.epeople.form.edit": "تحرير الكمبيوتر الشخصي", + + // "admin.access-control.epeople.form.edit": "Edit EPerson", + "admin.access-control.epeople.form.edit": "تحرير شخص إلكتروني", + + // "admin.access-control.epeople.form.firstName": "First name", "admin.access-control.epeople.form.firstName": "الاسم الأول", + + // "admin.access-control.epeople.form.lastName": "Last name", "admin.access-control.epeople.form.lastName": "اسم العائلة", + + // "admin.access-control.epeople.form.email": "Email", "admin.access-control.epeople.form.email": "البريد الإلكتروني", - "admin.access-control.epeople.form.emailHint": "يجب أن يكون عنوان بريد الإلكتروني صالح", - "admin.access-control.epeople.form.canLogIn": "يمكننا تسجيل الدخول", - "admin.access-control.epeople.form.requireCertificate": "أنا", + + // "admin.access-control.epeople.form.emailHint": "Must be a valid email address", + "admin.access-control.epeople.form.emailHint": "يجب أن يكون عنوان بريد إلكتروني صالح", + + // "admin.access-control.epeople.form.canLogIn": "Can log in", + "admin.access-control.epeople.form.canLogIn": "يمكنه تسجيل الدخول", + + // "admin.access-control.epeople.form.requireCertificate": "Requires certificate", + "admin.access-control.epeople.form.requireCertificate": "يتطلب شهادة", + + // "admin.access-control.epeople.form.return": "Back", "admin.access-control.epeople.form.return": "رجوع", + + // "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", "admin.access-control.epeople.form.notification.created.success": "تم إنشاء الشخص الإلكتروني \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", "admin.access-control.epeople.form.notification.created.failure": "فشل إنشاء الشخص الإلكتروني \"{{name}}\"", - "admin.access-control.epeople.form.notification.created.failure.emailInUse": "فشل إنشاء الشخص الإلكتروني \"{{name}}\"، البريد الإلكتروني \"{{email}}\"تعمل بالفعل.", - "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "فشل في تحرير الشخص الإلكتروني \"{{name}}\"، البريد الإلكتروني \"{{email}}\"تعمل بالفعل.", + + // "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.", + "admin.access-control.epeople.form.notification.created.failure.emailInUse": "فشل إنشاء الشخص الإلكتروني \"{{name}}\", البريد الإلكتروني \"{{email}}\" قيد الاستخدام بالفعل.", + + // "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Failed to edit EPerson \"{{name}}\", email \"{{email}}\" already in use.", + "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "فشل تحرير الشخص الإلكتروني \"{{name}}\", البريد الإلكتروني \"{{email}}\" قيد الاستخدام بالفعل.", + + // "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", "admin.access-control.epeople.form.notification.edited.success": "تم تحرير الشخص الإلكتروني \"{{name}}\"بنجاح", - "admin.access-control.epeople.form.notification.edited.failure": "فشل في تحرير الشخص الإلكتروني \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.edited.failure": "فشل تحرير الشخص الإلكتروني \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", "admin.access-control.epeople.form.notification.deleted.success": "تم حذف الشخص الإلكتروني \"{{name}}\"بنجاح", - "admin.access-control.epeople.form.notification.deleted.failure": "فشل في حذف الهاتف الإلكتروني \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.deleted.failure": "فشل حذف الشخص الإلكتروني \"{{name}}\"", + + // "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "عضو في هذه المجموعات:", + + // "admin.access-control.epeople.form.table.id": "ID", "admin.access-control.epeople.form.table.id": "المعرّف", + + // "admin.access-control.epeople.form.table.name": "Name", "admin.access-control.epeople.form.table.name": "الاسم", - "admin.access-control.epeople.form.table.collectionOrCommunity": "الحاوية/المجتمع", + + // "admin.access-control.epeople.form.table.collectionOrCommunity": "Collection/Community", + "admin.access-control.epeople.form.table.collectionOrCommunity": "حاوية/مجتمع", + + // "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", "admin.access-control.epeople.form.memberOfNoGroups": "هذا الشخص الإلكتروني ليس عضواً في أي مجموعة", - "admin.access-control.epeople.form.goToGroups": "إضافة إلى مجموعات", - "admin.access-control.epeople.notification.deleted.failure": "حدث خطأ عند محاولة حذف الشخص الإلكتروني بالمعرف \"{{id}}\" بالرمز: \"{{statusCode}}\" والرسالة: \"{{restResponse.errorMessage}}\"", - "admin.access-control.epeople.notification.deleted.success": "تم حذف البريد الإلكتروني الخاص بالشخص: \"{{name}}\"بنجاح", - "admin.access-control.groups.title": "مجموعات", - "admin.access-control.groups.breadcrumbs": "مجموعات", - "admin.access-control.groups.singleGroup.breadcrumbs": "تحرير المجموعة", - "admin.access-control.groups.title.singleGroup": "تحرير المجموعة", + + // "admin.access-control.epeople.form.goToGroups": "Add to groups", + "admin.access-control.epeople.form.goToGroups": "أضف إلى مجموعات", + + // "admin.access-control.epeople.notification.deleted.failure": "Error occurred when trying to delete EPerson with id \"{{id}}\" with code: \"{{statusCode}}\" and message: \"{{restResponse.errorMessage}}\"", + "admin.access-control.epeople.notification.deleted.failure": "حدث خطأ عند محاولة حذف شخص إلكتروني بالمعرف \"{{id}}\" بالرمز: \"{{statusCode}}\" والرسالة: \"{{restResponse.errorMessage}}\"", + + // "admin.access-control.epeople.notification.deleted.success": "Successfully deleted EPerson: \"{{name}}\"", + "admin.access-control.epeople.notification.deleted.success": "تم حذف الشخص الإلكتروني: \"{{name}}\"بنجاح", + + // "admin.access-control.groups.title": "Groups", + "admin.access-control.groups.title": "المجموعات", + + // "admin.access-control.groups.breadcrumbs": "Groups", + "admin.access-control.groups.breadcrumbs": "المجموعات", + + // "admin.access-control.groups.singleGroup.breadcrumbs": "Edit Group", + "admin.access-control.groups.singleGroup.breadcrumbs": "تحرير مجموعة", + + // "admin.access-control.groups.title.singleGroup": "Edit Group", + "admin.access-control.groups.title.singleGroup": "تحرير مجموعة", + + // "admin.access-control.groups.title.addGroup": "New Group", "admin.access-control.groups.title.addGroup": "مجموعة جديدة", + + // "admin.access-control.groups.addGroup.breadcrumbs": "New Group", "admin.access-control.groups.addGroup.breadcrumbs": "مجموعة جديدة", - "admin.access-control.groups.head": "مجموعات", + + // "admin.access-control.groups.head": "Groups", + "admin.access-control.groups.head": "المجموعات", + + // "admin.access-control.groups.button.add": "Add group", "admin.access-control.groups.button.add": "إضافة مجموعة", - "admin.access-control.groups.search.head": "بحثت المجموعات", - "admin.access-control.groups.button.see-all": "مراجعة الكل", + + // "admin.access-control.groups.search.head": "Search groups", + "admin.access-control.groups.search.head": "بحث المجموعات", + + // "admin.access-control.groups.button.see-all": "Browse all", + "admin.access-control.groups.button.see-all": "استعراض الكل", + + // "admin.access-control.groups.search.button": "Search", "admin.access-control.groups.search.button": "بحث", - "admin.access-control.groups.search.placeholder": "بحث في المجموعات...", + + // "admin.access-control.groups.search.placeholder": "Search groups...", + "admin.access-control.groups.search.placeholder": "بحث المجموعات...", + + // "admin.access-control.groups.table.id": "ID", "admin.access-control.groups.table.id": "المعرّف", + + // "admin.access-control.groups.table.name": "Name", "admin.access-control.groups.table.name": "الاسم", - "admin.access-control.groups.table.collectionOrCommunity": "الحاوية/المجتمع", + + // "admin.access-control.groups.table.collectionOrCommunity": "Collection/Community", + "admin.access-control.groups.table.collectionOrCommunity": "حاوية/مجتمع", + + // "admin.access-control.groups.table.members": "Members", "admin.access-control.groups.table.members": "الأعضاء", + + // "admin.access-control.groups.table.edit": "Edit", "admin.access-control.groups.table.edit": "تحرير", + + // "admin.access-control.groups.table.edit.buttons.edit": "Edit \"{{name}}\"", "admin.access-control.groups.table.edit.buttons.edit": "تحرير \"{{name}}\"", + + // "admin.access-control.groups.table.edit.buttons.remove": "Delete \"{{name}}\"", "admin.access-control.groups.table.edit.buttons.remove": "حذف \"{{name}}\"", - "admin.access-control.groups.no-items": "لم يتم العثور على أي مجموعات دي فيينا أو كمعرفي فريد", + + // "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", + "admin.access-control.groups.no-items": "لم يتم العثور على أي مجموعات بهذا في اسمها أو كمعرف عمومي فريد", + + // "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", "admin.access-control.groups.notification.deleted.success": "تم حذف المجموعة \"{{name}}\"بنجاح", - "admin.access-control.groups.notification.deleted.failure.title": "فشل في حذف المجموعة \"{{name}}\"", + + // "admin.access-control.groups.notification.deleted.failure.title": "Failed to delete group \"{{name}}\"", + "admin.access-control.groups.notification.deleted.failure.title": "فشل حذف المجموعة \"{{name}}\"", + + // "admin.access-control.groups.notification.deleted.failure.content": "Cause: \"{{cause}}\"", "admin.access-control.groups.notification.deleted.failure.content": "السبب: \"{{cause}}\"", - "admin.access-control.groups.form.alert.permanent": "هذه المجموعة حقوق، حقوق لا يمكن تحريرها أو حذفها. ", - "admin.access-control.groups.form.alert.workflowGroup": "لا يمكن تعديل هذه المجموعة أو حذفها بشكل واضح مع دقة عملية التقديم وسير العمل في \"{{name}}\" {{comcol}}. \"تعيين الضبط\" في صفحة التحرير {{comcol}}. ", + + // "admin.access-control.groups.form.alert.permanent": "This group is permanent, so it can't be edited or deleted. You can still add and remove group members using this page.", + "admin.access-control.groups.form.alert.permanent": "هذه المجموعة دائمة، لذا لا يمكن تحريرها أو حذفها. لكن لايزال بإمكانك إضافة وإزالة أعضاء المجموعة باستخدام هذه الصفحة..", + + // "admin.access-control.groups.form.alert.workflowGroup": "This group can’t be modified or deleted because it corresponds to a role in the submission and workflow process in the \"{{name}}\" {{comcol}}. You can delete it from the \"assign roles\" tab on the edit {{comcol}} page. You can still add and remove group members using this page.", + "admin.access-control.groups.form.alert.workflowGroup": "لا يمكن تعديل هذه المجموعة أو حذفها لأنها تتوافق مع دور في عملية التقديم وسير العمل في \"{{name}}\" {{comcol}}. يمكنك حذفها من تبويب \"تعيين الأدوار\" في صفحة تحرير {{comcol}}. لا يزال بإمكانك إضافة وإزالة أعضاء المجموعة باستخدام هذه الصفحة.", + + // "admin.access-control.groups.form.head.create": "Create group", "admin.access-control.groups.form.head.create": "إنشاء مجموعة", - "admin.access-control.groups.form.head.edit": "تحرير المجموعة", + + // "admin.access-control.groups.form.head.edit": "Edit group", + "admin.access-control.groups.form.head.edit": "تحرير مجموعة", + + // "admin.access-control.groups.form.groupName": "Group name", "admin.access-control.groups.form.groupName": "اسم المجموعة", + + // "admin.access-control.groups.form.groupCommunity": "Community or Collection", "admin.access-control.groups.form.groupCommunity": "مجتمع أو حاوية", + + // "admin.access-control.groups.form.groupDescription": "Description", "admin.access-control.groups.form.groupDescription": "الوصف", + + // "admin.access-control.groups.form.notification.created.success": "Successfully created Group \"{{name}}\"", "admin.access-control.groups.form.notification.created.success": "تم إنشاء المجموعة \"{{name}}\"بنجاح", + + // "admin.access-control.groups.form.notification.created.failure": "Failed to create Group \"{{name}}\"", "admin.access-control.groups.form.notification.created.failure": "فشل إنشاء المجموعة \"{{name}}\"", - "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "فشل في إنشاء المجموعة بالاسم: \"{{name}}\"، يرجى مراعاة أن الاسم ليس قيد التنفيذ.", + + // "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Failed to create Group with name: \"{{name}}\", make sure the name is not already in use.", + "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "فشل إنشاء المجموعة بالاسم: \"{{name}}\"، يرجى التأكد أن الاسم ليس قيد الاستخدام بالفعل.", + + // "admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"", "admin.access-control.groups.form.notification.edited.failure": "فشل تحرير المجموعة \"{{name}}\"", - "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "الاسم \"{{name}}\"تعمل بالفعل!", + + // "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!", + "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "الاسم \"{{name}}\" قيد الاستخدام بالفعل!", + + // "admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"", "admin.access-control.groups.form.notification.edited.success": "تم تحرير المجموعة \"{{name}}\"بنجاح", + + // "admin.access-control.groups.form.actions.delete": "Delete Group", "admin.access-control.groups.form.actions.delete": "حذف المجموعة", + + // "admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"", "admin.access-control.groups.form.delete-group.modal.header": "حذف المجموعة \"{{ dsoName }}\"", + + // "admin.access-control.groups.form.delete-group.modal.info": "Are you sure you want to delete Group \"{{ dsoName }}\"", "admin.access-control.groups.form.delete-group.modal.info": "هل أنت متأكد من أنك ترغب في حذف المجموعة \"{{ dsoName }}\"", + + // "admin.access-control.groups.form.delete-group.modal.cancel": "Cancel", "admin.access-control.groups.form.delete-group.modal.cancel": "إلغاء", + + // "admin.access-control.groups.form.delete-group.modal.confirm": "Delete", "admin.access-control.groups.form.delete-group.modal.confirm": "حذف", + + // "admin.access-control.groups.form.notification.deleted.success": "Successfully deleted group \"{{ name }}\"", "admin.access-control.groups.form.notification.deleted.success": "تم حذف المجموعة \"{{ name }}\"بنجاح", - "admin.access-control.groups.form.notification.deleted.failure.title": "فشل في حذف المجموعة \"{{ name }}\"", + + // "admin.access-control.groups.form.notification.deleted.failure.title": "Failed to delete group \"{{ name }}\"", + "admin.access-control.groups.form.notification.deleted.failure.title": "فشل حذف المجموعة \"{{ name }}\"", + + // "admin.access-control.groups.form.notification.deleted.failure.content": "Cause: \"{{ cause }}\"", "admin.access-control.groups.form.notification.deleted.failure.content": "السبب: \"{{ cause }}\"", - "admin.access-control.groups.form.members-list.head": "يأتي إليكين", - "admin.access-control.groups.form.members-list.search.head": "إضافة المزيد من الإلكترونيات", - "admin.access-control.groups.form.members-list.button.see-all": "مراجعة الكل", - "admin.access-control.groups.form.members-list.headMembers": "الأعضاء الحالية", + + // "admin.access-control.groups.form.members-list.head": "EPeople", + "admin.access-control.groups.form.members-list.head": "أشخاص إلكترونيين", + + // "admin.access-control.groups.form.members-list.search.head": "Add EPeople", + "admin.access-control.groups.form.members-list.search.head": "إضافة أشخاص إلكترونيين", + + // "admin.access-control.groups.form.members-list.button.see-all": "Browse All", + "admin.access-control.groups.form.members-list.button.see-all": "استعراض الكل", + + // "admin.access-control.groups.form.members-list.headMembers": "Current Members", + "admin.access-control.groups.form.members-list.headMembers": "الأعضاء الحاليين", + + // "admin.access-control.groups.form.members-list.search.button": "Search", "admin.access-control.groups.form.members-list.search.button": "بحث", + + // "admin.access-control.groups.form.members-list.table.id": "ID", "admin.access-control.groups.form.members-list.table.id": "المعرّف", + + // "admin.access-control.groups.form.members-list.table.name": "Name", "admin.access-control.groups.form.members-list.table.name": "الاسم", - "admin.access-control.groups.form.members-list.table.identity": "هوية", + + // "admin.access-control.groups.form.members-list.table.identity": "Identity", + "admin.access-control.groups.form.members-list.table.identity": "الهوية", + + // "admin.access-control.groups.form.members-list.table.email": "Email", "admin.access-control.groups.form.members-list.table.email": "البريد الإلكتروني", + + // "admin.access-control.groups.form.members-list.table.netid": "NetID", "admin.access-control.groups.form.members-list.table.netid": "NetID", + + // "admin.access-control.groups.form.members-list.table.edit": "Remove / Add", "admin.access-control.groups.form.members-list.table.edit": "إزالة / إضافة", - "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "حذف العضو باسم \"{{name}}\"", - "admin.access-control.groups.form.members-list.notification.success.addMember": "أكمل إضافة العضو: \"{{name}}\"بنجاح", - "admin.access-control.groups.form.members-list.notification.failure.addMember": "فشل في إضافة الموضوع: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"", + "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "حذف عضو باسم \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.success.addMember": "تمت إضافة العضو: \"{{name}}\"بنجاح", + + // "admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.failure.addMember": "فشل إضافة العضو: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", "admin.access-control.groups.form.members-list.notification.success.deleteMember": "تم حذف العضو: \"{{name}}\"بنجاح", - "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "فشل في حذف العضو: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "فشل حذف العضو: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", "admin.access-control.groups.form.members-list.table.edit.buttons.add": "إضافة عضو باسم \"{{name}}\"", - "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "لا توجد مجموعة حاليًا، سيتم تقديم الاسم الجديد.", + + // "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "لا توجد مجموعة نشطة حالياً، قم بتقديم الاسم أولاً.", + + // "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", "admin.access-control.groups.form.members-list.no-members-yet": "لا يوجد أعضاء في المجموعة حتى الآن، قم بالبحث والإضافة.", - "admin.access-control.groups.form.members-list.no-items": "لم يتم العثور على أي شخص إلكترونين في هذا البحث", + + // "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", + "admin.access-control.groups.form.members-list.no-items": "لم يتم العثور على أي أشخاص إلكترونيين في هذا البحث", + + // "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", "admin.access-control.groups.form.subgroups-list.notification.failure": "هناك خطأ ما: \"{{cause}}\"", - "admin.access-control.groups.form.subgroups-list.head": "مجموعات", + + // "admin.access-control.groups.form.subgroups-list.head": "Groups", + "admin.access-control.groups.form.subgroups-list.head": "المجموعات", + + // "admin.access-control.groups.form.subgroups-list.search.head": "Add Subgroup", "admin.access-control.groups.form.subgroups-list.search.head": "إضافة مجموعة فرعية", - "admin.access-control.groups.form.subgroups-list.button.see-all": "مراجعة الكل", - "admin.access-control.groups.form.subgroups-list.headSubgroups": "المجموعات الشكلية", + + // "admin.access-control.groups.form.subgroups-list.button.see-all": "Browse All", + "admin.access-control.groups.form.subgroups-list.button.see-all": "استعراض الكل", + + // "admin.access-control.groups.form.subgroups-list.headSubgroups": "Current Subgroups", + "admin.access-control.groups.form.subgroups-list.headSubgroups": "المجموعات الفرعية الحالية", + + // "admin.access-control.groups.form.subgroups-list.search.button": "Search", "admin.access-control.groups.form.subgroups-list.search.button": "بحث", + + // "admin.access-control.groups.form.subgroups-list.table.id": "ID", "admin.access-control.groups.form.subgroups-list.table.id": "المعرّف", + + // "admin.access-control.groups.form.subgroups-list.table.name": "Name", "admin.access-control.groups.form.subgroups-list.table.name": "الاسم", - "admin.access-control.groups.form.subgroups-list.table.collectionOrCommunity": "ابدأ/المجتمع", + + // "admin.access-control.groups.form.subgroups-list.table.collectionOrCommunity": "Collection/Community", + "admin.access-control.groups.form.subgroups-list.table.collectionOrCommunity": "الحاوية/المجتمع", + + // "admin.access-control.groups.form.subgroups-list.table.edit": "Remove / Add", "admin.access-control.groups.form.subgroups-list.table.edit": "إزالة / إضافة", - "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "إزالة المجموعة الفرعية باسم \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "Remove subgroup with name \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "إزالة مجموعة فرعية باسم \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"", "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "إضافة مجموعة فرعية باسم \"{{name}}\"", - "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "متابعة إضافة المجموعة: \"{{name}}\"بنجاح", - "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "فشل في إضافة المجموعة الفرعية: \"{{name}}\"", - "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "تم حذف المجموعة اليدوية: \"{{name}}\"بنجاح", - "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "فشل حذف المجموعة المصنوعة: \"{{name}}\"", - "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "لا توجد مجموعة حاليًا، سيتم تقديم الاسم الجديد.", - "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "هذه هي المجموعة الحالية، لا يمكن الاتصال بها.", - "admin.access-control.groups.form.subgroups-list.no-items": "لم يتم العثور على مجموعات بهذا الاسم في دارفور أو بكمعرفي فريد", - "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "لا يوجد مجموعات فرعية في المجموعة حتى الآن.", + + // "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "تمت إضافة المجموعة الفرعية: \"{{name}}\"بنجاح", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "فشل إضافة مجموعة فرعية: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "تم حذف المجموعة الفرعية: \"{{name}}\"بنجاح", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Failed to delete subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "فشل حذف المجموعة الفرعية: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "لا توجد مجموعة نشطة حالياً، قم بتقديم الاسم أولاً.", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "This is the current group, can't be added.", + "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "هذه هي المجموعة الحالية، لا يمكن إضافتها.", + + // "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", + "admin.access-control.groups.form.subgroups-list.no-items": "لم يتم العثور على مجموعات بهذا في اسمها أو بهذا كمعرف عمومي فريد", + + // "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", + "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "لا توجد مجموعات فرعية في المجموعة حتى الآن.", + + // "admin.access-control.groups.form.return": "Back", "admin.access-control.groups.form.return": "رجوع", + + // "admin.quality-assurance.breadcrumbs": "Quality Assurance", "admin.quality-assurance.breadcrumbs": "ضمان الجودة", - "admin.notifications.event.breadcrumbs": "آلات ضمان الجودة", - "admin.notifications.event.page.title": "آلات ضمان الجودة", + + // "admin.notifications.event.breadcrumbs": "Quality Assurance Suggestions", + "admin.notifications.event.breadcrumbs": "مقترحات ضمان الجودة", + + // "admin.notifications.event.page.title": "Quality Assurance Suggestions", + "admin.notifications.event.page.title": "مقترحات ضمان الجودة", + + // "admin.quality-assurance.page.title": "Quality Assurance", "admin.quality-assurance.page.title": "ضمان الجودة", + + // "admin.notifications.source.breadcrumbs": "Quality Assurance", "admin.notifications.source.breadcrumbs": "مصدر ضمان الجودة", - "admin.access-control.groups.form.tooltip.editGroupPage": "في هذه الصفحة، يمكنك تعديل مجموعة الخصائص وأعضائها. ", - "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "وتفكر شخصياً في هذه المجموعة أو تأسيسها، قم بالنقر على زر 'استعراض الكل' أو قم باستخدام شريط البحث أدناه للبحث عن المستخدمين (استخدم القائمة المسدلة الموجودة على يسار شريط البحث ما إذا كنت تريد البحث حسب الميتاداتا أو حسب البريد الإلكتروني). ", - "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "وبعد مجموعة فرعية إلى هذه المجموعة أو التغطية منها، قم بالنقر على زر 'استعراض الكل' أو قم باستخدام شريط البحث أدناه للبحث عن المجموعات. ", - "admin.reports.collections.title": "تقرير تصفية المجموعة", - "admin.reports.collections.breadcrumbs": "تقرير تصفية المجموعة", - "admin.reports.collections.head": "تقرير تصفية المجموعة", - "admin.reports.button.show-collections": "عرض المجموعات", - "admin.reports.collections.collections-report": "تقرير التحصيل", - "admin.reports.collections.item-results": "نتائج البند", - "admin.reports.collections.community": "مجتمع", - "admin.reports.collections.collection": "مجموعة", - "admin.reports.collections.nb_items": "ملحوظة. ", - "admin.reports.collections.match_all_selected_filters": "مطابقة جميع المرشحات المحددة", - "admin.reports.items.breadcrumbs": "تقرير استعلام بيانات التعريف", - "admin.reports.items.head": "تقرير استعلام بيانات التعريف", - "admin.reports.items.run": "تشغيل استعلام العنصر", - "admin.reports.items.section.collectionSelector": "محدد المجموعة", - "admin.reports.items.section.metadataFieldQueries": "استعلامات حقل بيانات التعريف", - "admin.reports.items.predefinedQueries": "الاستعلامات المحددة مسبقًا", - "admin.reports.items.section.limitPaginateQueries": "استعلامات الحد/الصفحات", - "admin.reports.items.limit": "حد/", - "admin.reports.items.offset": "عوض", - "admin.reports.items.wholeRepo": "المستودع كله", - "admin.reports.items.anyField": "أي مجال", - "admin.reports.items.predicate.exists": "موجود", - "admin.reports.items.predicate.doesNotExist": "غير موجود", - "admin.reports.items.predicate.equals": "يساوي", - "admin.reports.items.predicate.doesNotEqual": "لا يساوي", - "admin.reports.items.predicate.like": "يحب", - "admin.reports.items.predicate.notLike": "لا يشبه", - "admin.reports.items.predicate.contains": "يتضمن", - "admin.reports.items.predicate.doesNotContain": "لا يحتوي", - "admin.reports.items.predicate.matches": "اعواد الكبريت", - "admin.reports.items.predicate.doesNotMatch": "غير متطابق", - "admin.reports.items.preset.new": "استعلام جديد", - "admin.reports.items.preset.hasNoTitle": "لا يوجد لديه عنوان", - "admin.reports.items.preset.hasNoIdentifierUri": "لا يوجد لديه dc.identifier.uri", - "admin.reports.items.preset.hasCompoundSubject": "لديه موضوع مركب", - "admin.reports.items.preset.hasCompoundAuthor": "يحتوي على مركب dc.contributor.author", - "admin.reports.items.preset.hasCompoundCreator": "لديه مجمع DC.creator", - "admin.reports.items.preset.hasUrlInDescription": "لديه عنوان URL في dc.description", - "admin.reports.items.preset.hasFullTextInProvenance": "يحتوي على النص الكامل في dc.description.provenance", - "admin.reports.items.preset.hasNonFullTextInProvenance": "يحتوي على نص غير كامل في dc.description.provenance", - "admin.reports.items.preset.hasEmptyMetadata": "تحتوي على بيانات وصفية فارغة", - "admin.reports.items.preset.hasUnbreakingDataInDescription": "يحتوي على بيانات وصفية غير منقطعة في الوصف", - "admin.reports.items.preset.hasXmlEntityInMetadata": "يحتوي على كيان XML في بيانات التعريف", - "admin.reports.items.preset.hasNonAsciiCharInMetadata": "يحتوي على حرف غير ascii في البيانات الوصفية", - "admin.reports.items.number": "لا.", + + // "admin.access-control.groups.form.tooltip.editGroupPage": "On this page, you can modify the properties and members of a group. In the top section, you can edit the group name and description, unless this is an admin group for a collection or community, in which case the group name and description are auto-generated and cannot be edited. In the following sections, you can edit group membership. See [the wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group) for more details.", + "admin.access-control.groups.form.tooltip.editGroupPage": "في هذه الصفحة، يمكنك تعديل خصائص المجموعة وأعضائها. في القسم العلوي، يمكنك تحرير اسم المجموعة ووصفها، ما لم تكن هذه مجموعة إدارية لحاوية أو مجتمع، وفي هذه الحالة يتم إنشاء اسم المجموعة ووصفها تلقائياً ولا يمكن تحريرهما. في الأقسام التالية، يمكنك تعديل عضوية المجموعة. انظر [الويكي](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group) للمزيد من التفاصيل.", + + // "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "To add or remove an EPerson to/from this group, either click the 'Browse All' button or use the search bar below to search for users (use the dropdown to the left of the search bar to choose whether to search by metadata or by email). Then click the plus icon for each user you wish to add in the list below, or the trash can icon for each user you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages.", + "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "لإضافة شخص إلكتروني إلى هذه المجموعة أو إزالته منها، قم بالنقر على زر 'استعراض الكل' أو قم باستخدام شريط البحث أدناه للبحث عن المستخدمين (استخدم القائمة المنسدلة الموجودة على يسار شريط البحث لاختيار ما إذا كنت تريد البحث حسب الميتاداتا أو حسب البريد الإلكتروني). ثم قم بالنقر على أيقونة زائد لكل مستخدم ترغب في إضافته في القائمة أدناه، أو أيقونة سلة المهملات لكل مستخدم ترغب في إزالته. قد تحتوي القائمة أدناه على عدة صفحات: استخدم عناصر التحكم في الصفحة الموجودة أسفل القائمة للانتقال إلى الصفحات التالية.", + + // "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "To add or remove a Subgroup to/from this group, either click the 'Browse All' button or use the search bar below to search for groups. Then click the plus icon for each group you wish to add in the list below, or the trash can icon for each group you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages.", + "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "لإضافة مجموعة فرعية إلى هذه المجموعة أو إزالتها منها، قم بالنقر على زر 'استعراض الكل' أو قم باستخدام شريط البحث أدناه للبحث عن المجموعات. ثم قم بالنقر على أيقونة زائد لكل مجموعة ترغب في إضافتها في القائمة أدناه، أو أيقونة سلة المهملات لكل مجموعة ترغب في إزالتها. قد تحتوي القائمة أدناه على عدة صفحات: استخدم عناصر التحكم في الصفحة الموجودة أسفل القائمة للانتقال إلى الصفحات التالية.", + + // "admin.reports.collections.title": "Collection Filter Report", + // TODO New key - Add a translation + "admin.reports.collections.title": "Collection Filter Report", + + // "admin.reports.collections.breadcrumbs": "Collection Filter Report", + // TODO New key - Add a translation + "admin.reports.collections.breadcrumbs": "Collection Filter Report", + + // "admin.reports.collections.head": "Collection Filter Report", + // TODO New key - Add a translation + "admin.reports.collections.head": "Collection Filter Report", + + // "admin.reports.button.show-collections": "Show Collections", + // TODO New key - Add a translation + "admin.reports.button.show-collections": "Show Collections", + + // "admin.reports.collections.collections-report": "Collection Report", + // TODO New key - Add a translation + "admin.reports.collections.collections-report": "Collection Report", + + // "admin.reports.collections.item-results": "Item Results", + // TODO New key - Add a translation + "admin.reports.collections.item-results": "Item Results", + + // "admin.reports.collections.community": "Community", + // TODO New key - Add a translation + "admin.reports.collections.community": "Community", + + // "admin.reports.collections.collection": "Collection", + // TODO New key - Add a translation + "admin.reports.collections.collection": "Collection", + + // "admin.reports.collections.nb_items": "Nb. Items", + // TODO New key - Add a translation + "admin.reports.collections.nb_items": "Nb. Items", + + // "admin.reports.collections.match_all_selected_filters": "Matching all selected filters", + // TODO New key - Add a translation + "admin.reports.collections.match_all_selected_filters": "Matching all selected filters", + + // "admin.reports.items.breadcrumbs": "Metadata Query Report", + // TODO New key - Add a translation + "admin.reports.items.breadcrumbs": "Metadata Query Report", + + // "admin.reports.items.head": "Metadata Query Report", + // TODO New key - Add a translation + "admin.reports.items.head": "Metadata Query Report", + + // "admin.reports.items.run": "Run Item Query", + // TODO New key - Add a translation + "admin.reports.items.run": "Run Item Query", + + // "admin.reports.items.section.collectionSelector": "Collection Selector", + // TODO New key - Add a translation + "admin.reports.items.section.collectionSelector": "Collection Selector", + + // "admin.reports.items.section.metadataFieldQueries": "Metadata Field Queries", + // TODO New key - Add a translation + "admin.reports.items.section.metadataFieldQueries": "Metadata Field Queries", + + // "admin.reports.items.predefinedQueries": "Predefined Queries", + // TODO New key - Add a translation + "admin.reports.items.predefinedQueries": "Predefined Queries", + + // "admin.reports.items.section.limitPaginateQueries": "Limit/Paginate Queries", + // TODO New key - Add a translation + "admin.reports.items.section.limitPaginateQueries": "Limit/Paginate Queries", + + // "admin.reports.items.limit": "Limit/", + // TODO New key - Add a translation + "admin.reports.items.limit": "Limit/", + + // "admin.reports.items.offset": "Offset", + // TODO New key - Add a translation + "admin.reports.items.offset": "Offset", + + // "admin.reports.items.wholeRepo": "Whole Repository", + // TODO New key - Add a translation + "admin.reports.items.wholeRepo": "Whole Repository", + + // "admin.reports.items.anyField": "Any field", + // TODO New key - Add a translation + "admin.reports.items.anyField": "Any field", + + // "admin.reports.items.predicate.exists": "exists", + // TODO New key - Add a translation + "admin.reports.items.predicate.exists": "exists", + + // "admin.reports.items.predicate.doesNotExist": "does not exist", + // TODO New key - Add a translation + "admin.reports.items.predicate.doesNotExist": "does not exist", + + // "admin.reports.items.predicate.equals": "equals", + // TODO New key - Add a translation + "admin.reports.items.predicate.equals": "equals", + + // "admin.reports.items.predicate.doesNotEqual": "does not equal", + // TODO New key - Add a translation + "admin.reports.items.predicate.doesNotEqual": "does not equal", + + // "admin.reports.items.predicate.like": "like", + // TODO New key - Add a translation + "admin.reports.items.predicate.like": "like", + + // "admin.reports.items.predicate.notLike": "not like", + // TODO New key - Add a translation + "admin.reports.items.predicate.notLike": "not like", + + // "admin.reports.items.predicate.contains": "contains", + // TODO New key - Add a translation + "admin.reports.items.predicate.contains": "contains", + + // "admin.reports.items.predicate.doesNotContain": "does not contain", + // TODO New key - Add a translation + "admin.reports.items.predicate.doesNotContain": "does not contain", + + // "admin.reports.items.predicate.matches": "matches", + // TODO New key - Add a translation + "admin.reports.items.predicate.matches": "matches", + + // "admin.reports.items.predicate.doesNotMatch": "does not match", + // TODO New key - Add a translation + "admin.reports.items.predicate.doesNotMatch": "does not match", + + // "admin.reports.items.preset.new": "New Query", + // TODO New key - Add a translation + "admin.reports.items.preset.new": "New Query", + + // "admin.reports.items.preset.hasNoTitle": "Has No Title", + // TODO New key - Add a translation + "admin.reports.items.preset.hasNoTitle": "Has No Title", + + // "admin.reports.items.preset.hasNoIdentifierUri": "Has No dc.identifier.uri", + // TODO New key - Add a translation + "admin.reports.items.preset.hasNoIdentifierUri": "Has No dc.identifier.uri", + + // "admin.reports.items.preset.hasCompoundSubject": "Has compound subject", + // TODO New key - Add a translation + "admin.reports.items.preset.hasCompoundSubject": "Has compound subject", + + // "admin.reports.items.preset.hasCompoundAuthor": "Has compound dc.contributor.author", + // TODO New key - Add a translation + "admin.reports.items.preset.hasCompoundAuthor": "Has compound dc.contributor.author", + + // "admin.reports.items.preset.hasCompoundCreator": "Has compound dc.creator", + // TODO New key - Add a translation + "admin.reports.items.preset.hasCompoundCreator": "Has compound dc.creator", + + // "admin.reports.items.preset.hasUrlInDescription": "Has URL in dc.description", + // TODO New key - Add a translation + "admin.reports.items.preset.hasUrlInDescription": "Has URL in dc.description", + + // "admin.reports.items.preset.hasFullTextInProvenance": "Has full text in dc.description.provenance", + // TODO New key - Add a translation + "admin.reports.items.preset.hasFullTextInProvenance": "Has full text in dc.description.provenance", + + // "admin.reports.items.preset.hasNonFullTextInProvenance": "Has non-full text in dc.description.provenance", + // TODO New key - Add a translation + "admin.reports.items.preset.hasNonFullTextInProvenance": "Has non-full text in dc.description.provenance", + + // "admin.reports.items.preset.hasEmptyMetadata": "Has empty metadata", + // TODO New key - Add a translation + "admin.reports.items.preset.hasEmptyMetadata": "Has empty metadata", + + // "admin.reports.items.preset.hasUnbreakingDataInDescription": "Has unbreaking metadata in description", + // TODO New key - Add a translation + "admin.reports.items.preset.hasUnbreakingDataInDescription": "Has unbreaking metadata in description", + + // "admin.reports.items.preset.hasXmlEntityInMetadata": "Has XML entity in metadata", + // TODO New key - Add a translation + "admin.reports.items.preset.hasXmlEntityInMetadata": "Has XML entity in metadata", + + // "admin.reports.items.preset.hasNonAsciiCharInMetadata": "Has non-ascii character in metadata", + // TODO New key - Add a translation + "admin.reports.items.preset.hasNonAsciiCharInMetadata": "Has non-ascii character in metadata", + + // "admin.reports.items.number": "No.", + // TODO New key - Add a translation + "admin.reports.items.number": "No.", + + // "admin.reports.items.id": "UUID", + // TODO New key - Add a translation "admin.reports.items.id": "UUID", - "admin.reports.items.collection": "مجموعة", + + // "admin.reports.items.collection": "Collection", + // TODO New key - Add a translation + "admin.reports.items.collection": "Collection", + + // "admin.reports.items.handle": "URI", + // TODO New key - Add a translation "admin.reports.items.handle": "URI", - "admin.reports.items.title": "عنوان", - "admin.reports.commons.filters": "المرشحات", - "admin.reports.commons.additional-data": "بيانات إضافية للعودة", - "admin.reports.commons.previous-page": "الصفحة السابقة", - "admin.reports.commons.next-page": "الصفحة التالية", - "admin.reports.commons.page": "صفحة", - "admin.reports.commons.of": "ل", - "admin.reports.commons.export": "تصدير لتحديث بيانات التعريف", - "admin.reports.commons.filters.deselect_all": "قم بإلغاء تحديد جميع المرشحات", - "admin.reports.commons.filters.select_all": "حدد كافة المرشحات", - "admin.reports.commons.filters.matches_all": "يطابق جميع المرشحات المحددة", - "admin.reports.commons.filters.property": "عوامل تصفية خصائص العنصر", - "admin.reports.commons.filters.property.is_item": "هل البند - صحيح دائمًا", - "admin.reports.commons.filters.property.is_withdrawn": "العناصر المسحوبة", - "admin.reports.commons.filters.property.is_not_withdrawn": "العناصر المتوفرة - لم يتم سحبها", - "admin.reports.commons.filters.property.is_discoverable": "العناصر القابلة للاكتشاف - ليست خاصة", - "admin.reports.commons.filters.property.is_not_discoverable": "غير قابل للاكتشاف - عنصر خاص", - "admin.reports.commons.filters.bitstream": "مرشحات تيار البت الأساسية", - "admin.reports.commons.filters.bitstream.has_multiple_originals": "يحتوي العنصر على تدفقات بت أصلية متعددة", - "admin.reports.commons.filters.bitstream.has_no_originals": "لا يحتوي العنصر على تدفقات بت أصلية", - "admin.reports.commons.filters.bitstream.has_one_original": "يحتوي العنصر على تدفق بت أصلي واحد", - "admin.reports.commons.filters.bitstream_mime": "عوامل تصفية Bitstream حسب نوع MIME", - "admin.reports.commons.filters.bitstream_mime.has_doc_original": "يحتوي العنصر على Doc Original Bitstream (PDF، Office، Text، HTML، XML، إلخ)", - "admin.reports.commons.filters.bitstream_mime.has_image_original": "يحتوي العنصر على تدفق بت للصورة الأصلية", - "admin.reports.commons.filters.bitstream_mime.has_unsupp_type": "يحتوي على أنواع Bitstream أخرى (ليست Doc أو Image)", - "admin.reports.commons.filters.bitstream_mime.has_mixed_original": "يحتوي العنصر على أنواع متعددة من تدفقات البت الأصلية (Doc، Image، Other)", - "admin.reports.commons.filters.bitstream_mime.has_pdf_original": "يحتوي العنصر على تدفق بت أصلي بتنسيق PDF", - "admin.reports.commons.filters.bitstream_mime.has_jpg_original": "يحتوي العنصر على JPG Original Bitstream", - "admin.reports.commons.filters.bitstream_mime.has_small_pdf": "يحتوي على ملف PDF صغير بشكل غير عادي", - "admin.reports.commons.filters.bitstream_mime.has_large_pdf": "يحتوي على ملف PDF كبير الحجم بشكل غير عادي", - "admin.reports.commons.filters.bitstream_mime.has_doc_without_text": "يحتوي على تدفق بت للمستند بدون عنصر TEXT", - "admin.reports.commons.filters.mime": "عوامل تصفية نوع MIME المدعومة", - "admin.reports.commons.filters.mime.has_only_supp_image_type": "يتم دعم تدفقات البت لصورة العنصر", - "admin.reports.commons.filters.mime.has_unsupp_image_type": "يحتوي العنصر على Image Bitstream غير مدعوم", - "admin.reports.commons.filters.mime.has_only_supp_doc_type": "يتم دعم تدفقات بت مستند العنصر", - "admin.reports.commons.filters.mime.has_unsupp_doc_type": "يحتوي العنصر على تدفق بت للمستند غير مدعوم", - "admin.reports.commons.filters.bundle": "مرشحات حزمة Bitstream", - "admin.reports.commons.filters.bundle.has_unsupported_bundle": "يحتوي على تدفق بت في حزمة غير مدعومة", - "admin.reports.commons.filters.bundle.has_small_thumbnail": "لديه صورة مصغرة صغيرة بشكل غير عادي", - "admin.reports.commons.filters.bundle.has_original_without_thumbnail": "يحتوي على تدفق بت أصلي بدون صورة مصغرة", - "admin.reports.commons.filters.bundle.has_invalid_thumbnail_name": "يحتوي على اسم صورة مصغرة غير صالح (بافتراض صورة مصغرة واحدة لكل نسخة أصلية)", - "admin.reports.commons.filters.bundle.has_non_generated_thumb": "تحتوي على صورة مصغرة لم يتم إنشاؤها", - "admin.reports.commons.filters.bundle.no_license": "ليس لديه ترخيص", - "admin.reports.commons.filters.bundle.has_license_documentation": "لديه وثائق في حزمة الترخيص", - "admin.reports.commons.filters.permission": "مرشحات الأذونات", - "admin.reports.commons.filters.permission.has_restricted_original": "يحتوي العنصر على تدفق بت أصلي مقيد", - "admin.reports.commons.filters.permission.has_restricted_original.tooltip": "يحتوي العنصر على تدفق بت أصلي واحد على الأقل لا يمكن للمستخدم المجهول الوصول إليه", - "admin.reports.commons.filters.permission.has_restricted_thumbnail": "يحتوي العنصر على صورة مصغرة مقيدة", - "admin.reports.commons.filters.permission.has_restricted_thumbnail.tooltip": "يحتوي العنصر على صورة مصغرة واحدة على الأقل لا يمكن للمستخدم المجهول الوصول إليها", - "admin.reports.commons.filters.permission.has_restricted_metadata": "يحتوي العنصر على بيانات وصفية مقيدة", - "admin.reports.commons.filters.permission.has_restricted_metadata.tooltip": "يحتوي العنصر على بيانات تعريف لا يمكن للمستخدم المجهول الوصول إليها", + + // "admin.reports.items.title": "Title", + // TODO New key - Add a translation + "admin.reports.items.title": "Title", + + // "admin.reports.commons.filters": "Filters", + // TODO New key - Add a translation + "admin.reports.commons.filters": "Filters", + + // "admin.reports.commons.additional-data": "Additional data to return", + // TODO New key - Add a translation + "admin.reports.commons.additional-data": "Additional data to return", + + // "admin.reports.commons.previous-page": "Prev Page", + // TODO New key - Add a translation + "admin.reports.commons.previous-page": "Prev Page", + + // "admin.reports.commons.next-page": "Next Page", + // TODO New key - Add a translation + "admin.reports.commons.next-page": "Next Page", + + // "admin.reports.commons.page": "Page", + // TODO New key - Add a translation + "admin.reports.commons.page": "Page", + + // "admin.reports.commons.of": "of", + // TODO New key - Add a translation + "admin.reports.commons.of": "of", + + // "admin.reports.commons.export": "Export for Metadata Update", + // TODO New key - Add a translation + "admin.reports.commons.export": "Export for Metadata Update", + + // "admin.reports.commons.filters.deselect_all": "Deselect all filters", + // TODO New key - Add a translation + "admin.reports.commons.filters.deselect_all": "Deselect all filters", + + // "admin.reports.commons.filters.select_all": "Select all filters", + // TODO New key - Add a translation + "admin.reports.commons.filters.select_all": "Select all filters", + + // "admin.reports.commons.filters.matches_all": "Matches all specified filters", + // TODO New key - Add a translation + "admin.reports.commons.filters.matches_all": "Matches all specified filters", + + // "admin.reports.commons.filters.property": "Item Property Filters", + // TODO New key - Add a translation + "admin.reports.commons.filters.property": "Item Property Filters", + + // "admin.reports.commons.filters.property.is_item": "Is Item - always true", + // TODO New key - Add a translation + "admin.reports.commons.filters.property.is_item": "Is Item - always true", + + // "admin.reports.commons.filters.property.is_withdrawn": "Withdrawn Items", + // TODO New key - Add a translation + "admin.reports.commons.filters.property.is_withdrawn": "Withdrawn Items", + + // "admin.reports.commons.filters.property.is_not_withdrawn": "Available Items - Not Withdrawn", + // TODO New key - Add a translation + "admin.reports.commons.filters.property.is_not_withdrawn": "Available Items - Not Withdrawn", + + // "admin.reports.commons.filters.property.is_discoverable": "Discoverable Items - Not Private", + // TODO New key - Add a translation + "admin.reports.commons.filters.property.is_discoverable": "Discoverable Items - Not Private", + + // "admin.reports.commons.filters.property.is_not_discoverable": "Not Discoverable - Private Item", + // TODO New key - Add a translation + "admin.reports.commons.filters.property.is_not_discoverable": "Not Discoverable - Private Item", + + // "admin.reports.commons.filters.bitstream": "Basic Bitstream Filters", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream": "Basic Bitstream Filters", + + // "admin.reports.commons.filters.bitstream.has_multiple_originals": "Item has Multiple Original Bitstreams", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream.has_multiple_originals": "Item has Multiple Original Bitstreams", + + // "admin.reports.commons.filters.bitstream.has_no_originals": "Item has No Original Bitstreams", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream.has_no_originals": "Item has No Original Bitstreams", + + // "admin.reports.commons.filters.bitstream.has_one_original": "Item has One Original Bitstream", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream.has_one_original": "Item has One Original Bitstream", + + // "admin.reports.commons.filters.bitstream_mime": "Bitstream Filters by MIME Type", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime": "Bitstream Filters by MIME Type", + + // "admin.reports.commons.filters.bitstream_mime.has_doc_original": "Item has a Doc Original Bitstream (PDF, Office, Text, HTML, XML, etc)", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_doc_original": "Item has a Doc Original Bitstream (PDF, Office, Text, HTML, XML, etc)", + + // "admin.reports.commons.filters.bitstream_mime.has_image_original": "Item has an Image Original Bitstream", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_image_original": "Item has an Image Original Bitstream", + + // "admin.reports.commons.filters.bitstream_mime.has_unsupp_type": "Has Other Bitstream Types (not Doc or Image)", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_unsupp_type": "Has Other Bitstream Types (not Doc or Image)", + + // "admin.reports.commons.filters.bitstream_mime.has_mixed_original": "Item has multiple types of Original Bitstreams (Doc, Image, Other)", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_mixed_original": "Item has multiple types of Original Bitstreams (Doc, Image, Other)", + + // "admin.reports.commons.filters.bitstream_mime.has_pdf_original": "Item has a PDF Original Bitstream", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_pdf_original": "Item has a PDF Original Bitstream", + + // "admin.reports.commons.filters.bitstream_mime.has_jpg_original": "Item has JPG Original Bitstream", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_jpg_original": "Item has JPG Original Bitstream", + + // "admin.reports.commons.filters.bitstream_mime.has_small_pdf": "Has unusually small PDF", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_small_pdf": "Has unusually small PDF", + + // "admin.reports.commons.filters.bitstream_mime.has_large_pdf": "Has unusually large PDF", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_large_pdf": "Has unusually large PDF", + + // "admin.reports.commons.filters.bitstream_mime.has_doc_without_text": "Has document bitstream without TEXT item", + // TODO New key - Add a translation + "admin.reports.commons.filters.bitstream_mime.has_doc_without_text": "Has document bitstream without TEXT item", + + // "admin.reports.commons.filters.mime": "Supported MIME Type Filters", + // TODO New key - Add a translation + "admin.reports.commons.filters.mime": "Supported MIME Type Filters", + + // "admin.reports.commons.filters.mime.has_only_supp_image_type": "Item Image Bitstreams are Supported", + // TODO New key - Add a translation + "admin.reports.commons.filters.mime.has_only_supp_image_type": "Item Image Bitstreams are Supported", + + // "admin.reports.commons.filters.mime.has_unsupp_image_type": "Item has Image Bitstream that is Unsupported", + // TODO New key - Add a translation + "admin.reports.commons.filters.mime.has_unsupp_image_type": "Item has Image Bitstream that is Unsupported", + + // "admin.reports.commons.filters.mime.has_only_supp_doc_type": "Item Document Bitstreams are Supported", + // TODO New key - Add a translation + "admin.reports.commons.filters.mime.has_only_supp_doc_type": "Item Document Bitstreams are Supported", + + // "admin.reports.commons.filters.mime.has_unsupp_doc_type": "Item has Document Bitstream that is Unsupported", + // TODO New key - Add a translation + "admin.reports.commons.filters.mime.has_unsupp_doc_type": "Item has Document Bitstream that is Unsupported", + + // "admin.reports.commons.filters.bundle": "Bitstream Bundle Filters", + // TODO New key - Add a translation + "admin.reports.commons.filters.bundle": "Bitstream Bundle Filters", + + // "admin.reports.commons.filters.bundle.has_unsupported_bundle": "Has bitstream in an unsupported bundle", + // TODO New key - Add a translation + "admin.reports.commons.filters.bundle.has_unsupported_bundle": "Has bitstream in an unsupported bundle", + + // "admin.reports.commons.filters.bundle.has_small_thumbnail": "Has unusually small thumbnail", + // TODO New key - Add a translation + "admin.reports.commons.filters.bundle.has_small_thumbnail": "Has unusually small thumbnail", + + // "admin.reports.commons.filters.bundle.has_original_without_thumbnail": "Has original bitstream without thumbnail", + // TODO New key - Add a translation + "admin.reports.commons.filters.bundle.has_original_without_thumbnail": "Has original bitstream without thumbnail", + + // "admin.reports.commons.filters.bundle.has_invalid_thumbnail_name": "Has invalid thumbnail name (assumes one thumbnail for each original)", + // TODO New key - Add a translation + "admin.reports.commons.filters.bundle.has_invalid_thumbnail_name": "Has invalid thumbnail name (assumes one thumbnail for each original)", + + // "admin.reports.commons.filters.bundle.has_non_generated_thumb": "Has non-generated thumbnail", + // TODO New key - Add a translation + "admin.reports.commons.filters.bundle.has_non_generated_thumb": "Has non-generated thumbnail", + + // "admin.reports.commons.filters.bundle.no_license": "Doesn't have a license", + // TODO New key - Add a translation + "admin.reports.commons.filters.bundle.no_license": "Doesn't have a license", + + // "admin.reports.commons.filters.bundle.has_license_documentation": "Has documentation in the license bundle", + // TODO New key - Add a translation + "admin.reports.commons.filters.bundle.has_license_documentation": "Has documentation in the license bundle", + + // "admin.reports.commons.filters.permission": "Permission Filters", + // TODO New key - Add a translation + "admin.reports.commons.filters.permission": "Permission Filters", + + // "admin.reports.commons.filters.permission.has_restricted_original": "Item has Restricted Original Bitstream", + // TODO New key - Add a translation + "admin.reports.commons.filters.permission.has_restricted_original": "Item has Restricted Original Bitstream", + + // "admin.reports.commons.filters.permission.has_restricted_original.tooltip": "Item has at least one original bitstream that is not accessible to Anonymous user", + // TODO New key - Add a translation + "admin.reports.commons.filters.permission.has_restricted_original.tooltip": "Item has at least one original bitstream that is not accessible to Anonymous user", + + // "admin.reports.commons.filters.permission.has_restricted_thumbnail": "Item has Restricted Thumbnail", + // TODO New key - Add a translation + "admin.reports.commons.filters.permission.has_restricted_thumbnail": "Item has Restricted Thumbnail", + + // "admin.reports.commons.filters.permission.has_restricted_thumbnail.tooltip": "Item has at least one thumbnail that is not accessible to Anonymous user", + // TODO New key - Add a translation + "admin.reports.commons.filters.permission.has_restricted_thumbnail.tooltip": "Item has at least one thumbnail that is not accessible to Anonymous user", + + // "admin.reports.commons.filters.permission.has_restricted_metadata": "Item has Restricted Metadata", + // TODO New key - Add a translation + "admin.reports.commons.filters.permission.has_restricted_metadata": "Item has Restricted Metadata", + + // "admin.reports.commons.filters.permission.has_restricted_metadata.tooltip": "Item has metadata that is not accessible to Anonymous user", + // TODO New key - Add a translation + "admin.reports.commons.filters.permission.has_restricted_metadata.tooltip": "Item has metadata that is not accessible to Anonymous user", + + // "admin.search.breadcrumbs": "Administrative Search", "admin.search.breadcrumbs": "بحث إداري", + + // "admin.search.collection.edit": "Edit", "admin.search.collection.edit": "تحرير", + + // "admin.search.community.edit": "Edit", "admin.search.community.edit": "تحرير", + + // "admin.search.item.delete": "Delete", "admin.search.item.delete": "حذف", + + // "admin.search.item.edit": "Edit", "admin.search.item.edit": "تحرير", - "admin.search.item.make-private": "اجعله غير للاكتشاف", - "admin.search.item.make-public": "اجعله للاكتشاف", + + // "admin.search.item.make-private": "Make non-discoverable", + "admin.search.item.make-private": "اجعله غير قابل للاكتشاف", + + // "admin.search.item.make-public": "Make discoverable", + "admin.search.item.make-public": "اجعله قابل للاكتشاف", + + // "admin.search.item.move": "Move", "admin.search.item.move": "نقل", + + // "admin.search.item.reinstate": "Reinstate", "admin.search.item.reinstate": "إعادة تعيين", - "admin.search.item.withdraw": "يسحب", + + // "admin.search.item.withdraw": "Withdraw", + "admin.search.item.withdraw": "سحب", + + // "admin.search.title": "Administrative Search", "admin.search.title": "بحث إداري", + + // "administrativeView.search.results.head": "Administrative Search", "administrativeView.search.results.head": "بحث إداري", + + // "admin.workflow.breadcrumbs": "Administer Workflow", "admin.workflow.breadcrumbs": "أدر سير العمل", + + // "admin.workflow.title": "Administer Workflow", "admin.workflow.title": "أدر سير العمل", + + // "admin.workflow.item.workflow": "Workflow", "admin.workflow.item.workflow": "سير العمل", + + // "admin.workflow.item.workspace": "Workspace", "admin.workflow.item.workspace": "مساحة العمل", + + // "admin.workflow.item.delete": "Delete", "admin.workflow.item.delete": "حذف", - "admin.workflow.item.send-back": "إعادة الإرسال", - "admin.workflow.item.policies": "تماما", - "admin.workflow.item.supervision": "شاهد", - "admin.metadata-import.breadcrumbs": "قم باستيراد الميتاداتا", + + // "admin.workflow.item.send-back": "Send back", + "admin.workflow.item.send-back": "إعادة إرسال", + + // "admin.workflow.item.policies": "Policies", + "admin.workflow.item.policies": "السياسات", + + // "admin.workflow.item.supervision": "Supervision", + "admin.workflow.item.supervision": "الإشراف", + + // "admin.metadata-import.breadcrumbs": "Import Metadata", + "admin.metadata-import.breadcrumbs": "استيراد الميتاداتا", + + // "admin.batch-import.breadcrumbs": "Import Batch", "admin.batch-import.breadcrumbs": "استيراد الدفعة", - "admin.metadata-import.title": "قم باستيراد الميتاداتا", + + // "admin.metadata-import.title": "Import Metadata", + "admin.metadata-import.title": "استيراد الميتاداتا", + + // "admin.batch-import.title": "Import Batch", "admin.batch-import.title": "استيراد الدفعة", - "admin.metadata-import.page.header": "قم باستيراد الميتاداتا", + + // "admin.metadata-import.page.header": "Import Metadata", + "admin.metadata-import.page.header": "استيراد الميتاداتا", + + // "admin.batch-import.page.header": "Import Batch", "admin.batch-import.page.header": "استيراد الدفعة", - "admin.metadata-import.page.help": "يمكنك أن تحتوي أو تستعرض ملفات CSV التي تحتوي على عمليات ميتة بالدفع على الملفات من هنا", - "admin.batch-import.page.help": "حدد المراد الاستيراد منها. ", - "admin.batch-import.page.toggle.help": "من خلال إجراء الاستيراد إما عن طريق تحميل الملف أو عبر عنوان URL، استخدم المزيد لتعيين مصدر الإدخال", - "admin.metadata-import.page.dropMsg": "قم بإسقاط ملف CSV للميتاداتا للاستيراده", + + // "admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here", + "admin.metadata-import.page.help": "يمكنك إفلات أو استعراض ملفات CSV التي تحتوي على عمليات ميتاداتا بالدفعة على الملفات من هنا", + + // "admin.batch-import.page.help": "Select the Collection to import into. Then, drop or browse to a Simple Archive Format (SAF) zip file that includes the Items to import", + "admin.batch-import.page.help": "حدد الحاوية المراد الاستيراد إليها. بعد ذلك، قم بإسقاط أو تصفح ملف مضغوط بتنسيق أرشيف بسيط (SAF) يتضمن المواد المراد استيرادها", + + // "admin.batch-import.page.toggle.help": "It is possible to perform import either with file upload or via URL, use above toggle to set the input source", + "admin.batch-import.page.toggle.help": "من الممكن إجراء الاستيراد إما عن طريق تحميل الملف أو عبر عنوان URL، استخدم التبديل أعلاه لتعيين مصدر الإدخال", + + // "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", + "admin.metadata-import.page.dropMsg": "قم بإسقاط ملف CSV للميتاداتا لاستيراده", + + // "admin.batch-import.page.dropMsg": "Drop a batch ZIP to import", "admin.batch-import.page.dropMsg": "قم بإسقاط ZIP الدفعة المراد استيرادها", - "admin.metadata-import.page.dropMsgReplace": "قم بالمسح لاستبدال ملف CSV للميتاداتا المراد استيراده", - "admin.batch-import.page.dropMsgReplace": "قم بالمسح لاستبدال ZIP الدفعة المراد استيرادها", + + // "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", + "admin.metadata-import.page.dropMsgReplace": "قم بالإسقاط لاستبدال ملف CSV للميتاداتا المراد استيراده", + + // "admin.batch-import.page.dropMsgReplace": "Drop to replace the batch ZIP to import", + "admin.batch-import.page.dropMsgReplace": "قم بالإسقاط لاستبدال ZIP الدفعة المراد استيرادها", + + // "admin.metadata-import.page.button.return": "Back", "admin.metadata-import.page.button.return": "رجوع", + + // "admin.metadata-import.page.button.proceed": "Proceed", "admin.metadata-import.page.button.proceed": "متابعة", - "admin.metadata-import.page.button.select-collection": "حدد", - "admin.metadata-import.page.error.addFile": "حدد ملف الجديد!", - "admin.metadata-import.page.error.addFileUrl": "أدخل عنوان URL للملف الجديد!", - "admin.batch-import.page.error.addFile": "حدد ملف ZIP الجديد!", + + // "admin.metadata-import.page.button.select-collection": "Select Collection", + "admin.metadata-import.page.button.select-collection": "حدد الحاوية", + + // "admin.metadata-import.page.error.addFile": "Select file first!", + "admin.metadata-import.page.error.addFile": "حدد ملف أولاً!", + + // "admin.metadata-import.page.error.addFileUrl": "Insert file URL first!", + "admin.metadata-import.page.error.addFileUrl": "أدخل عنوان URL للملف أولاً!", + + // "admin.batch-import.page.error.addFile": "Select ZIP file first!", + "admin.batch-import.page.error.addFile": "حدد ملف ZIP أولاً!", + + // "admin.metadata-import.page.toggle.upload": "Upload", "admin.metadata-import.page.toggle.upload": "تحميل", + + // "admin.metadata-import.page.toggle.url": "URL", "admin.metadata-import.page.toggle.url": "عنوان URL", - "admin.metadata-import.page.urlMsg": "قم بالضغط على عنوان url لملف ZIP الخاص بالدفعة للاستيراده", + + // "admin.metadata-import.page.urlMsg": "Insert the batch ZIP url to import", + "admin.metadata-import.page.urlMsg": "قم بإدخال عنوان url لملف ZIP الخاص بالدفعة لاستيراده", + + // "admin.metadata-import.page.validateOnly": "Validate Only", "admin.metadata-import.page.validateOnly": "التحقق فقط", - "admin.metadata-import.page.validateOnly.hint": "عند التحديد، سيتم التحقق من صحة ملف CSV الذي تم تحميله. ", + + // "admin.metadata-import.page.validateOnly.hint": "When selected, the uploaded CSV will be validated. You will receive a report of detected changes, but no changes will be saved.", + "admin.metadata-import.page.validateOnly.hint": "عند التحديد، سيتم التحقق من صحة ملف CSV الذي تم تحميله. ستتلقى تقريراً بالتغييرات التي تم اكتشافها، ولكن لن يتم حفظ أي تغييرات.", + + // "advanced-workflow-action.rating.form.rating.label": "Rating", "advanced-workflow-action.rating.form.rating.label": "التقييم", + + // "advanced-workflow-action.rating.form.rating.error": "You must rate the item", "advanced-workflow-action.rating.form.rating.error": "يجب عليك تقييم هذه المادة", + + // "advanced-workflow-action.rating.form.review.label": "Review", "advanced-workflow-action.rating.form.review.label": "مراجعة", - "advanced-workflow-action.rating.form.review.error": "يجب عليك تفصيل تفاصيل لتقديم هذا التقييم", - "advanced-workflow-action.rating.description": "برجاء تحديد التقييم أدناه", - "advanced-workflow-action.rating.description-requiredDescription": "يرجى تحديد التقييم التفصيلي للمراجعة", - "advanced-workflow-action.select-reviewer.description-single": "يرجى اختيار مرشح واحد أدناه للمقدمة", - "advanced-workflow-action.select-reviewer.description-multiple": "يرجى اختيار مرشح واحد أو أكثر أدناه قبل التقديم", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.head": "يأتي إليكين", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.head": "إضافة المزيد من الإلكترونيات", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.button.see-all": "مراجعة الكل", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "الأعضاء الحالية", + + // "advanced-workflow-action.rating.form.review.error": "You must enter a review to submit this rating", + "advanced-workflow-action.rating.form.review.error": "يجب عليك إدخال مراجعة لتقديم هذا التقييم", + + // "advanced-workflow-action.rating.description": "Please select a rating below", + "advanced-workflow-action.rating.description": "يرجى تحديد التقييم أدناه", + + // "advanced-workflow-action.rating.description-requiredDescription": "Please select a rating below and also add a review", + "advanced-workflow-action.rating.description-requiredDescription": "يرجى تحديد التقييم أدناه وإضافة مراجعة", + + // "advanced-workflow-action.select-reviewer.description-single": "Please select a single reviewer below before submitting", + "advanced-workflow-action.select-reviewer.description-single": "يرجى اختيار مراجع واحد أدناه قبل التقديم", + + // "advanced-workflow-action.select-reviewer.description-multiple": "Please select one or more reviewers below before submitting", + "advanced-workflow-action.select-reviewer.description-multiple": "يرجى اختيار مراجع واحد أو أكثر أدناه قبل التقديم", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.head": "EPeople", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.head": "أشخاص إلكترونيين", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.head": "Add EPeople", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.head": "إضافة أشخاص إلكترونيين", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.button.see-all": "Browse All", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.button.see-all": "استعراض الكل", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Current Members", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "الأعضاء الحاليين", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "Search", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "بحث", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.id": "ID", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.id": "المعرّف", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.name": "Name", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.name": "الاسم", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.identity": "هوية", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.identity": "Identity", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.identity": "الهوية", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.email": "Email", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.email": "البريد الإلكتروني", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.netid": "NetID", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.netid": "NetID", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit": "Remove / Add", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit": "إزالة / إضافة", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit.buttons.remove": "إزالة عضو باسم \"{{name}}\"", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.success.addMember": "أكمل إضافة العضو: \"{{name}}\"بنجاح", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.addMember": "فشل في إضافة الموضوع: \"{{name}}\"", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.success.addMember": "تمت إضافة العضو: \"{{name}}\"بنجاح", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.addMember": "فشل إضافة العضو: \"{{name}}\"", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.success.deleteMember": "تم حذف العضو: \"{{name}}\"بنجاح", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.deleteMember": "فشل في حذف العضو: \"{{name}}\"", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.deleteMember": "فشل حذف العضو: \"{{name}}\"", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit.buttons.add": "إضافة عضو باسم \"{{name}}\"", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "لا توجد مجموعة حاليًا، سيتم تقديم الاسم الجديد.", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "لا توجد مجموعة نشطة حالياً، قم بتقديم الاسم أولاً.", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-members-yet": "No members in group yet, search and add.", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-members-yet": "لا يوجد أعضاء في المجموعة حتى الآن، قم بالبحث والإضافة.", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-items": "لم يتم العثور على أي شخص إلكترونين في هذا البحث", - "advanced-workflow-action.select-reviewer.no-reviewer-selected.error": "لم يتم تحديد أي زائر.", - "admin.batch-import.page.validateOnly.hint": "عند التحديد، سيتم التحقق من صحة الملف الموجود الذي تم تحميله. ", + + // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-items": "No EPeople found in that search", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-items": "لم يتم العثور على أي أشخاص إلكترونيين في هذا البحث", + + // "advanced-workflow-action.select-reviewer.no-reviewer-selected.error": "No reviewer selected.", + "advanced-workflow-action.select-reviewer.no-reviewer-selected.error": "لم يتم تحديد أي مراجع.", + + // "admin.batch-import.page.validateOnly.hint": "When selected, the uploaded ZIP will be validated. You will receive a report of detected changes, but no changes will be saved.", + "admin.batch-import.page.validateOnly.hint": "عند التحديد، سيتم التحقق من صحة الملف المضغوط الذي تم تحميله. ستتلقى تقريراً بالتغييرات التي تم اكتشافها، ولكن لن يتم حفظ أي تغييرات.", + + // "admin.batch-import.page.remove": "remove", "admin.batch-import.page.remove": "إزالة", - "auth.errors.invalid-user": "عنوان البريد الإلكتروني أو كلمة مرور غير صالحة.", - "auth.messages.expired": "لقد تعلمت. ", - "auth.messages.token-refresh-failed": "فشل تحديث الرمز المميز لجلستك. ", + + // "auth.errors.invalid-user": "Invalid email address or password.", + "auth.errors.invalid-user": "عنوان البريد الإلكتروني أو كلمة المرور غير صالحة.", + + // "auth.messages.expired": "Your session has expired. Please log in again.", + "auth.messages.expired": "لقد انتهت جلستك. يرجى تسجيل الدخول مرة أخرى.", + + // "auth.messages.token-refresh-failed": "Refreshing your session token failed. Please log in again.", + "auth.messages.token-refresh-failed": "فشل تحديث الرمز المميز لجلستك. يرجى تسجيل الدخول مرة أخرى.", + + // "bitstream.download.page": "Now downloading {{bitstream}}...", "bitstream.download.page": "جاري الآن تنزيل {{bitstream}}...", + + // "bitstream.download.page.back": "Back", "bitstream.download.page.back": "رجوع", - "bitstream.edit.authorizations.link": "تحرير سياسة تدفق البت", - "bitstream.edit.authorizations.title": "تحرير سياسة تدفق البت", + + // "bitstream.edit.authorizations.link": "Edit bitstream's Policies", + "bitstream.edit.authorizations.link": "تحرير سياسات تدفق البت", + + // "bitstream.edit.authorizations.title": "Edit bitstream's Policies", + "bitstream.edit.authorizations.title": "تحرير سياسات تدفق البت", + + // "bitstream.edit.return": "Back", "bitstream.edit.return": "رجوع", + + // "bitstream.edit.bitstream": "Bitstream: ", "bitstream.edit.bitstream": "تدفق البت: ", - "bitstream.edit.form.description.hint": "اختياريًا، قم بتقديم وصف مختصر للملف، على سبيل المثال \"المقال الرئيسي\"أو\"قراءات بيانات الخبرة\".", + + // "bitstream.edit.form.description.hint": "Optionally, provide a brief description of the file, for example \"Main article\" or \"Experiment data readings\".", + "bitstream.edit.form.description.hint": "اختيارياً، قم بتقديم وصف مختصر للملف، على سبيل المثال \"المقال الرئيسي\" أو \"قراءات بيانات التجربة\".", + + // "bitstream.edit.form.description.label": "Description", "bitstream.edit.form.description.label": "الوصف", - "bitstream.edit.form.embargo.hint": "أول يوم يسمح له بالوصول. لا يمكن تعديل هذا التاريخ في هذا النموذج. لتعيين تاريخ حظر تدفق بت، قم بالذهاب إلى كتلة المادة، كوك بالنقر على ...تصاريح، إنشاء أو تحرير أبو يقرأ الخاصة بتدفق البت، وتعيين تاريخ الميلاد حسب الطلب.", - "bitstream.edit.form.embargo.label": "الحظر حتى تاريخ المحدد", - "bitstream.edit.form.fileName.hint": "تغيير اسم الملف لتدفق البت. ", + + // "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", + "bitstream.edit.form.embargo.hint": "أول يوم يسمح منه الوصول. لا يمكن تعديل هذا التاريخ في هذا النموذج. لتعيين تاريخ حظر لتدفق بت، قم بالذهاب إلى تبويب حالة المادة، وقم بالنقر على تصاريح...، إنشاء أو تحرير سياسة READ الخاصة بتدفق البت، وتعيين تاريخ البدء حسب الرغبة.", + + // "bitstream.edit.form.embargo.label": "Embargo until specific date", + "bitstream.edit.form.embargo.label": "حظر حتى تاريخ محدد", + + // "bitstream.edit.form.fileName.hint": "Change the filename for the bitstream. Note that this will change the display bitstream URL, but old links will still resolve as long as the sequence ID does not change.", + "bitstream.edit.form.fileName.hint": "تغيير اسم الملف لتدفق البت. لاحظ أن هذا سيؤدي إلى تغيير عنوان URL لدفق البت المعروض، لكن الروابط القديمة ستظل تحل طالما لم يتغير معرف التسلسل.", + + // "bitstream.edit.form.fileName.label": "Filename", "bitstream.edit.form.fileName.label": "اسم الملف", - "bitstream.edit.form.newFormat.label": "وصفه محدده جديده", + + // "bitstream.edit.form.newFormat.label": "Describe new format", + "bitstream.edit.form.newFormat.label": "وصف التنسيق الجديد", + + // "bitstream.edit.form.newFormat.hint": "The application you used to create the file, and the version number (for example, \"ACMESoft SuperApp version 1.5\").", "bitstream.edit.form.newFormat.hint": "التطبيق الذي قمت باستخدامه لإنشاء الملف، ورقم الإصدار (على سبيل المثال: \"ACMESoft SuperApp الإصدار 1.5\").", - "bitstream.edit.form.primaryBitstream.label": "التدفق الرئيسي للبيت", - "bitstream.edit.form.selectedFormat.hint": "إذا لم يكن متاحًا في المستقبل، يجب أن يطلب \"التنسيق غير موجود في المستند\" مسبقًا مسموح لها \"وصف التنسيق الجديد\".", - "bitstream.edit.form.selectedFormat.label": "البحث عن أداة", - "bitstream.edit.form.selectedFormat.unknown": "في حالة عدم وجودها في القائمة", - "bitstream.edit.notifications.error.format.title": "لقد حدث خطأ أثناء حفظ تدفق البت", - "bitstream.edit.notifications.error.primaryBitstream.title": "حدث خطأ أثناء حفظ التدفق الأساسي", - "bitstream.edit.form.iiifLabel.label": "ملصق التسمية IIIF", - "bitstream.edit.form.iiifLabel.hint": "تسمية قماش لهذه الصورة. ", + + // "bitstream.edit.form.primaryBitstream.label": "Primary File", + "bitstream.edit.form.primaryBitstream.label": "تدفق البت الرئيسي", + + // "bitstream.edit.form.selectedFormat.hint": "If the format is not in the above list, select \"format not in list\" above and describe it under \"Describe new format\".", + "bitstream.edit.form.selectedFormat.hint": "إذا لم يكن التنسيق موجوداً في القائمة أعلاه، قم بتحديد \"التنسيق غير موجود في القائمة\" أعلاه وقم بوصفه أدنى \"وصف تنسيق جديد\".", + + // "bitstream.edit.form.selectedFormat.label": "Selected Format", + "bitstream.edit.form.selectedFormat.label": "التنسيق المحدد", + + // "bitstream.edit.form.selectedFormat.unknown": "Format not in list", + "bitstream.edit.form.selectedFormat.unknown": "التنسيق غير موجود في القائمة", + + // "bitstream.edit.notifications.error.format.title": "An error occurred saving the bitstream's format", + "bitstream.edit.notifications.error.format.title": "لقد حدث خطأ أثناء حفظ تنسيق تدفق البت", + + // "bitstream.edit.notifications.error.primaryBitstream.title": "An error occurred saving the primary bitstream", + "bitstream.edit.notifications.error.primaryBitstream.title": "حدث خطأ أثناء حفظ تدفق البت الرئيسي", + + // "bitstream.edit.form.iiifLabel.label": "IIIF Label", + "bitstream.edit.form.iiifLabel.label": "ملصق تسمية IIIF", + + // "bitstream.edit.form.iiifLabel.hint": "Canvas label for this image. If not provided default label will be used.", + "bitstream.edit.form.iiifLabel.hint": "تسمية Canvas لهذه الصورة. إذا لم يتم توفير التسمية الافتراضية سيتم استخدامها.", + + // "bitstream.edit.form.iiifToc.label": "IIIF Table of Contents", "bitstream.edit.form.iiifToc.label": "جدول محتويات IIIF", - "bitstream.edit.form.iiifToc.hint": "إن إضافة نص هنا تجعل هذا بداية لنطاق محتويات جديد.", - "bitstream.edit.form.iiifWidth.label": "عرض قماش IIIF", - "bitstream.edit.form.iiifWidth.hint": "يجب أن يتطابق عرض القماش مع عرض الصورة.", - "bitstream.edit.form.iiifHeight.label": "ارتفاع قماش IIIF", - "bitstream.edit.form.iiifHeight.hint": "يجب أن يتطابق ارتفاع القماش مع ارتفاع الصورة.", - "bitstream.edit.notifications.saved.content": "تم حفظ التغييرات التي أحبها على تدفق هذا.", + + // "bitstream.edit.form.iiifToc.hint": "Adding text here makes this the start of a new table of contents range.", + "bitstream.edit.form.iiifToc.hint": "إن إضافة نص هنا تجعل هذا بداية لنطاق جدول محتويات جديد.", + + // "bitstream.edit.form.iiifWidth.label": "IIIF Canvas Width", + "bitstream.edit.form.iiifWidth.label": "عرض IIIF Canvas", + + // "bitstream.edit.form.iiifWidth.hint": "The canvas width should usually match the image width.", + "bitstream.edit.form.iiifWidth.hint": "يجب أن يتطابق عرض Canvas عادةً مع عرض الصورة.", + + // "bitstream.edit.form.iiifHeight.label": "IIIF Canvas Height", + "bitstream.edit.form.iiifHeight.label": "ارتفاع Canvas IIIF", + + // "bitstream.edit.form.iiifHeight.hint": "The canvas height should usually match the image height.", + "bitstream.edit.form.iiifHeight.hint": "يجب أن يتطابق ارتفاع Canvas عادةً مع ارتفاع الصورة.", + + // "bitstream.edit.notifications.saved.content": "Your changes to this bitstream were saved.", + "bitstream.edit.notifications.saved.content": "تم حفظ التغييرات التي أجريتها على تدفق البت هذا.", + + // "bitstream.edit.notifications.saved.title": "Bitstream saved", "bitstream.edit.notifications.saved.title": "تم حفظ تدفق البت", + + // "bitstream.edit.title": "Edit bitstream", "bitstream.edit.title": "تحرير تدفق البت", - "bitstream-request-a-copy.alert.canDownload1": "لقد بالفعل حق الوصول إلى هذا الملف. ", + + // "bitstream-request-a-copy.alert.canDownload1": "You already have access to this file. If you want to download the file, click ", + "bitstream-request-a-copy.alert.canDownload1": "لديك بالفعل حق الوصول إلى هذا الملف. إذا كنت تريد تنزيل الملف، انقر ", + + // "bitstream-request-a-copy.alert.canDownload2": "here", "bitstream-request-a-copy.alert.canDownload2": "هنا", - "bitstream-request-a-copy.header": "نسخة الطلب من الملف", - "bitstream-request-a-copy.intro": "يرجى إعادة المعلومات التالية لطلب النسخة التالية: ", - "bitstream-request-a-copy.intro.bitstream.one": "جاري الطلب الملف التالي: ", + + // "bitstream-request-a-copy.header": "Request a copy of the file", + "bitstream-request-a-copy.header": "طلب نسخة من الملف", + + // "bitstream-request-a-copy.intro": "Enter the following information to request a copy for the following item: ", + "bitstream-request-a-copy.intro": "قم بإدخال المعلومات التالية لطلب نسخة للمادة التالية: ", + + // "bitstream-request-a-copy.intro.bitstream.one": "Requesting the following file: ", + "bitstream-request-a-copy.intro.bitstream.one": "جاري طلب الملف التالي: ", + + // "bitstream-request-a-copy.intro.bitstream.all": "Requesting all files. ", "bitstream-request-a-copy.intro.bitstream.all": "طلب كل الملفات. ", + + // "bitstream-request-a-copy.name.label": "Name *", "bitstream-request-a-copy.name.label": "الاسم *", + + // "bitstream-request-a-copy.name.error": "The name is required", "bitstream-request-a-copy.name.error": "الاسم مطلوب", - "bitstream-request-a-copy.email.label": "عنوان بريدك الإلكتروني *", - "bitstream-request-a-copy.email.hint": "يتم استخدام عنوان البريد الإلكتروني هذا الملف.", - "bitstream-request-a-copy.email.error": "يرجى الاتصال بعنوان بريد إلكتروني صالح.", + + // "bitstream-request-a-copy.email.label": "Your email address *", + "bitstream-request-a-copy.email.label": "عنوان بريدك الإلكتروني *", + + // "bitstream-request-a-copy.email.hint": "This email address is used for sending the file.", + "bitstream-request-a-copy.email.hint": "يتم استخدام عنوان هذا البريد الإلكتروني لإرسال الملف.", + + // "bitstream-request-a-copy.email.error": "Please enter a valid email address.", + "bitstream-request-a-copy.email.error": "يرجى إدخال عنوان بريد إلكتروني صالح.", + + // "bitstream-request-a-copy.allfiles.label": "Files", "bitstream-request-a-copy.allfiles.label": "ملفات", + + // "bitstream-request-a-copy.files-all-false.label": "Only the requested file", "bitstream-request-a-copy.files-all-false.label": "الملف المطلوب فقط", - "bitstream-request-a-copy.files-all-true.label": "كل الملفات (لهذه المادة) في الوصول المحدود", + + // "bitstream-request-a-copy.files-all-true.label": "All files (of this item) in restricted access", + "bitstream-request-a-copy.files-all-true.label": "كل الملفات (لهذه المادة) في الوصول المقيد", + + // "bitstream-request-a-copy.message.label": "Message", "bitstream-request-a-copy.message.label": "رسالة", + + // "bitstream-request-a-copy.return": "Back", "bitstream-request-a-copy.return": "رجوع", - "bitstream-request-a-copy.submit": "نسخة الطلب", - "bitstream-request-a-copy.submit.success": "تم تقديم طلب فعال.", + + // "bitstream-request-a-copy.submit": "Request copy", + "bitstream-request-a-copy.submit": "طلب نسخة", + + // "bitstream-request-a-copy.submit.success": "The item request was submitted successfully.", + "bitstream-request-a-copy.submit.success": "تم تقديم طلب المادة بنجاح.", + + // "bitstream-request-a-copy.submit.error": "Something went wrong with submitting the item request.", "bitstream-request-a-copy.submit.error": "حدث خطأ ما أثناء تقديم طلب المادة.", - "browse.back.all-results": "جميع النتائج حدثت", + + // "browse.back.all-results": "All browse results", + "browse.back.all-results": "جميع نتائج الاستعراض", + + // "browse.comcol.by.author": "By Author", "browse.comcol.by.author": "حسب المؤلف", + + // "browse.comcol.by.dateissued": "By Issue Date", "browse.comcol.by.dateissued": "حسب تاريخ الإصدار", + + // "browse.comcol.by.subject": "By Subject", "browse.comcol.by.subject": "حسب الموضوع", + + // "browse.comcol.by.srsc": "By Subject Category", "browse.comcol.by.srsc": "حسب فئة الموضوع", - "browse.comcol.by.nsi": "حسب فرس العلوم النرويجي", - "browse.comcol.by.title": "عنوان حسب الطلب", + + // "browse.comcol.by.nsi": "By Norwegian Science Index", + "browse.comcol.by.nsi": "حسب فهرس العلوم النرويجي", + + // "browse.comcol.by.title": "By Title", + "browse.comcol.by.title": "حسب العنوان", + + // "browse.comcol.head": "Browse", "browse.comcol.head": "استعراض", - "browse.empty": "لا يوجد شيء للعرض.", + + // "browse.empty": "No items to show.", + "browse.empty": "لا توجد مواد للعرض.", + + // "browse.metadata.author": "Author", "browse.metadata.author": "المؤلف", + + // "browse.metadata.dateissued": "Issue Date", "browse.metadata.dateissued": "تاريخ الإصدار", + + // "browse.metadata.subject": "Subject", "browse.metadata.subject": "الموضوع", - "browse.metadata.title": "عنوان العنوان", + + // "browse.metadata.title": "Title", + "browse.metadata.title": "العنوان", + + // "browse.metadata.srsc": "Subject Category", "browse.metadata.srsc": "فئة الموضوع", - "browse.metadata.author.breadcrumbs": "مراجعة حسب المؤلف", - "browse.metadata.dateissued.breadcrumbs": "تاريخ المراجعة حسب التاريخ", - "browse.metadata.subject.breadcrumbs": "مراجعة حسب الموضوع", - "browse.metadata.srsc.breadcrumbs": "مراجعة حسب فئة الموضوع", - "browse.metadata.nsi.breadcrumbs": "مراجعة حسب هرس العلوم النرويجي", - "browse.metadata.title.breadcrumbs": "قم باستعراض العنوان حسب الطلب", + + // "browse.metadata.author.breadcrumbs": "Browse by Author", + "browse.metadata.author.breadcrumbs": "استعراض حسب المؤلف", + + // "browse.metadata.dateissued.breadcrumbs": "Browse by Date", + "browse.metadata.dateissued.breadcrumbs": "استعراض حسب التاريخ", + + // "browse.metadata.subject.breadcrumbs": "Browse by Subject", + "browse.metadata.subject.breadcrumbs": "استعراض حسب الموضوع", + + // "browse.metadata.srsc.breadcrumbs": "Browse by Subject Category", + "browse.metadata.srsc.breadcrumbs": "استعراض حسب فئة الموضوع", + + // "browse.metadata.nsi.breadcrumbs": "Browse by Norwegian Science Index", + "browse.metadata.nsi.breadcrumbs": "استعراض حسب فهرس العلوم النرويجي", + + // "browse.metadata.title.breadcrumbs": "Browse by Title", + "browse.metadata.title.breadcrumbs": "استعراض حسب العنوان", + + // "pagination.next.button": "Next", "pagination.next.button": "التالي", - "pagination.previous.button": "السابقة", - "pagination.next.button.disabled.tooltip": "لا تقرأ من الصفحات من النتائج", - "browse.startsWith": "، يبدأ بـ {{ startsWith }}", + + // "pagination.previous.button": "Previous", + "pagination.previous.button": "السابق", + + // "pagination.next.button.disabled.tooltip": "No more pages of results", + "pagination.next.button.disabled.tooltip": "لا مزيد من الصفحات من النتائج", + + // "browse.startsWith": ", starting with {{ startsWith }}", + "browse.startsWith": ", يبدأ بـ {{ startsWith }}", + + // "browse.startsWith.choose_start": "(Choose start)", "browse.startsWith.choose_start": "(اختر الشهر)", + + // "browse.startsWith.choose_year": "(Choose year)", "browse.startsWith.choose_year": "(اختر السنة)", + + // "browse.startsWith.choose_year.label": "Choose the issue year", "browse.startsWith.choose_year.label": "اختر سنة الإصدار", - "browse.startsWith.jump": "تهذيب النتيجة حسب السنة أو الشهر", + + // "browse.startsWith.jump": "Filter results by year or month", + "browse.startsWith.jump": "تنقيح النتائج حسب السنة أو الشهر", + + // "browse.startsWith.months.april": "April", "browse.startsWith.months.april": "أبريل", + + // "browse.startsWith.months.august": "August", "browse.startsWith.months.august": "أغسطس", + + // "browse.startsWith.months.december": "December", "browse.startsWith.months.december": "ديسمبر", + + // "browse.startsWith.months.february": "February", "browse.startsWith.months.february": "فبراير", + + // "browse.startsWith.months.january": "January", "browse.startsWith.months.january": "يناير", + + // "browse.startsWith.months.july": "July", "browse.startsWith.months.july": "يوليو", + + // "browse.startsWith.months.june": "June", "browse.startsWith.months.june": "يونيو", + + // "browse.startsWith.months.march": "March", "browse.startsWith.months.march": "مارس", + + // "browse.startsWith.months.may": "May", "browse.startsWith.months.may": "مايو", + + // "browse.startsWith.months.none": "(Choose month)", "browse.startsWith.months.none": "(اختر الشهر)", - "browse.startsWith.months.none.label": "تاريخ إنشاء الإصدار", + + // "browse.startsWith.months.none.label": "Choose the issue month", + "browse.startsWith.months.none.label": "اختر تاريخ الإصدار", + + // "browse.startsWith.months.november": "November", "browse.startsWith.months.november": "نوفمبر", + + // "browse.startsWith.months.october": "October", "browse.startsWith.months.october": "أكتوبر", + + // "browse.startsWith.months.september": "September", "browse.startsWith.months.september": "سبتمبر", + + // "browse.startsWith.submit": "Browse", "browse.startsWith.submit": "استعراض", - "browse.startsWith.type_date": "تأهيل النتائج حسب التاريخ", - "browse.startsWith.type_date.label": "أو قم بكتابة تاريخ (السنة - الشهر) والنقر على زر المراجعة.", - "browse.startsWith.type_text": "تسهيل البحث عن طريق كتابة الرواية الأولى", + + // "browse.startsWith.type_date": "Filter results by date", + "browse.startsWith.type_date": "تنقيح النتائج حسب التاريخ", + + // "browse.startsWith.type_date.label": "Or type in a date (year-month) and click on the Browse button", + "browse.startsWith.type_date.label": "أو قم بكتابة تاريخ (السنة - الشهر) والنقر على زر استعراض.", + + // "browse.startsWith.type_text": "Filter results by typing the first few letters", + "browse.startsWith.type_text": "تنقيح النتائج عن طريق كتابة الأحرف الأولى", + + // "browse.startsWith.input": "Filter", "browse.startsWith.input": "منقح", + + // "browse.taxonomy.button": "Browse", "browse.taxonomy.button": "استعراض", - "browse.title": "مراجعة حسب الطلب {{ field }}{{ startsWith }} {{ value }}", - "browse.title.page": "مراجعة حسب الطلب {{ field }} {{ value }}", + + // "browse.title": "Browsing by {{ field }}{{ startsWith }} {{ value }}", + "browse.title": "استعراض حسب {{ field }}{{ startsWith }} {{ value }}", + + // "browse.title.page": "Browsing by {{ field }} {{ value }}", + "browse.title.page": "استعراض حسب {{ field }} {{ value }}", + + // "search.browse.item-back": "Back to Results", "search.browse.item-back": "العودة إلى النتائج", - "chips.remove": "إزالة الجانب", + + // "chips.remove": "Remove chip", + "chips.remove": "إزالة الشريحة", + + // "claimed-approved-search-result-list-element.title": "Approved", "claimed-approved-search-result-list-element.title": "مقبول", - "claimed-declined-search-result-list-element.title": "تم الرفض وتمت إعادة إنتاجه إلى مقدم الطلب", - "claimed-declined-task-search-result-list-element.title": "تم الرفض، وتمت إعادة العمل إلى سير عمل مدير المراجعة", - "collection.browse.logo": "تمت القراءة للحصول على شعار للصورة", + + // "claimed-declined-search-result-list-element.title": "Rejected, sent back to submitter", + "claimed-declined-search-result-list-element.title": "تم الرفض، وتمت الإعادة إلى مقدم الطلب", + + // "claimed-declined-task-search-result-list-element.title": "Declined, sent back to Review Manager's workflow", + "claimed-declined-task-search-result-list-element.title": "تم الرفض، وتمت الإعادة إلى سير عمل مدير المراجعة", + + // "collection.browse.logo": "Browse for a collection logo", + "collection.browse.logo": "استعراض للحصول على شعار للحاوية", + + // "collection.create.head": "Create a Collection", "collection.create.head": "إنشاء حاوية", - "collection.create.notifications.success": "تم إنشاء فعال", - "collection.create.sub-head": "إنشاء خانة تمكين {{ parent }}", + + // "collection.create.notifications.success": "Successfully created the Collection", + "collection.create.notifications.success": "تم إنشاء الحاوية بنجاح", + + // "collection.create.sub-head": "Create a Collection for Community {{ parent }}", + "collection.create.sub-head": "إنشاء حاوية للمجتمع {{ parent }}", + + // "collection.curate.header": "Curate Collection: {{collection}}", "collection.curate.header": "أكرتة الحاوية: {{collection}}", + + // "collection.delete.cancel": "Cancel", "collection.delete.cancel": "إلغاء", - "collection.delete.confirm": "بالتأكيد", - "collection.delete.processing": "غاري الحذف", - "collection.delete.head": "تأكد من الحذف", - "collection.delete.notification.fail": "عذرا حف", - "collection.delete.notification.success": "تم الحذف الفعال", - "collection.delete.text": "هل أنت متأكد من أنك تريد حذف الهاتف \"{{ dso }}\"", - "collection.edit.delete": "حذف هذه الصورة", - "collection.edit.head": "تحرير", - "collection.edit.breadcrumbs": "تحرير", + + // "collection.delete.confirm": "Confirm", + "collection.delete.confirm": "تأكيد", + + // "collection.delete.processing": "Deleting", + "collection.delete.processing": "جاري الحذف", + + // "collection.delete.head": "Delete Collection", + "collection.delete.head": "حذف الحاوية", + + // "collection.delete.notification.fail": "Collection could not be deleted", + "collection.delete.notification.fail": "تعذر حف الحاوية", + + // "collection.delete.notification.success": "Successfully deleted collection", + "collection.delete.notification.success": "تم حذف الحاوية بنجاح", + + // "collection.delete.text": "Are you sure you want to delete collection \"{{ dso }}\"", + "collection.delete.text": "هل أنت متأكد من أنك تريد حذف الحاوية \"{{ dso }}\"", + + // "collection.edit.delete": "Delete this collection", + "collection.edit.delete": "حذف هذه الحاوية", + + // "collection.edit.head": "Edit Collection", + "collection.edit.head": "تحرير الحاوية", + + // "collection.edit.breadcrumbs": "Edit Collection", + "collection.edit.breadcrumbs": "تحرير الحاوية", + + // "collection.edit.tabs.mapper.head": "Item Mapper", "collection.edit.tabs.mapper.head": "مخطط المادة", - "collection.edit.tabs.item-mapper.title": "فتح المادة", + + // "collection.edit.tabs.item-mapper.title": "Collection Edit - Item Mapper", + "collection.edit.tabs.item-mapper.title": "تحرير الحاوية - مخطط المادة", + + // "collection.edit.item-mapper.cancel": "Cancel", "collection.edit.item-mapper.cancel": "إلغاء", - "collection.edit.item-mapper.collection": "التام: \"{{name}}\"", + + // "collection.edit.item-mapper.collection": "Collection: \"{{name}}\"", + "collection.edit.item-mapper.collection": "الحاوية: \"{{name}}\"", + + // "collection.edit.item-mapper.confirm": "Map selected items", "collection.edit.item-mapper.confirm": "تخطيط المواد المحددة", - "collection.edit.item-mapper.description": "هذه هي أداة المادة والتي بدأت لمديري في تخطيط المنتجات من كعكة صغيرة أخرى إلى هذه الثلاجة. ", - "collection.edit.item-mapper.head": "الخامة الأخرى - تخطيط مواد من توفيق", - "collection.edit.item-mapper.no-search": "يرجى الاتصال باستعلام للبحث", - "collection.edit.item-mapper.notifications.map.error.content": "حدثت أثناء التخطيط {{amount}} مادة.", + + // "collection.edit.item-mapper.description": "This is the item mapper tool that allows collection administrators to map items from other collections into this collection. You can search for items from other collections and map them, or browse the list of currently mapped items.", + "collection.edit.item-mapper.description": "هذه هي أداة مخطط المادة والتي تتيح لمديري الحاوية بتخطيط مواد من حاويات أخرى إلى هذه الحاوية. يمكنك البحث عن مواد من حاويات أخرى وتخطيطها، أو استعراض قائمة بالمواد المخططة حاليًا.", + + // "collection.edit.item-mapper.head": "Item Mapper - Map Items from Other Collections", + "collection.edit.item-mapper.head": "مخطط المادة - تخطيط مواد من حاويات أخرى", + + // "collection.edit.item-mapper.no-search": "Please enter a query to search", + "collection.edit.item-mapper.no-search": "يرجى إدخال استعلام للبحث", + + // "collection.edit.item-mapper.notifications.map.error.content": "Errors occurred for mapping of {{amount}} items.", + "collection.edit.item-mapper.notifications.map.error.content": "حدثت أخطاء أثناء تخطيط {{amount}} مادة.", + + // "collection.edit.item-mapper.notifications.map.error.head": "Mapping errors", "collection.edit.item-mapper.notifications.map.error.head": "أخطاء التخطيط", - "collection.edit.item-mapper.notifications.map.success.content": "تم التخطيط {{amount}} مادة فعالة.", + + // "collection.edit.item-mapper.notifications.map.success.content": "Successfully mapped {{amount}} items.", + "collection.edit.item-mapper.notifications.map.success.content": "تم تخطيط {{amount}} مادة بنجاح.", + + // "collection.edit.item-mapper.notifications.map.success.head": "Mapping completed", "collection.edit.item-mapper.notifications.map.success.head": "اكتمل التخطيط", - "collection.edit.item-mapper.notifications.unmap.error.content": "حدث خطأ أثناء إزالة التخطيطات {{amount}} مادة.", + + // "collection.edit.item-mapper.notifications.unmap.error.content": "Errors occurred for removing the mappings of {{amount}} items.", + "collection.edit.item-mapper.notifications.unmap.error.content": "حدثت أخطأ أثناء إزالة تخطيطات {{amount}} مادة.", + + // "collection.edit.item-mapper.notifications.unmap.error.head": "Remove mapping errors", "collection.edit.item-mapper.notifications.unmap.error.head": "أخطاء إزالة التخطيط", - "collection.edit.item-mapper.notifications.unmap.success.content": "بعد إزالة {{amount}} تخطيط فعّال.", + + // "collection.edit.item-mapper.notifications.unmap.success.content": "Successfully removed the mappings of {{amount}} items.", + "collection.edit.item-mapper.notifications.unmap.success.content": "تمت إزالة {{amount}} تخطيط مادة بنجاح.", + + // "collection.edit.item-mapper.notifications.unmap.success.head": "Remove mapping completed", "collection.edit.item-mapper.notifications.unmap.success.head": "اكتملت إزالة التخطيط", - "collection.edit.item-mapper.remove": "إزالة التخطيطات المحددة", - "collection.edit.item-mapper.search-form.placeholder": "المواد المدروسة...", - "collection.edit.item-mapper.tabs.browse": "فحص المواد الجيدة", + + // "collection.edit.item-mapper.remove": "Remove selected item mappings", + "collection.edit.item-mapper.remove": "إزالة تخطيطات المادة المحددة", + + // "collection.edit.item-mapper.search-form.placeholder": "Search items...", + "collection.edit.item-mapper.search-form.placeholder": "بحث المواد...", + + // "collection.edit.item-mapper.tabs.browse": "Browse mapped items", + "collection.edit.item-mapper.tabs.browse": "استعراض المواد المخططة", + + // "collection.edit.item-mapper.tabs.map": "Map new items", "collection.edit.item-mapper.tabs.map": "تخطيط مواد جديدة", + + // "collection.edit.logo.delete.title": "Delete logo", "collection.edit.logo.delete.title": "حذف الشعار", - "collection.edit.logo.delete-undo.title": "السماء عن الحذف", - "collection.edit.logo.label": "شعار تجاري", - "collection.edit.logo.notifications.add.error": "فشل تحميل شعار التعليمات. ", - "collection.edit.logo.notifications.add.success": "تم تحميل فيتامين فعال.", + + // "collection.edit.logo.delete-undo.title": "Undo delete", + "collection.edit.logo.delete-undo.title": "التراجع عن الحذف", + + // "collection.edit.logo.label": "Collection logo", + "collection.edit.logo.label": "شعار الحاوية", + + // "collection.edit.logo.notifications.add.error": "Uploading Collection logo failed. Please verify the content before retrying.", + "collection.edit.logo.notifications.add.error": "فشل تحميل شعار الحاوية. يرجى التحقق من المحتوى قبل إعادة المحاولة.", + + // "collection.edit.logo.notifications.add.success": "Upload Collection logo successful.", + "collection.edit.logo.notifications.add.success": "تم تحميل شعار الحاوية بنجاح.", + + // "collection.edit.logo.notifications.delete.success.title": "Logo deleted", "collection.edit.logo.notifications.delete.success.title": "تم حذف الشعار", - "collection.edit.logo.notifications.delete.success.content": "تم حذف الشعار الفعال", + + // "collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo", + "collection.edit.logo.notifications.delete.success.content": "تم حذف شعار الحاوية بنجاح", + + // "collection.edit.logo.notifications.delete.error.title": "Error deleting logo", "collection.edit.logo.notifications.delete.error.title": "حدث خطأ أثناء حذف الشعار", - "collection.edit.logo.upload": "قم بإسقاط شعار العلامة للتحميل", - "collection.edit.notifications.success": "تم تحرير فعال", + + // "collection.edit.logo.upload": "Drop a Collection Logo to upload", + "collection.edit.logo.upload": "قم بإسقاط شعار الحاوية للتحميل", + + // "collection.edit.notifications.success": "Successfully edited the Collection", + "collection.edit.notifications.success": "تم تحرير الحاوية بنجاح", + + // "collection.edit.return": "Back", "collection.edit.return": "رجوع", + + // "collection.edit.tabs.access-control.head": "Access Control", "collection.edit.tabs.access-control.head": "التحكم في الوصول", - "collection.edit.tabs.access-control.title": "تحرير البدء - التحكم في الوصول", + + // "collection.edit.tabs.access-control.title": "Collection Edit - Access Control", + "collection.edit.tabs.access-control.title": "تحرير الحاوية - التحكم في الوصول", + + // "collection.edit.tabs.curate.head": "Curate", "collection.edit.tabs.curate.head": "أكرتة", - "collection.edit.tabs.curate.title": "تحرير تحرير - كرتة", - "collection.edit.tabs.authorizations.head": ".تصاريح", - "collection.edit.tabs.authorizations.title": "تحرير - تصاريح", + + // "collection.edit.tabs.curate.title": "Collection Edit - Curate", + "collection.edit.tabs.curate.title": "تحرير الحاوية - أكرتة", + + // "collection.edit.tabs.authorizations.head": "Authorizations", + "collection.edit.tabs.authorizations.head": "تصاريح", + + // "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", + "collection.edit.tabs.authorizations.title": "تحرير الحاوية - تصاريح", + + // "collection.edit.item.authorizations.load-bundle-button": "Load more bundles", "collection.edit.item.authorizations.load-bundle-button": "تحميل المزيد من الحزم", + + // "collection.edit.item.authorizations.load-more-button": "Load more", "collection.edit.item.authorizations.load-more-button": "تحميل المزيد", - "collection.edit.item.authorizations.show-bitstreams-button": "عرض سياسات التدفق الكامل", + + // "collection.edit.item.authorizations.show-bitstreams-button": "Show bitstream policies for bundle", + "collection.edit.item.authorizations.show-bitstreams-button": "عرض سياسات تدفق البت للحزمة", + + // "collection.edit.tabs.metadata.head": "Edit Metadata", "collection.edit.tabs.metadata.head": "تحرير الميتاداتا", - "collection.edit.tabs.metadata.title": "تحرير تحرير - الميتاداتا", - "collection.edit.tabs.roles.head": "تم تعيينه", - "collection.edit.tabs.roles.title": "تحرير - التعديل", - "collection.edit.tabs.source.external": "لتتمكن من هذه بحصاد محتوياتها من مصدر خارجي", - "collection.edit.tabs.source.form.errors.oaiSource.required": "يجب عليك تقديم معرف حزمة التفاصيل الخاصة.", - "collection.edit.tabs.source.form.harvestType": "استمرار المحتوى", - "collection.edit.tabs.source.form.head": "قوة مصدر خارجي", - "collection.edit.tabs.source.form.metadataConfigId": "تنسيق الميثاداتا", + + // "collection.edit.tabs.metadata.title": "Collection Edit - Metadata", + "collection.edit.tabs.metadata.title": "تحرير الحاوية - الميتاداتا", + + // "collection.edit.tabs.roles.head": "Assign Roles", + "collection.edit.tabs.roles.head": "تعيين الأدوار", + + // "collection.edit.tabs.roles.title": "Collection Edit - Roles", + "collection.edit.tabs.roles.title": "تحرير الحاوية - الأدوار", + + // "collection.edit.tabs.source.external": "This collection harvests its content from an external source", + "collection.edit.tabs.source.external": "تقوم هذه الحاوية بحصاد محتواها من مصدر خارجي", + + // "collection.edit.tabs.source.form.errors.oaiSource.required": "You must provide a set id of the target collection.", + "collection.edit.tabs.source.form.errors.oaiSource.required": "يجب عليك تقديم معرف حزمة للحاوية المستهدفة.", + + // "collection.edit.tabs.source.form.harvestType": "Content being harvested", + "collection.edit.tabs.source.form.harvestType": "المحتوى الجاري حصاده", + + // "collection.edit.tabs.source.form.head": "Configure an external source", + "collection.edit.tabs.source.form.head": "تهيئة مصدر خارجي", + + // "collection.edit.tabs.source.form.metadataConfigId": "Metadata Format", + "collection.edit.tabs.source.form.metadataConfigId": "تنسيق الميتاداتا", + + // "collection.edit.tabs.source.form.oaiSetId": "OAI specific set id", "collection.edit.tabs.source.form.oaiSetId": "معرف حزمة محددة لمبادرة الأرشيفات المفتوحة", - "collection.edit.tabs.source.form.oaiSource": "مقدمة لخدمة المعلومات الأرشيفات المفتوحة", - "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "ميتاداتا وتدفقات البت (يتطلب دعم ORE)", - "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "غاب الميتاداتا والمراجع إلى تدفقات البت (يطلب دعم ORE)", - "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "موت الميتاتا فقط", + + // "collection.edit.tabs.source.form.oaiSource": "OAI Provider", + "collection.edit.tabs.source.form.oaiSource": "مقدم خدمة مبادرة الأرشيفات المفتوحة", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "Harvest metadata and bitstreams (requires ORE support)", + "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "حصاد الميتاداتا وتدفقات البت (يتطلب دعم ORE)", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "Harvest metadata and references to bitstreams (requires ORE support)", + "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "حصاد الميتاداتا والمراجع إلى تدفقات البت (يتطلب دعم ORE)", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "Harvest metadata only", + "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "حصاد الميتاداتا فقط", + + // "collection.edit.tabs.source.head": "Content Source", "collection.edit.tabs.source.head": "مصدر المحتوى", - "collection.edit.tabs.source.notifications.discarded.content": "تم تجاهل تجاهلك. ", + + // "collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "collection.edit.tabs.source.notifications.discarded.content": "تم تجاهل تغييراتك. لإعادة تعيين تغييراتك قم النقر على زر 'تراجع'", + + // "collection.edit.tabs.source.notifications.discarded.title": "Changes discarded", "collection.edit.tabs.source.notifications.discarded.title": "تم تجاهل التغييرات", - "collection.edit.tabs.source.notifications.invalid.content": "لم يتم الحفاظ على جديدك. ", - "collection.edit.tabs.source.notifications.invalid.title": "دياداتا غير صالحة", - "collection.edit.tabs.source.notifications.saved.content": "تم حفظ تفاصيلك على مصدر محتوى هذه الرسالة.", + + // "collection.edit.tabs.source.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + "collection.edit.tabs.source.notifications.invalid.content": "لم يتم حفظ تغييراتك. يرجى التأكد من صحة كل الحقول قبل الحفظ.", + + // "collection.edit.tabs.source.notifications.invalid.title": "Metadata invalid", + "collection.edit.tabs.source.notifications.invalid.title": "الميتاداتا غير صالحة", + + // "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", + "collection.edit.tabs.source.notifications.saved.content": "تم حفظ تغييراتك على مصدر محتوى هذه الحاوية.", + + // "collection.edit.tabs.source.notifications.saved.title": "Content Source saved", "collection.edit.tabs.source.notifications.saved.title": "تم حفظ مصدر المحتوى", - "collection.edit.tabs.source.title": "تحرير - مصدر المحتوى", + + // "collection.edit.tabs.source.title": "Collection Edit - Content Source", + "collection.edit.tabs.source.title": "تحرير الحاوية - مصدر المحتوى", + + // "collection.edit.template.add-button": "Add", "collection.edit.template.add-button": "إضافة", + + // "collection.edit.template.breadcrumbs": "Item template", "collection.edit.template.breadcrumbs": "قالب المادة", + + // "collection.edit.template.cancel": "Cancel", "collection.edit.template.cancel": "إلغاء", + + // "collection.edit.template.delete-button": "Delete", "collection.edit.template.delete-button": "حذف", + + // "collection.edit.template.edit-button": "Edit", "collection.edit.template.edit-button": "تحرير", - "collection.edit.template.error": "حدث خطأ أثناء حذف التصميم الإلكتروني", - "collection.edit.template.head": "تحرير قالب القالب للعباوية \"{{ collection }}\"", - "collection.edit.template.label": "قالب", - "collection.edit.template.loading": "جاري تحميل التصميم المعماري...", - "collection.edit.template.notifications.delete.error": "فشل في حذف قالب المادة", - "collection.edit.template.notifications.delete.success": "تم حذف القالب الفعال", - "collection.edit.template.title": "تحرير النموذج على موقع الكتروني", - "collection.form.abstract": "وصف قصير", - "collection.form.description": "نص استعدادي (HTML)", - "collection.form.errors.title.required": "يرجى الإدخال اسم العلبة", - "collection.form.license": "com", + + // "collection.edit.template.error": "An error occurred retrieving the template item", + "collection.edit.template.error": "حدث خطأ أثناء استرداد عنصر القالب", + + // "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", + "collection.edit.template.head": "تحرير عنصر القالب للحاوية \"{{ collection }}\"", + + // "collection.edit.template.label": "Template item", + "collection.edit.template.label": "عنصر القالب", + + // "collection.edit.template.loading": "Loading template item...", + "collection.edit.template.loading": "جاري تحميل عنصر القالب...", + + // "collection.edit.template.notifications.delete.error": "Failed to delete the item template", + "collection.edit.template.notifications.delete.error": "فشل حذف قالب المادة", + + // "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", + "collection.edit.template.notifications.delete.success": "تم حذف قالب المادة بنجاح", + + // "collection.edit.template.title": "Edit Template Item", + "collection.edit.template.title": "تحرير عنصر القالب", + + // "collection.form.abstract": "Short Description", + "collection.form.abstract": "وصف مختصر", + + // "collection.form.description": "Introductory text (HTML)", + "collection.form.description": "نص تمهيدي (HTML)", + + // "collection.form.errors.title.required": "Please enter a collection name", + "collection.form.errors.title.required": "يرجى إدخال اسم الحاوية", + + // "collection.form.license": "License", + "collection.form.license": "الترخيص", + + // "collection.form.provenance": "Provenance", "collection.form.provenance": "المنشأ", + + // "collection.form.rights": "Copyright text (HTML)", "collection.form.rights": "نص حقوق النشر (HTML)", + + // "collection.form.tableofcontents": "News (HTML)", "collection.form.tableofcontents": "الأخبار (HTML)", + + // "collection.form.title": "Name", "collection.form.title": "الاسم", + + // "collection.form.entityType": "Entity Type", "collection.form.entityType": "نوع الكينونة", - "collection.listelement.badge": "ابدأ", - "collection.logo": "شعار تجاري", - "collection.page.browse.search.head": "يبحث", - "collection.page.edit": "تحرير هذه الجزئية", - "collection.page.handle": "URI الجديد لهذه الكائنات", - "collection.page.license": "com", + + // "collection.listelement.badge": "Collection", + "collection.listelement.badge": "الحاوية", + + // "collection.logo": "Collection logo", + "collection.logo": "شعار الحاوية", + + // "collection.page.browse.search.head": "Search", + // TODO New key - Add a translation + "collection.page.browse.search.head": "Search", + + // "collection.page.edit": "Edit this collection", + "collection.page.edit": "تحرير هذه الحاوية", + + // "collection.page.handle": "Permanent URI for this collection", + "collection.page.handle": "URI الدائم لهذه الحاوية", + + // "collection.page.license": "License", + "collection.page.license": "الترخيص", + + // "collection.page.news": "News", "collection.page.news": "الأخبار", - "collection.search.results.head": "نتائج البحث", - "collection.select.confirm": "بالتأكيد", - "collection.select.empty": "لا يوجد شيء للعرض", - "collection.select.table.selected": "محدد المعالم", - "collection.select.table.select": "تحديد الحاوية", - "collection.select.table.deselect": "إلغاء تحديد الحاوية", - "collection.select.table.title": "عنوان العنوان", - "collection.source.controls.head": "إعدادات التحكم في", - "collection.source.controls.test.submit.error": "حدث خطأ ما أثناء بدء الاختبار", - "collection.source.controls.test.failed": "فشل العناصر المكونة لها", - "collection.source.controls.test.completed": "كلمات بمعنى: أدى إلى النهاية", - "collection.source.controls.test.submit": "تم اختبار التهيئة", + + // "collection.search.results.head": "Search Results", + // TODO New key - Add a translation + "collection.search.results.head": "Search Results", + + // "collection.select.confirm": "Confirm selected", + "collection.select.confirm": "تأكيد المحدد", + + // "collection.select.empty": "No collections to show", + "collection.select.empty": "لا توجد حاويات للعرض", + + // "collection.select.table.selected": "Selected collections", + "collection.select.table.selected": "الحاويات المحددة", + + // "collection.select.table.select": "Select collection", + "collection.select.table.select": "تحديد حاوية", + + // "collection.select.table.deselect": "Deselect collection", + "collection.select.table.deselect": "إلغاء تحديد حاوية", + + // "collection.select.table.title": "Title", + "collection.select.table.title": "العنوان", + + // "collection.source.controls.head": "Harvest Controls", + "collection.source.controls.head": "إعدادات التحكم في الحصاد", + + // "collection.source.controls.test.submit.error": "Something went wrong with initiating the testing of the settings", + "collection.source.controls.test.submit.error": "حدث خطأ ما أثناء بدء اختبار الإعدادات", + + // "collection.source.controls.test.failed": "The script to test the settings has failed", + "collection.source.controls.test.failed": "فشل البرنامج النصي لاختبار الإعدادات", + + // "collection.source.controls.test.completed": "The script to test the settings has successfully finished", + "collection.source.controls.test.completed": "انتهى البرنامج النصي لاختبار الإعدادات بنجاح", + + // "collection.source.controls.test.submit": "Test configuration", + "collection.source.controls.test.submit": "اختبار التهيئة", + + // "collection.source.controls.test.running": "Testing configuration...", "collection.source.controls.test.running": "جاري اختبار التهيئة...", - "collection.source.controls.import.submit.success": "تم البدء بالتنشيط الفعال", + + // "collection.source.controls.import.submit.success": "The import has been successfully initiated", + "collection.source.controls.import.submit.success": "تم بدء الاستيراد بنجاح", + + // "collection.source.controls.import.submit.error": "Something went wrong with initiating the import", "collection.source.controls.import.submit.error": "حدث خطأ ما أثناء بدء الاستيراد", + + // "collection.source.controls.import.submit": "Import now", "collection.source.controls.import.submit": "استيراد الآن", + + // "collection.source.controls.import.running": "Importing...", "collection.source.controls.import.running": "جاري الاستيراد...", + + // "collection.source.controls.import.failed": "An error occurred during the import", "collection.source.controls.import.failed": "حدث خطأ أثناء الاستيراد", + + // "collection.source.controls.import.completed": "The import completed", "collection.source.controls.import.completed": "اكتمل الاستيراد", - "collection.source.controls.reset.submit.success": "تم البدء في البدء في المستقبل البعيد للاستيراد الفعال", - "collection.source.controls.reset.submit.error": "حدث خطأ ما أثناء البدء في إعادة الاستيراد", - "collection.source.controls.reset.failed": "حدث خطأ أثناء إعادة الاستيراد", - "collection.source.controls.reset.completed": "اكتملت العملية المتعلقة بإعادة الاستيراد", - "collection.source.controls.reset.submit": "أعد تعيينه لإعادة الاستيراد", - "collection.source.controls.reset.running": "جاري إعادة المركز للاستيراد...", - "collection.source.controls.harvest.status": "حالة:", - "collection.source.controls.harvest.start": "وقت البدء:", - "collection.source.controls.harvest.last": "تم آخر مرة:", - "collection.source.controls.harvest.message": "معلومات هناك:", - "collection.source.controls.harvest.no-information": "غير محتمل", - "collection.source.update.notifications.error.content": "تم اختبارها ولم لا تعمل ك.", + + // "collection.source.controls.reset.submit.success": "The reset and reimport has been successfully initiated", + "collection.source.controls.reset.submit.success": "تم بدء عملية إعادة التعيين وإعادة الاستيراد بنجاح", + + // "collection.source.controls.reset.submit.error": "Something went wrong with initiating the reset and reimport", + "collection.source.controls.reset.submit.error": "حدث خطأ ما أثناء بدء إعادة التعيين وإعادة الاستيراد", + + // "collection.source.controls.reset.failed": "An error occurred during the reset and reimport", + "collection.source.controls.reset.failed": "حدث خطأ أثناء إعادة التعيين وإعادة الاستيراد", + + // "collection.source.controls.reset.completed": "The reset and reimport completed", + "collection.source.controls.reset.completed": "اكتملت عملية إعادة التعيين وإعادة الاستيراد", + + // "collection.source.controls.reset.submit": "Reset and reimport", + "collection.source.controls.reset.submit": "إعادة تعيين وإعادة استيراد", + + // "collection.source.controls.reset.running": "Resetting and reimporting...", + "collection.source.controls.reset.running": "جاري إعادة التعيين وإعادة الاستيراد...", + + // "collection.source.controls.harvest.status": "Harvest status:", + "collection.source.controls.harvest.status": "حالة الحصاد:", + + // "collection.source.controls.harvest.start": "Harvest start time:", + "collection.source.controls.harvest.start": "وقت بدء الحصاد:", + + // "collection.source.controls.harvest.last": "Last time harvested:", + "collection.source.controls.harvest.last": "آخر مرة تم الحصاد:", + + // "collection.source.controls.harvest.message": "Harvest info:", + "collection.source.controls.harvest.message": "معلومات الحصاد:", + + // "collection.source.controls.harvest.no-information": "N/A", + "collection.source.controls.harvest.no-information": "غير قابل للتطبيق", + + // "collection.source.update.notifications.error.content": "The provided settings have been tested and didn't work.", + "collection.source.update.notifications.error.content": "تم اختبار الإعدادات المتوفرة ولم تعملk.", + + // "collection.source.update.notifications.error.title": "Server Error", "collection.source.update.notifications.error.title": "خطأ في الخادم", - "communityList.breadcrumbs": "اجمعها", - "communityList.tabTitle": "اجمعها", - "communityList.title": "اجمعها", + + // "communityList.breadcrumbs": "Community List", + "communityList.breadcrumbs": "قائمة المجتمعات", + + // "communityList.tabTitle": "Community List", + "communityList.tabTitle": "قائمة المجتمعات", + + // "communityList.title": "List of Communities", + "communityList.title": "قائمة المجتمعات", + + // "communityList.showMore": "Show More", "communityList.showMore": "عرض المزيد", - "communityList.expand": "الأوقات {{ name }}", - "communityList.collapse": "طيء {{ name }}", - "community.browse.logo": "تم الحصول على معلومات حول شعار المجتمع", - "community.subcoms-cols.breadcrumbs": "المجتمعات الفرعية والمجموعات", + + // "communityList.expand": "Expand {{ name }}", + "communityList.expand": "توسيع {{ name }}", + + // "communityList.collapse": "Collapse {{ name }}", + "communityList.collapse": "طي {{ name }}", + + // "community.browse.logo": "Browse for a community logo", + "community.browse.logo": "استعراض للحصول على شعار المجتمع", + + // "community.subcoms-cols.breadcrumbs": "Subcommunities and Collections", + // TODO New key - Add a translation + "community.subcoms-cols.breadcrumbs": "Subcommunities and Collections", + + // "community.create.head": "Create a Community", "community.create.head": "إنشاء مجتمع", - "community.create.notifications.success": "تم إنشاء المجتمع الفعال", - "community.create.sub-head": "إنشاء مجتمع فرعي متاح {{ parent }}", + + // "community.create.notifications.success": "Successfully created the Community", + "community.create.notifications.success": "تم إنشاء المجتمع بنجاح", + + // "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", + "community.create.sub-head": "إنشاء مجتمع فرعي للمجتمع {{ parent }}", + + // "community.curate.header": "Curate Community: {{community}}", "community.curate.header": "أكرتة المجتمع: {{community}}", + + // "community.delete.cancel": "Cancel", "community.delete.cancel": "إلغاء", - "community.delete.confirm": "بالتأكيد", + + // "community.delete.confirm": "Confirm", + "community.delete.confirm": "تأكيد", + + // "community.delete.processing": "Deleting...", "community.delete.processing": "جاري الحذف...", + + // "community.delete.head": "Delete Community", "community.delete.head": "حذف المجتمع", - "community.delete.notification.fail": "عذرًا لحذف المجتمع", - "community.delete.notification.success": "تم حذف المجتمع الفعال", + + // "community.delete.notification.fail": "Community could not be deleted", + "community.delete.notification.fail": "تعذر حذف المجتمع", + + // "community.delete.notification.success": "Successfully deleted community", + "community.delete.notification.success": "تم حذف المجتمع بنجاح", + + // "community.delete.text": "Are you sure you want to delete community \"{{ dso }}\"", "community.delete.text": "هل أنت متأكد من أنك تريد حذف المجتمع \"{{ dso }}\"", + + // "community.edit.delete": "Delete this community", "community.edit.delete": "حذف هذا المجتمع", + + // "community.edit.head": "Edit Community", "community.edit.head": "تحرير المجتمع", + + // "community.edit.breadcrumbs": "Edit Community", "community.edit.breadcrumbs": "تحرير المجتمع", + + // "community.edit.logo.delete.title": "Delete logo", "community.edit.logo.delete.title": "حذف الشعار", - "community.edit.logo.delete-undo.title": "السماء عن الحذف", + + // "community.edit.logo.delete-undo.title": "Undo delete", + "community.edit.logo.delete-undo.title": "التراجع عن الحذف", + + // "community.edit.logo.label": "Community logo", "community.edit.logo.label": "شعار المجتمع", - "community.edit.logo.notifications.add.error": "فشل تحميل شعار المجتمع. ", - "community.edit.logo.notifications.add.success": "تم تحميل شعار المجتمع الفعال.", + + // "community.edit.logo.notifications.add.error": "Uploading community logo failed. Please verify the content before retrying.", + "community.edit.logo.notifications.add.error": "فشل تحميل شعار المجتمع. يرجى التحقق من المحتوى قبل إعادة المحاولة.", + + // "community.edit.logo.notifications.add.success": "Upload community logo successful.", + "community.edit.logo.notifications.add.success": "تم تحميل شعار المجتمع بنجاح.", + + // "community.edit.logo.notifications.delete.success.title": "Logo deleted", "community.edit.logo.notifications.delete.success.title": "تم حذف الشعار", - "community.edit.logo.notifications.delete.success.content": "تم حذف العنصر الفعال", + + // "community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo", + "community.edit.logo.notifications.delete.success.content": "تم حذف شعار المجتمع بنجاح", + + // "community.edit.logo.notifications.delete.error.title": "Error deleting logo", "community.edit.logo.notifications.delete.error.title": "حدث خطأ أثناء حذف الشعار", + + // "community.edit.logo.upload": "Drop a community logo to upload", "community.edit.logo.upload": "قم بإسقاط شعار المجتمع للتحميل", - "community.edit.notifications.success": "تم تحرير المجتمع الفعال", - "community.edit.notifications.unauthorized": "ليس لديك امتيازات لهذا الغد", + + // "community.edit.notifications.success": "Successfully edited the Community", + "community.edit.notifications.success": "تم تحرير المجتمع بنجاح", + + // "community.edit.notifications.unauthorized": "You do not have privileges to make this change", + "community.edit.notifications.unauthorized": "ليس لديك امتيازات لإجراء هذا التغيير", + + // "community.edit.notifications.error": "An error occured while editing the community", "community.edit.notifications.error": "حدث خطأ أثناء تحرير المجتمع", + + // "community.edit.return": "Back", "community.edit.return": "رجوع", + + // "community.edit.tabs.curate.head": "Curate", "community.edit.tabs.curate.head": "أكرتة", - "community.edit.tabs.curate.title": "تحرير المجتمع - كورة", + + // "community.edit.tabs.curate.title": "Community Edit - Curate", + "community.edit.tabs.curate.title": "تحرير المجتمع - أكرتة", + + // "community.edit.tabs.access-control.head": "Access Control", "community.edit.tabs.access-control.head": "التحكم في الوصول", + + // "community.edit.tabs.access-control.title": "Community Edit - Access Control", "community.edit.tabs.access-control.title": "تحرير المجتمع - التحكم في الوصول", + + // "community.edit.tabs.metadata.head": "Edit Metadata", "community.edit.tabs.metadata.head": "تحرير الميتاداتا", + + // "community.edit.tabs.metadata.title": "Community Edit - Metadata", "community.edit.tabs.metadata.title": "تحرير المجتمع - الميتاداتا", - "community.edit.tabs.roles.head": "مواعيد محددة", + + // "community.edit.tabs.roles.head": "Assign Roles", + "community.edit.tabs.roles.head": "تعيين أدوار", + + // "community.edit.tabs.roles.title": "Community Edit - Roles", "community.edit.tabs.roles.title": "تحرير المجتمع - أدوار", + + // "community.edit.tabs.authorizations.head": "Authorizations", "community.edit.tabs.authorizations.head": "التصاريح", + + // "community.edit.tabs.authorizations.title": "Community Edit - Authorizations", "community.edit.tabs.authorizations.title": "تحرير المجتمع - التصاريح", + + // "community.listelement.badge": "Community", "community.listelement.badge": "مجتمع", + + // "community.logo": "Community logo", "community.logo": "شعار المجتمع", + + // "comcol-role.edit.no-group": "None", "comcol-role.edit.no-group": "لا شيء", + + // "comcol-role.edit.create": "Create", "comcol-role.edit.create": "إنشاء", + + // "comcol-role.edit.create.error.title": "Failed to create a group for the '{{ role }}' role", "comcol-role.edit.create.error.title": "فشل إنشاء مجموعة لدور '{{ role }}'", - "comcol-role.edit.restrict": "انها", + + // "comcol-role.edit.restrict": "Restrict", + "comcol-role.edit.restrict": "تقييد", + + // "comcol-role.edit.delete": "Delete", "comcol-role.edit.delete": "حذف", - "comcol-role.edit.delete.error.title": "فشل في حذف مجموعة الدور '{{ role }}'", + + // "comcol-role.edit.delete.error.title": "Failed to delete the '{{ role }}' role's group", + "comcol-role.edit.delete.error.title": "فشل حذف مجموعة الدور '{{ role }}'", + + // "comcol-role.edit.community-admin.name": "Administrators", "comcol-role.edit.community-admin.name": "المسؤولون", + + // "comcol-role.edit.collection-admin.name": "Administrators", "comcol-role.edit.collection-admin.name": "المسؤولون", - "comcol-role.edit.community-admin.description": "يمكن لمديري المجتمع إنشاء مجتمعات فرعية أو العهد، وإدارة أو تعيين المديرين المجتمعيين أو المعتمدين. ", - "comcol-role.edit.collection-admin.description": "تحديد مديري يبدأ من البدء في المواد إلى هذه المشاركة، وتحرير ميتاداتا المادة (بعد الحضور)، بحضور (تخطيط) المواد يبدأ من الآخر إلى هذه المشاركة (ترغب في المشاركة في المشاركة).", - "comcol-role.edit.submitters.name": "شيرون", - "comcol-role.edit.submitters.description": "الأشخاص الإلكترونيين والمجموعات الذين يملكون القدرة على تقديم منتجات جديدة إلى هذه البسيطة.", - "comcol-role.edit.item_read.name": "وصول قراءة المادة الافتراضية", - "comcol-role.edit.item_read.description": "الأشخاص الإلكترونيون والمجموعات الذين يمكنهم قراءة المواد الجديدة تم تقديمها إلى هذه البسيطة. ", - "comcol-role.edit.item_read.anonymous-group": "تم تعيين القراءة الإلكترونية للمواد حاليًا إلى معرف غير معرف.", + + // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + "comcol-role.edit.community-admin.description": "يمكن لمديري المجتمع إنشاء مجتمعات فرعية أو حاويات، وإدارة أو تعيين الإدارة لتلك المجتمعات الفرعية أو الحاويات. بالإضافة إلى ذلك، يقومون بتقرير من يمكنه تقديم المواد إلى أي حاويات فرعية، وتحرير ميتاداتا المادة (بعد التقديم)، وإضافة (تخطيط) المواد الحالية من الحاويات الأخرى (تخضع للتصريح).", + + // "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", + "comcol-role.edit.collection-admin.description": "يقرر مديري الحاوية من يمكنه تقديم المواد إلى الحاوية، وتحريرميتاداتا المادة (بعد التقديم)، وإضافة (تخطيط) المواد الحاوية من الحاويات الأخرى إلى هذه الحاوية (تخضع للتصريح لتلك الحاوية).", + + // "comcol-role.edit.submitters.name": "Submitters", + "comcol-role.edit.submitters.name": "المقدمون", + + // "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", + "comcol-role.edit.submitters.description": "الأشخاص الإلكترونيين والمجموعات الذين يملكون صلاحية تقديم مواد جديدة إلى هذه الحاوية.", + + // "comcol-role.edit.item_read.name": "Default item read access", + "comcol-role.edit.item_read.name": "وصول قراءة المادة الافتراضي", + + // "comcol-role.edit.item_read.description": "E-People and Groups that can read new items submitted to this collection. Changes to this role are not retroactive. Existing items in the system will still be viewable by those who had read access at the time of their addition.", + "comcol-role.edit.item_read.description": "الأشخاص الإلكترونيون والمجموعات الذين يمكنهم قراءة المواد الجديدة التي تم تقديمها إلى هذه الحاوية. التغييرات على هذا الدور ليست بأثر رجعي. ستظل المواد الحالية الموجودة في النظام قابلة للعرض بواسطة أولئك الذين يملكون الوصول للقراءة في وقت إضافتها.", + + // "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", + "comcol-role.edit.item_read.anonymous-group": "تم تعيين القراءة الافتراضية للمواد الواردة حاليًا إلى غير معرف الهوية.", + + // "comcol-role.edit.bitstream_read.name": "Default bitstream read access", "comcol-role.edit.bitstream_read.name": "وصول قراءة تدفق البت الافتراضي", - "comcol-role.edit.bitstream_read.description": "يمكن لمديري المجتمع إنشاء مجتمعات فرعية أو العهد، وإدارة أو تعيين المديرين المجتمعيين أو المعتمدين. ", - "comcol-role.edit.bitstream_read.anonymous-group": "تم تعيين القراءة الافتراضية لتدفقات البت حاليا إلى غير معرف الهوية.", + + // "comcol-role.edit.bitstream_read.description": "E-People and Groups that can read new bitstreams submitted to this collection. Changes to this role are not retroactive. Existing bitstreams in the system will still be viewable by those who had read access at the time of their addition.", + "comcol-role.edit.bitstream_read.description": "يمكن لمديري المجتمع إنشاء مجتمعات فرعية أو حاويات، وإدارة أو تعيين الإدارة لتلك المجتمعات الفرعية أو الحاويات. بالإضافة إلى ذلك، يقومون بتقرير من يمكنه تقديم المواد إلى أي حاويات فرعية، وتحرير ميتاداتا المادة (بعد التقديم)، وإضافة (تخطيط) المواد الحالية من الحاويات الأخرى (تخضع للتصريح).", + + // "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", + "comcol-role.edit.bitstream_read.anonymous-group": "تم تعيين القراءة الافتراضية لتدفقات البت الواردة حاليًا إلى غير معرف الهوية.", + + // "comcol-role.edit.editor.name": "Editors", "comcol-role.edit.editor.name": "المحررون", - "comcol-role.edit.editor.description": "يمكن للمحررون تحرير ميتاداتا للعروض المقدمة، ثم قبولها أو رفضها.", + + // "comcol-role.edit.editor.description": "Editors are able to edit the metadata of incoming submissions, and then accept or reject them.", + "comcol-role.edit.editor.description": "يمكن للمحررون تحرير ميتاداتا التقديمات الواردة، ثم قبولها أو رفضها.", + + // "comcol-role.edit.finaleditor.name": "Final editors", "comcol-role.edit.finaleditor.name": "المحررون النهائيون", - "comcol-role.edit.finaleditor.description": "يمكن للمحرر النهائي لتحرير ميتاداتا التقديمات المقدمة، لكن لا يمكنهم رفضها.", + + // "comcol-role.edit.finaleditor.description": "Final editors are able to edit the metadata of incoming submissions, but will not be able to reject them.", + "comcol-role.edit.finaleditor.description": "يمكن للمحررون النهائيون تحرير ميتاداتا التقديمات الواردة، لكن لا يمكنهم رفضها.", + + // "comcol-role.edit.reviewer.name": "Reviewers", "comcol-role.edit.reviewer.name": "المراجعون", - "comcol-role.edit.reviewer.description": "يمكن للمراجعين قبول أو رفض التقديم. ", - "comcol-role.edit.scorereviewers.name": "نقاط الضعفاء", - "comcol-role.edit.scorereviewers.description": "يمكن للمراجعين أن ترسل المشاركات إلينا، وهذا ما يحدد ما إذا كان الرفض أم لا.", - "community.form.abstract": "وصف قصير", - "community.form.description": "نص استعدادي (HTML)", - "community.form.errors.title.required": "الرجاء الاتصال باسم مجتمع", + + // "comcol-role.edit.reviewer.description": "Reviewers are able to accept or reject incoming submissions. However, they are not able to edit the submission's metadata.", + "comcol-role.edit.reviewer.description": "يمكن للمراجعين قبول أو رفض التقديمات الواردة. غير أنه لا يمكنهم تحرير ميتاداتا التقديم..", + + // "comcol-role.edit.scorereviewers.name": "Score Reviewers", + "comcol-role.edit.scorereviewers.name": "نقاط المراجعين", + + // "comcol-role.edit.scorereviewers.description": "Reviewers are able to give a score to incoming submissions, this will define whether the submission will be rejected or not.", + "comcol-role.edit.scorereviewers.description": "يمكن للمراجعين منح نقاط للمشاركات الواردة، وهذا سيحدد ما إذا كان سيتم رفض التقديم أم لا.", + + // "community.form.abstract": "Short Description", + "community.form.abstract": "وصف مختصر", + + // "community.form.description": "Introductory text (HTML)", + "community.form.description": "نص تمهيدي (HTML)", + + // "community.form.errors.title.required": "Please enter a community name", + "community.form.errors.title.required": "يرجى إدخال اسم مجتمع", + + // "community.form.rights": "Copyright text (HTML)", "community.form.rights": "نص حقوق النشر (HTML)", + + // "community.form.tableofcontents": "News (HTML)", "community.form.tableofcontents": "الأخبار (HTML)", + + // "community.form.title": "Name", "community.form.title": "الاسم", + + // "community.page.edit": "Edit this community", "community.page.edit": "تحرير هذا المجتمع", - "community.page.handle": "URI الجديد لهذا المجتمع", - "community.page.license": "com", + + // "community.page.handle": "Permanent URI for this community", + "community.page.handle": "ال URI الدائم لهذا المجتمع", + + // "community.page.license": "License", + "community.page.license": "الترخيص", + + // "community.page.news": "News", "community.page.news": "الأخبار", - "community.all-lists.head": "الكونيات الحاويات", - "community.search.results.head": "نتائج البحث", - "community.sub-collection-list.head": "توفيق هذا المجتمع", + + // "community.all-lists.head": "Subcommunities and Collections", + "community.all-lists.head": "المجتمعات الفرعية والحاويات", + + // "community.search.results.head": "Search Results", + // TODO New key - Add a translation + "community.search.results.head": "Search Results", + + // "community.sub-collection-list.head": "Collections in this Community", + "community.sub-collection-list.head": "حاويات هذا المجتمع", + + // "community.sub-community-list.head": "Communities in this Community", "community.sub-community-list.head": "مجتمعات هذا المجتمع", + + // "cookies.consent.accept-all": "Accept all", "cookies.consent.accept-all": "قبول الكل", - "cookies.consent.accept-selected": "قبول البناء", - "cookies.consent.app.opt-out.description": "تم تحميل هذا التطبيق افتراضياً (لكن يمكنك اختيار)", + + // "cookies.consent.accept-selected": "Accept selected", + "cookies.consent.accept-selected": "قبول المحدد", + + // "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", + "cookies.consent.app.opt-out.description": "تم تحميل هذا التطبيق افتراضياً (لكن يمكنك الانسحاب)", + + // "cookies.consent.app.opt-out.title": "(opt-out)", "cookies.consent.app.opt-out.title": "(انسحاب)", - "cookies.consent.app.purpose": "اللحوم", - "cookies.consent.app.required.description": "هذا التطبيق مطلوب تكرارا", - "cookies.consent.app.required.title": "(مطلوب مرة أخرى)", - "cookies.consent.app.disable-all.description": "استخدم هذا الزر لتفعيل جميع الخدمات أو جونسونها.", - "cookies.consent.app.disable-all.title": "تفعيل أو تفعيل كل الخدمات", - "cookies.consent.update": "لقد قمت بتغيير بعض التغييرات منذ الآن، يرجى تحديث موافقتك.", + + // "cookies.consent.app.purpose": "purpose", + "cookies.consent.app.purpose": "الغرض", + + // "cookies.consent.app.required.description": "This application is always required", + "cookies.consent.app.required.description": "هذا التطبيق مطلوب دائماً", + + // "cookies.consent.app.required.title": "(always required)", + "cookies.consent.app.required.title": "(مطلوب دائماً)", + + // "cookies.consent.app.disable-all.description": "Use this switch to enable or disable all services.", + "cookies.consent.app.disable-all.description": "استخدم هذا التبديل لتفعيل كل الخدمات أو تعطيلها.", + + // "cookies.consent.app.disable-all.title": "Enable or disable all services", + "cookies.consent.app.disable-all.title": "تفعيل أو تعطيل كل الخدمات", + + // "cookies.consent.update": "There were changes since your last visit, please update your consent.", + "cookies.consent.update": "لقد حدثت بعض التغييرات منذ زيارتك الأخيرة، يرجى تحديث موافقتك.", + + // "cookies.consent.close": "Close", "cookies.consent.close": "إغلاق", - "cookies.consent.decline": "الرفض", + + // "cookies.consent.decline": "Decline", + "cookies.consent.decline": "رفض", + + // "cookies.consent.ok": "That's ok", "cookies.consent.ok": "لا بأس", + + // "cookies.consent.save": "Save", "cookies.consent.save": "حفظ", + + // "cookies.consent.content-notice.title": "Cookie Consent", "cookies.consent.content-notice.title": "الموافقة على ملفات تعريف الارتباط", - "cookies.consent.content-notice.description": "لإصلاح بجمع ومعالجة معلوماتك الشخصية للأغراض التالية: الاستثناء، والتفضيلات، والاستخلاص، والإحصاء.
لمعرفة المزيد، يرجى قراءة {privacyPolicy}.", - "cookies.consent.content-notice.description.no-privacy": "لإصلاح بجمع ومعالجة معلوماتك الشخصية للأغراض التالية: الاستثناء، والتفضيلات، والاستخلاص، والإحصاء.", + + // "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.
To learn more, please read our {privacyPolicy}.", + "cookies.consent.content-notice.description": "نقوم بجمع ومعالجة معلوماتك الشخصية للأغراض التالية: الاستيثاق، والتفضيلات، والإقرار، والإحصائيات.
لمعرفة المزيد، يرجى قراءة {privacyPolicy}.", + + // "cookies.consent.content-notice.description.no-privacy": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.", + "cookies.consent.content-notice.description.no-privacy": "نقوم بجمع ومعالجة معلوماتك الشخصية للأغراض التالية: الاستيثاق، والتفضيلات، والإقرار، والإحصائيات.", + + // "cookies.consent.content-notice.learnMore": "Customize", "cookies.consent.content-notice.learnMore": "تخصيص", - "cookies.consent.content-modal.description": "من هنا يمكنك رؤية وتخصيص المعلومات التي تجمعها عنك.", + + // "cookies.consent.content-modal.description": "Here you can see and customize the information that we collect about you.", + "cookies.consent.content-modal.description": "من هنا يمكنك رؤية وتخصيص المعلومات التي نقوم بجمعها عنك.", + + // "cookies.consent.content-modal.privacy-policy.name": "privacy policy", "cookies.consent.content-modal.privacy-policy.name": "سياسة الخصوصية", + + // "cookies.consent.content-modal.privacy-policy.text": "To learn more, please read our {privacyPolicy}.", "cookies.consent.content-modal.privacy-policy.text": "لمعرفة المزيد، يرجى قراءة {privacyPolicy}.", - "cookies.consent.content-modal.title": "المعلومات التي بجمعها", + + // "cookies.consent.content-modal.title": "Information that we collect", + "cookies.consent.content-modal.title": "المعلومات التي نقوم بجمعها", + + // "cookies.consent.content-modal.services": "services", "cookies.consent.content-modal.services": "خدمات", + + // "cookies.consent.content-modal.service": "service", "cookies.consent.content-modal.service": "خدمة", + + // "cookies.consent.app.title.authentication": "Authentication", "cookies.consent.app.title.authentication": "استيثاق", + + // "cookies.consent.app.description.authentication": "Required for signing you in", "cookies.consent.app.description.authentication": "مطلوب لتسجيل دخولك", + + // "cookies.consent.app.title.preferences": "Preferences", "cookies.consent.app.title.preferences": "التفضيلات", - "cookies.consent.app.description.preferences": "مطلوب تحسين تفضيلاتك", - "cookies.consent.app.title.acknowledgement": "تأهيل", - "cookies.consent.app.description.acknowledgement": "مطلوب حفظك وموافقتك", + + // "cookies.consent.app.description.preferences": "Required for saving your preferences", + "cookies.consent.app.description.preferences": "مطلوب لحفظ تفضيلاتك", + + // "cookies.consent.app.title.acknowledgement": "Acknowledgement", + "cookies.consent.app.title.acknowledgement": "إقرار", + + // "cookies.consent.app.description.acknowledgement": "Required for saving your acknowledgements and consents", + "cookies.consent.app.description.acknowledgement": "مطلوب لحفظ إقراراتك وموافقاتك", + + // "cookies.consent.app.title.google-analytics": "Google Analytics", "cookies.consent.app.title.google-analytics": "تحليلات جوجل", - "cookies.consent.app.description.google-analytics": "يسمح لنا بتتبع البيانات الإحصائية", + + // "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", + "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", + + // "cookies.consent.app.title.google-recaptcha": "Google reCaptcha", "cookies.consent.app.title.google-recaptcha": "جوجل ريكابتشا", - "cookies.consent.app.description.google-recaptcha": "نحن نستخدم خدمة google reCAPTCHA أثناء التسجيل واستعادة كلمة المرور", - "cookies.consent.purpose.functional": "فعالة", + + // "cookies.consent.app.description.google-recaptcha": "We use google reCAPTCHA service during registration and password recovery", + // TODO New key - Add a translation + "cookies.consent.app.description.google-recaptcha": "We use google reCAPTCHA service during registration and password recovery", + + // "cookies.consent.purpose.functional": "Functional", + "cookies.consent.purpose.functional": "وظيفي", + + // "cookies.consent.purpose.statistical": "Statistical", "cookies.consent.purpose.statistical": "إحصائي", - "cookies.consent.purpose.registration-password-recovery": "التسجيل و استعادة كلمة المرور", + + // "cookies.consent.purpose.registration-password-recovery": "Registration and Password recovery", + "cookies.consent.purpose.registration-password-recovery": "التسجيل واستعادة كلمة المرور", + + // "cookies.consent.purpose.sharing": "Sharing", "cookies.consent.purpose.sharing": "مشاركة", + + // "curation-task.task.citationpage.label": "Generate Citation Page", "curation-task.task.citationpage.label": "إنشاء صفحة الاقتباس", + + // "curation-task.task.checklinks.label": "Check Links in Metadata", "curation-task.task.checklinks.label": "التحقق من الروابط في الميتاداتا", + + // "curation-task.task.noop.label": "NOOP", "curation-task.task.noop.label": "لا توجد مهمة", + + // "curation-task.task.profileformats.label": "Profile Bitstream Formats", "curation-task.task.profileformats.label": "تنسيقات تدفق بت البروفايل", - "curation-task.task.requiredmetadata.label": "التحقق من الميتاداتا المطلوبة", + + // "curation-task.task.requiredmetadata.label": "Check for Required Metadata", + "curation-task.task.requiredmetadata.label": "التحقق للميتاداتا المطلوبة", + + // "curation-task.task.translate.label": "Microsoft Translator", "curation-task.task.translate.label": "مترجم ميكروسوفت", - "curation-task.task.vscan.label": "حذف الفيروسات", - "curation-task.task.registerdoi.label": "تسجيل المعرفة الرقمية", - "curation.form.task-select.label": "مهم:", + + // "curation-task.task.vscan.label": "Virus Scan", + "curation-task.task.vscan.label": "مسح الفيروسات", + + // "curation-task.task.registerdoi.label": "Register DOI", + "curation-task.task.registerdoi.label": "تسجيل معرف الكائن الرقمي", + + // "curation.form.task-select.label": "Task:", + "curation.form.task-select.label": "المهمة:", + + // "curation.form.submit": "Start", "curation.form.submit": "بدء", - "curation.form.submit.success.head": "تم بدء مهمة فعالة فعالة", - "curation.form.submit.success.content": "ستتم إعادة توجيهك إلى السجن.", - "curation.form.submit.error.head": "فشل تشغيل مهمة أخرى", + + // "curation.form.submit.success.head": "The curation task has been started successfully", + "curation.form.submit.success.head": "تم بدء مهمة الأكرتة بنجاح", + + // "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", + "curation.form.submit.success.content": "ستتم إعادة توجيهك إلى صفحة العملية المقابلة.", + + // "curation.form.submit.error.head": "Running the curation task failed", + "curation.form.submit.error.head": "فشل تشغيل مهمة الأكرتة", + + // "curation.form.submit.error.content": "An error occured when trying to start the curation task.", "curation.form.submit.error.content": "حدث خطأ أثناء محاولة بدء مهمة الأكرتة.", - "curation.form.submit.error.invalid-handle": "تعذر تحديد يد هذا", - "curation.form.handle.label": "مقبض:", - "curation.form.handle.hint": "تلميح: قم برجاء زيارة [your-handle-prefix]/0 لاستخدام مهمة عبر الموقع قادرة (قد لا تدعم جميع هذه الإمكانية)", - "deny-request-copy.email.message": "عزيزي {{ recipientName }},\n{{ itemUrl }}\"({{ itemName }})، والتي قمت بتأليفها.\n\n\n{{ authorName }} <{{ authorEmail }}>", - "deny-request-copy.email.subject": "طلب نسخة من الوثيقة", + + // "curation.form.submit.error.invalid-handle": "Couldn't determine the handle for this object", + "curation.form.submit.error.invalid-handle": "تعذر تحديد هاندل هذا الكائن", + + // "curation.form.handle.label": "Handle:", + "curation.form.handle.label": "هاندل:", + + // "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", + "curation.form.handle.hint": "تلميح: قم بإدخال [your-handle-prefix]/0 لتشغيل مهمة عبر الموقع بأكمله (قد لا تدعم جميع المهام هذه الإمكانية)", + + // "deny-request-copy.email.message": "Dear {{ recipientName }},\nIn response to your request I regret to inform you that it's not possible to send you a copy of the file(s) you have requested, concerning the document: \"{{ itemUrl }}\" ({{ itemName }}), of which I am an author.\n\nBest regards,\n{{ authorName }} <{{ authorEmail }}>", + "deny-request-copy.email.message": "عزيزي {{ recipientName }},\nردًا على طلبك، يؤسفني إبلاغك أنه لا يمكن إرسال نسخة من الملف الذي قمت بطلبه، فيما يتعلق بالوثيقة: \"{{ itemUrl }}\" ({{ itemName }}), والتي قمت بتأليفها.\n\nمع أطيب التحيات,\n{{ authorName }} <{{ authorEmail }}>", + + // "deny-request-copy.email.subject": "Request copy of document", + "deny-request-copy.email.subject": "طلب نسخة من وثيقة", + + // "deny-request-copy.error": "An error occurred", "deny-request-copy.error": "لقد حدث خطأ", - "deny-request-copy.header": "طلب طلب نسخة أوكلاند", + + // "deny-request-copy.header": "Deny document copy request", + "deny-request-copy.header": "رفض طلب نسخ الوثيقة", + + // "deny-request-copy.intro": "This message will be sent to the applicant of the request", "deny-request-copy.intro": "سيتم إرسال هذه الرسالة إلى مقدم الطلب", - "deny-request-copy.success": "تم الرفض للطلب الفعال", + + // "deny-request-copy.success": "Successfully denied item request", + "deny-request-copy.success": "تم رفض طلب المادة بنجاح", + + // "dso.name.untitled": "Untitled", "dso.name.untitled": "بدون عنوان", + + // "dso.name.unnamed": "Unnamed", "dso.name.unnamed": "بدون اسم", + + // "dso-selector.create.collection.head": "New collection", "dso-selector.create.collection.head": "حاوية جديدة", + + // "dso-selector.create.collection.sub-level": "Create a new collection in", "dso-selector.create.collection.sub-level": "إنشاء حاوية جديدة في", + + // "dso-selector.create.community.head": "New community", "dso-selector.create.community.head": "مجتمع جديد", + + // "dso-selector.create.community.or-divider": "or", "dso-selector.create.community.or-divider": "أو", + + // "dso-selector.create.community.sub-level": "Create a new community in", "dso-selector.create.community.sub-level": "إنشاء مجتمع جديد في", + + // "dso-selector.create.community.top-level": "Create a new top-level community", "dso-selector.create.community.top-level": "إنشاء مجتمع مستوى أعلى جديد", + + // "dso-selector.create.item.head": "New item", "dso-selector.create.item.head": "مادة جديدة", + + // "dso-selector.create.item.sub-level": "Create a new item in", "dso-selector.create.item.sub-level": "إنشاء مادة جديدة في", + + // "dso-selector.create.submission.head": "New submission", "dso-selector.create.submission.head": "تقديم جديد", - "dso-selector.edit.collection.head": "تحرير", + + // "dso-selector.edit.collection.head": "Edit collection", + "dso-selector.edit.collection.head": "تحرير الحاوية", + + // "dso-selector.edit.community.head": "Edit community", "dso-selector.edit.community.head": "تحرير المجتمع", + + // "dso-selector.edit.item.head": "Edit item", "dso-selector.edit.item.head": "تحرير المادة", - "dso-selector.error.title": "حدث خطأ أثناء البحث عنه {{ type }}", - "dso-selector.export-metadata.dspaceobject.head": "قم باستيراد بيانات ميتا من", - "dso-selector.export-batch.dspaceobject.head": "قم باستيراد دفعة (ZIP) من", - "dso-selector.import-batch.dspaceobject.head": "قم باستيراد دفعة من", - "dso-selector.no-results": "لم يتم العثور عليها {{ type }}", - "dso-selector.placeholder": "بحثت عن {{ type }}", - "dso-selector.select.collection.head": "تحديد الحاوية", + + // "dso-selector.error.title": "An error occurred searching for a {{ type }}", + "dso-selector.error.title": "حدث خطأ أثناء البحث عن {{ type }}", + + // "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", + "dso-selector.export-metadata.dspaceobject.head": "استيراد ميتاداتا من", + + // "dso-selector.export-batch.dspaceobject.head": "Export Batch (ZIP) from", + "dso-selector.export-batch.dspaceobject.head": "استيراد دفعة (ZIP) من", + + // "dso-selector.import-batch.dspaceobject.head": "Import batch from", + "dso-selector.import-batch.dspaceobject.head": "استيراد دفعة من", + + // "dso-selector.no-results": "No {{ type }} found", + "dso-selector.no-results": "لم يتم العثور على {{ type }}", + + // "dso-selector.placeholder": "Search for a {{ type }}", + "dso-selector.placeholder": "بحث عن {{ type }}", + + // "dso-selector.select.collection.head": "Select a collection", + "dso-selector.select.collection.head": "تحديد حاوية", + + // "dso-selector.set-scope.community.head": "Select a search scope", "dso-selector.set-scope.community.head": "تحديد نطاق البحث", + + // "dso-selector.set-scope.community.button": "Search all of DSpace", "dso-selector.set-scope.community.button": "بحث دي سبيس بالكامل", + + // "dso-selector.set-scope.community.or-divider": "or", "dso-selector.set-scope.community.or-divider": "أو", - "dso-selector.set-scope.community.input-header": "ابحث عن حاوية أو مجتمع", + + // "dso-selector.set-scope.community.input-header": "Search for a community or collection", + "dso-selector.set-scope.community.input-header": "البحث عن حاوية أو مجتمع", + + // "dso-selector.claim.item.head": "Profile tips", "dso-selector.claim.item.head": "نصائح الملف الشخصي", - "dso-selector.claim.item.body": "هذه هي الملفات الشخصية التي قد تكون ذات صلة بك. ", + + // "dso-selector.claim.item.body": "These are existing profiles that may be related to you. If you recognize yourself in one of these profiles, select it and on the detail page, among the options, choose to claim it. Otherwise you can create a new profile from scratch using the button below.", + "dso-selector.claim.item.body": "هذه هي الملفات الشخصية الموجودة التي قد تكون ذات صلة بك. إذا تعرفت على نفسك في أحد هذه الملفات الشخصية، قم بتحديده وفي صفحة التفاصيل، من بين الخيارات، اختر المطالبة به. بخلاف ذلك، يمكنك إنشاء ملف شخصي جديد من البداية باستخدام الزر أدناه.", + + // "dso-selector.claim.item.not-mine-label": "None of these are mine", "dso-selector.claim.item.not-mine-label": "لا يعود أي من هذا لي", + + // "dso-selector.claim.item.create-from-scratch": "Create a new one", "dso-selector.claim.item.create-from-scratch": "إنشاء واحد جديد", - "dso-selector.results-could-not-be-retrieved": "حدث خطأ ما، يرجى تحديث مرة أخرى ↻", + + // "dso-selector.results-could-not-be-retrieved": "Something went wrong, please refresh again ↻", + "dso-selector.results-could-not-be-retrieved": "حدث خطأ ما، يرجى التحديث مرة أخرى ↻", + + // "supervision-group-selector.header": "Supervision Group Selector", "supervision-group-selector.header": "محدد مجموعة الإشراف", - "supervision-group-selector.select.type-of-order.label": "حدد نوع الصف", + + // "supervision-group-selector.select.type-of-order.label": "Select a type of Order", + "supervision-group-selector.select.type-of-order.label": "حدد نوع الرتبة", + + // "supervision-group-selector.select.type-of-order.option.none": "NONE", "supervision-group-selector.select.type-of-order.option.none": "لا شيء", + + // "supervision-group-selector.select.type-of-order.option.editor": "EDITOR", "supervision-group-selector.select.type-of-order.option.editor": "محرر", - "supervision-group-selector.select.type-of-order.option.observer": "انتبه", - "supervision-group-selector.select.group.label": "حدد المجموعة", + + // "supervision-group-selector.select.type-of-order.option.observer": "OBSERVER", + "supervision-group-selector.select.type-of-order.option.observer": "مراقب", + + // "supervision-group-selector.select.group.label": "Select a Group", + "supervision-group-selector.select.group.label": "حدد مجموعة", + + // "supervision-group-selector.button.cancel": "Cancel", "supervision-group-selector.button.cancel": "إلغاء", + + // "supervision-group-selector.button.save": "Save", "supervision-group-selector.button.save": "حفظ", - "supervision-group-selector.select.type-of-order.error": "يرجى تحديد نوع الطائرة", - "supervision-group-selector.select.group.error": "يرجى تحديد المجموعة", - "supervision-group-selector.notification.create.success.title": "تم إنشاء تشكيلة متنوعة فعالة {{ name }}", + + // "supervision-group-selector.select.type-of-order.error": "Please select a type of order", + "supervision-group-selector.select.type-of-order.error": "يرجى تحديد نوع الرتبة", + + // "supervision-group-selector.select.group.error": "Please select a group", + "supervision-group-selector.select.group.error": "يرجى تحديد مجموعة", + + // "supervision-group-selector.notification.create.success.title": "Successfully created supervision order for group {{ name }}", + "supervision-group-selector.notification.create.success.title": "تم إنشاء رتبة الإشراف للمجموعة بنجاح {{ name }}", + + // "supervision-group-selector.notification.create.failure.title": "Error", "supervision-group-selector.notification.create.failure.title": "خطأ", - "supervision-group-selector.notification.create.already-existing": "هناك بالفعل خيار البحث عن هذه المواد المحددة", + + // "supervision-group-selector.notification.create.already-existing": "A supervision order already exists on this item for selected group", + "supervision-group-selector.notification.create.already-existing": "يوجد بالفعل رتبة إشراف على هذه المادة للمجموعة المحددة", + + // "confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}", "confirmation-modal.export-metadata.header": "تصدير الميتاداتا لـ {{ dsoName }}", + + // "confirmation-modal.export-metadata.info": "Are you sure you want to export metadata for {{ dsoName }}", "confirmation-modal.export-metadata.info": "هل أنت متأكد أنك تريد تصدير الميتاداتا لـ {{ dsoName }}", + + // "confirmation-modal.export-metadata.cancel": "Cancel", "confirmation-modal.export-metadata.cancel": "إلغاء", + + // "confirmation-modal.export-metadata.confirm": "Export", "confirmation-modal.export-metadata.confirm": "تصدير", + + // "confirmation-modal.export-batch.header": "Export batch (ZIP) for {{ dsoName }}", "confirmation-modal.export-batch.header": "تصدير دفعة (ZIP) لـ {{ dsoName }}", + + // "confirmation-modal.export-batch.info": "Are you sure you want to export batch (ZIP) for {{ dsoName }}", "confirmation-modal.export-batch.info": "هل أنت متأكد أنك تريد تصدير دفعة (ZIP) لـ {{ dsoName }}", + + // "confirmation-modal.export-batch.cancel": "Cancel", "confirmation-modal.export-batch.cancel": "إلغاء", + + // "confirmation-modal.export-batch.confirm": "Export", "confirmation-modal.export-batch.confirm": "تصدير", + + // "confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"", "confirmation-modal.delete-eperson.header": "حذف الشخص الإلكتروني \"{{ dsoName }}\"", - "confirmation-modal.delete-eperson.info": "هل أنت متأكد من أنك تريد حذف الهاتف الإلكتروني \"{{ dsoName }}\"", + + // "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", + "confirmation-modal.delete-eperson.info": "هل أنت متأكد من أنك تريد حذف الشخص الإلكتروني \"{{ dsoName }}\"", + + // "confirmation-modal.delete-eperson.cancel": "Cancel", "confirmation-modal.delete-eperson.cancel": "إلغاء", + + // "confirmation-modal.delete-eperson.confirm": "Delete", "confirmation-modal.delete-eperson.confirm": "حذف", + + // "confirmation-modal.delete-profile.header": "Delete Profile", "confirmation-modal.delete-profile.header": "حذف الملف الشخصي", - "confirmation-modal.delete-profile.info": "هل أنت متأكد من أنك تريد حذف ملفك الشخصي", + + // "confirmation-modal.delete-profile.info": "Are you sure you want to delete your profile", + "confirmation-modal.delete-profile.info": "هل أنت متأكد أنك تريد حذف ملف الشخصي الخاص بك", + + // "confirmation-modal.delete-profile.cancel": "Cancel", "confirmation-modal.delete-profile.cancel": "إلغاء", + + // "confirmation-modal.delete-profile.confirm": "Delete", "confirmation-modal.delete-profile.confirm": "حذف", + + // "confirmation-modal.delete-subscription.header": "Delete Subscription", "confirmation-modal.delete-subscription.header": "حذف الاشتراك", + + // "confirmation-modal.delete-subscription.info": "Are you sure you want to delete subscription for \"{{ dsoName }}\"", "confirmation-modal.delete-subscription.info": "هل أنت متأكد من أنك تريد حذف الاشتراك لـ \"{{ dsoName }}\"", + + // "confirmation-modal.delete-subscription.cancel": "Cancel", "confirmation-modal.delete-subscription.cancel": "إلغاء", + + // "confirmation-modal.delete-subscription.confirm": "Delete", "confirmation-modal.delete-subscription.confirm": "حذف", - "error.bitstream": "حدث خطأ أثناء تدفق البالت", - "error.browse-by": "حدث خطأ أثناء المواد", - "error.collection": "حدث خطأ أثناء دخول", - "error.collections": "حدث خطأ أثناء فترة مقبولة", - "error.community": "حدث خطأ أثناء المجتمع", + + // "error.bitstream": "Error fetching bitstream", + "error.bitstream": "حدث خطأ أثناء جلب تدفق البت", + + // "error.browse-by": "Error fetching items", + "error.browse-by": "حدث خطأ أثناء جلب المواد", + + // "error.collection": "Error fetching collection", + "error.collection": "حدث خطأ أثناء جلب الحاوية", + + // "error.collections": "Error fetching collections", + "error.collections": "حدث خطأ أثناء جلب الحاويات", + + // "error.community": "Error fetching community", + "error.community": "حدث خطأ أثناء جلب المجتمع", + + // "error.identifier": "No item found for the identifier", "error.identifier": "لم يتم العثور على أي مادة للمعرف", + + // "error.default": "Error", "error.default": "خطأ", - "error.item": "حدث خطأ أثناء حضور المادة", - "error.items": "حدث خطأ أثناء المواد", - "error.objects": "حدث خطأ أثناء إجراء الكائنات الفضائية", - "error.recent-submissions": "حدث خطأ أثناء جلب أحدث العروض", - "error.search-results": "حدث خطأ أثناء نتائج البحث", - "error.invalid-search-query": "استعلام البحث غير صالح. بناء جملة استعلام Solr أفضل الممارسات للحصول على قراءة المعلومات حول هذا الخطأ.", - "error.sub-collections": "حدث خطأ أثناء تقديم العرض", - "error.sub-communities": "حدث خطأ أثناء النظر في الجسد", - "error.submission.sections.init-form-error": "حدث خطأ أثناء تهيئة القسم، يرجى التحقق من تهيئة نموذج العنصر الخاص بك.

", - "error.top-level-communities": "حدث خطأ خلال مجتمعات المستوى الأعلى", - "error.validation.license.notgranted": "يجب عليك أن تطلب من هذا الأمر التقديم الخاص بك. ", + + // "error.item": "Error fetching item", + "error.item": "حدث خطأ أثناء جلب المادة", + + // "error.items": "Error fetching items", + "error.items": "حدث خطأ أثناء جلب المواد", + + // "error.objects": "Error fetching objects", + "error.objects": "حدث خطأ أثناء جلب الكائنات", + + // "error.recent-submissions": "Error fetching recent submissions", + "error.recent-submissions": "حدث خطأ أثناء جلب أحدث التقديمات", + + // "error.search-results": "Error fetching search results", + "error.search-results": "حدث خطأ أثناء جلب نتائج البحث", + + // "error.invalid-search-query": "Search query is not valid. Please check Solr query syntax best practices for further information about this error.", + "error.invalid-search-query": "استعلام البحث غير صالح. يرجى مراجعة بناء جملة استعلام Solr أفضل الممارسات للحصول على مزيد من المعلومات حول هذا الخطأ.", + + // "error.sub-collections": "Error fetching sub-collections", + "error.sub-collections": "حدث خطأ أثناء جلب الحاويات الفرعية", + + // "error.sub-communities": "Error fetching sub-communities", + "error.sub-communities": "حدث خطأ أثناء جلب المجتمعات الفرعية", + + // "error.submission.sections.init-form-error": "An error occurred during section initialize, please check your input-form configuration. Details are below :

", + "error.submission.sections.init-form-error": "حدث خطأ أثناء تهيئة القسم، يرجى التحقق من تهيئة نموذج الإدخال الخاص بك. التفاصيل أدناه :

", + + // "error.top-level-communities": "Error fetching top-level communities", + "error.top-level-communities": "حدث خطأ أثناء جلب مجتمعات المستوى الأعلى", + + // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", + "error.validation.license.notgranted": "يجب عليك منح هذا الترخيص لإكمال عملية التقديم الخاصة بك. إذا لم تتمكن من منح هذا الترخيص في هذا الوقت، يمكنك حفظ عملك والعودة لاحقاً أو إزالة التقديم.", + + // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", "error.validation.pattern": "هذا الإدخال مقيد بالنمط الحالي: {{ pattern }}.", - "error.validation.filerequired": "تحميل الملف المشروط", - "error.validation.required": "هذا مطلوب الحقل", + + // "error.validation.filerequired": "The file upload is mandatory", + "error.validation.filerequired": "تحميل الملف إلزامي", + + // "error.validation.required": "This field is required", + "error.validation.required": "هذا الحقل مطلوب", + + // "error.validation.NotValidEmail": "This is not a valid email", "error.validation.NotValidEmail": "البريد الإلكتروني غير صالح", - "error.validation.emailTaken": "هذا البريد الإلكتروني السؤال بالفعل", + + // "error.validation.emailTaken": "This email is already taken", + "error.validation.emailTaken": "هذا البريد الإلكتروني مأخوذ بالفعل", + + // "error.validation.groupExists": "This group already exists", "error.validation.groupExists": "هذه المجموعة موجودة بالفعل", - "error.validation.metadata.name.invalid-pattern": "لا يمكن أن يحتوي هذا الحقل على نقاط أو فواصل أو مسافات. ", + + // "error.validation.metadata.name.invalid-pattern": "This field cannot contain dots, commas or spaces. Please use the Element & Qualifier fields instead", + "error.validation.metadata.name.invalid-pattern": "لا يمكن أن يحتوي هذا الحقل على نقاط أو فواصل أو مسافات. يرجى استخدام حقول العنصر والمؤهل بدلاً من ذلك", + + // "error.validation.metadata.name.max-length": "This field may not contain more than 32 characters", "error.validation.metadata.name.max-length": "يجب ألا يحتوي هذا الحقل على أكثر من 32 حرفاً", - "error.validation.metadata.namespace.max-length": "يجب ألا يحتوي هذا الحقل على أكثر من 256 حرفاً", - "error.validation.metadata.element.invalid-pattern": "لا يمكن أن يحتوي هذا الحقل على نقاط أو فواصل أو مسافات. ", + + // "error.validation.metadata.namespace.max-length": "This field may not contain more than 256 characters", + "error.validation.metadata.namespace.max-length": "يجب ألا يحتوي هذا الحقل على أكثر من 256 حرفاًs", + + // "error.validation.metadata.element.invalid-pattern": "This field cannot contain dots, commas or spaces. Please use the Qualifier field instead", + "error.validation.metadata.element.invalid-pattern": "لا يمكن أن يحتوي هذا الحقل على نقاط أو فواصل أو مسافات. يرجى استخدام حقل المؤهل بدلاً من ذلك", + + // "error.validation.metadata.element.max-length": "This field may not contain more than 64 characters", "error.validation.metadata.element.max-length": "يجب ألا يحتوي هذا الحقل على أكثر من 64 حرفاً", + + // "error.validation.metadata.qualifier.invalid-pattern": "This field cannot contain dots, commas or spaces", "error.validation.metadata.qualifier.invalid-pattern": "لا يمكن أن يحتوي هذا الحقل على نقاط أو فواصل أو مسافات", + + // "error.validation.metadata.qualifier.max-length": "This field may not contain more than 64 characters", "error.validation.metadata.qualifier.max-length": "يجب ألا يحتوي هذا الحقل على أكثر من 64 حرفاً", - "feed.description": " مشاركة التعليقات", + + // "feed.description": "Syndication feed", + "feed.description": " ملاحظات Syndication", + + // "file-download-link.restricted": "Restricted bitstream", "file-download-link.restricted": "دفق البت المقيد", - "file-section.error.header": "حدث خطأ أثناء الحصول على ملفات هذه المادة", + + // "file-section.error.header": "Error obtaining files for this item", + "file-section.error.header": "حدث خطأ أثناء الحصول على ملفات لهذه المادة", + + // "footer.copyright": "copyright © 2002-{{ year }}", "footer.copyright": "حقوق النشر © 2002-{{ year }}", + + // "footer.link.dspace": "DSpace software", "footer.link.dspace": "برنامج دي سبيس", + + // "footer.link.lyrasis": "LYRASIS", "footer.link.lyrasis": "ليراسيس", + + // "footer.link.cookies": "Cookie settings", "footer.link.cookies": "إعدادات ملفات تعريف الارتباط", + + // "footer.link.privacy-policy": "Privacy policy", "footer.link.privacy-policy": "سياسة الخصوصية", - "footer.link.end-user-agreement": "الاستخدام النهائي", + + // "footer.link.end-user-agreement": "End User Agreement", + "footer.link.end-user-agreement": "اتفاقية المستخدم النهائي", + + // "footer.link.feedback": "Send Feedback", "footer.link.feedback": "إرسال الملاحظات", - "footer.link.coar-notify-support": "إخطار COAR", + + // "footer.link.coar-notify-support": "COAR Notify", + // TODO New key - Add a translation + "footer.link.coar-notify-support": "COAR Notify", + + // "forgot-email.form.header": "Forgot Password", "forgot-email.form.header": "هل نسيت كلمة المرور", - "forgot-email.form.info": "قم بالضغط على عنوان البريد الإلكتروني ليس بالحساب.", + + // "forgot-email.form.info": "Enter the email address associated with the account.", + "forgot-email.form.info": "قم بإدخال عنوان البريد الإلكتروني المرتبط بالحساب.", + + // "forgot-email.form.email": "Email Address *", "forgot-email.form.email": "عنوان البريد الإلكتروني *", - "forgot-email.form.email.error.required": "الرجاء ملء عنوان البريد الإلكتروني", - "forgot-email.form.email.error.not-email-form": "برجاء ملء عنوان بريد إلكتروني صالح", - "forgot-email.form.email.hint": "سيتم إرسال بريد الإلكتروني إلى هذا العنوان ويتضمن المزيد من التعليمات.", + + // "forgot-email.form.email.error.required": "Please fill in an email address", + "forgot-email.form.email.error.required": "يرجى ملء عنوان البريد الإلكتروني", + + // "forgot-email.form.email.error.not-email-form": "Please fill in a valid email address", + "forgot-email.form.email.error.not-email-form": "يرجى ملء عنوان بريد إلكتروني صالح", + + // "forgot-email.form.email.hint": "An email will be sent to this address with a further instructions.", + "forgot-email.form.email.hint": "سيتم إرسال بريد إلكتروني إلى هذا العنوان يتضمن المزيد من التعليمات.", + + // "forgot-email.form.submit": "Reset password", "forgot-email.form.submit": "إعادة تعيين كلمة المرور", - "forgot-email.form.success.head": "تم إرسال رسالة عبر البريد الإلكتروني وإعادة تعيين كلمة المرور", - "forgot-email.form.success.content": "تم إرسال بريد إلكتروني إلى {{ email }} يحتوي على عنوان URL الخاص بالمزيد.", + + // "forgot-email.form.success.head": "Password reset email sent", + "forgot-email.form.success.head": "تم إرسال رسالة عبر البريد الإلكتروني لإعادة تعيين كلمة المرور", + + // "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + "forgot-email.form.success.content": "تم إرسال بريد إلكتروني إلى {{ email }} يحتوي على عنوان URL خاص وتعليمات إضافية.", + + // "forgot-email.form.error.head": "Error when trying to reset password", "forgot-email.form.error.head": "حدث خطأ أثناء محاولة إعادة تعيين كلمة المرور", - "forgot-email.form.error.content": "حدث خطأ أثناء محاولة إعادة تعيين كلمة المرور للحساب بالإضافة إلى عنوان البريد الإلكتروني التالي: {{ email }}", + + // "forgot-email.form.error.content": "An error occured when attempting to reset the password for the account associated with the following email address: {{ email }}", + "forgot-email.form.error.content": "حدث خطأ أثناء محاولة إعادة تعيين كلمة المرور للحساب المرتبط بعنوان البريد الإلكتروني التالي: {{ email }}", + + // "forgot-password.title": "Forgot Password", "forgot-password.title": "نسيت كلمة المرور", + + // "forgot-password.form.head": "Forgot Password", "forgot-password.form.head": "نسيت كلمة المرور", - "forgot-password.form.info": "قم بتأكيد كلمة المرور الجديدة في الشريط أدناه، وقم بتأكيدها عن طريق كتابتها مرة أخرى في الشريط الثاني.", + + // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box.", + "forgot-password.form.info": "قم بإدخال كلمة المرور الجديدة في المربع أدناه، وقم بتأكيدها عن طريق كتابتها مرة أخرى في المربع الثاني.", + + // "forgot-password.form.card.security": "Security", "forgot-password.form.card.security": "الحماية والأمان", + + // "forgot-password.form.identification.header": "Identify", "forgot-password.form.identification.header": "تعريف", + + // "forgot-password.form.identification.email": "Email address: ", "forgot-password.form.identification.email": "عنوان البريد الإلكتروني: ", + + // "forgot-password.form.label.password": "Password", "forgot-password.form.label.password": "كلمة المرور", - "forgot-password.form.label.passwordrepeat": "إعادة الكتابة للتأكيد", - "forgot-password.form.error.empty-password": "يرجى الاتصال بكلمة المرور في المجالات السابقة.", + + // "forgot-password.form.label.passwordrepeat": "Retype to confirm", + "forgot-password.form.label.passwordrepeat": "أعد الكتابة للتأكيد", + + // "forgot-password.form.error.empty-password": "Please enter a password in the boxes above.", + "forgot-password.form.error.empty-password": "يرجى إدخال كلمة المرور في المربعات أعلاه.", + + // "forgot-password.form.error.matching-passwords": "The passwords do not match.", "forgot-password.form.error.matching-passwords": "كلمات المرور غير متطابقة.", + + // "forgot-password.form.notification.error.title": "Error when trying to submit new password", "forgot-password.form.notification.error.title": "حدث خطأ أثناء محاولة تقديم كلمة المرور الجديدة", - "forgot-password.form.notification.success.content": "تمت إعادة تعيين كلمة فعالة. ", + + // "forgot-password.form.notification.success.content": "The password reset was successful. You have been logged in as the created user.", + "forgot-password.form.notification.success.content": "تمت إعادة تعيين كلمة المرور بنجاح. لقد قمت بتسجيل الدخول كمستخدم تم إنشاؤه.", + + // "forgot-password.form.notification.success.title": "Password reset completed", "forgot-password.form.notification.success.title": "اكتملت إعادة تعيين كلمة المرور", + + // "forgot-password.form.submit": "Submit password", "forgot-password.form.submit": "تقديم كلمة المرور", + + // "form.add": "Add more", "form.add": "إضافة المزيد", - "form.add-help": "انقر هنا لإدخال النص الحالي", + + // "form.add-help": "Click here to add the current entry and to add another one", + "form.add-help": "انقر هنا لإضافة الإدخال الحالي وإضافة إدخال آخر", + + // "form.cancel": "Cancel", "form.cancel": "إلغاء", - "form.clear": "تعديل التعديل", - "form.clear-help": "انقر هنا القيمة المحددة", - "form.discard": "لا", - "form.drag": "يسحب", + + // "form.clear": "Clear", + "form.clear": "مسح", + + // "form.clear-help": "Click here to remove the selected value", + "form.clear-help": "انقر هنا لإزالة القيمة المحددة", + + // "form.discard": "Discard", + "form.discard": "تجاهل", + + // "form.drag": "Drag", + "form.drag": "سحب", + + // "form.edit": "Edit", "form.edit": "تحرير", + + // "form.edit-help": "Click here to edit the selected value", "form.edit-help": "انقر هنا لتحرير القيمة المحددة", + + // "form.first-name": "First name", "form.first-name": "الاسم الأول", - "form.group-collapse": "طيء", + + // "form.group-collapse": "Collapse", + "form.group-collapse": "طي", + + // "form.group-collapse-help": "Click here to collapse", "form.group-collapse-help": "انقر هنا للطي", - "form.group-expand": "الأوقات", - "form.group-expand-help": "انقر هنا للتوسيع ولم المزيد من العناصر", + + // "form.group-expand": "Expand", + "form.group-expand": "توسيع", + + // "form.group-expand-help": "Click here to expand and add more elements", + "form.group-expand-help": "انقر هنا للتوسيع وإضافة المزيد من العناصر", + + // "form.last-name": "Last name", "form.last-name": "اسم العائلة", + + // "form.loading": "Loading...", "form.loading": "جاري التحميل...", - "form.lookup": "هان عن", - "form.lookup-help": "انقر هنا للبحث عن علاقة حالة", - "form.no-results": "لم يتم العثور على النتائج", - "form.no-value": "لم يتم توفير أي قيمة", + + // "form.lookup": "Lookup", + "form.lookup": "ابحث عن", + + // "form.lookup-help": "Click here to look up an existing relation", + "form.lookup-help": "انقر هنا للبحث عن علاقة حالية", + + // "form.no-results": "No results found", + "form.no-results": "لم يتم العثور على نتائج", + + // "form.no-value": "No value entered", + "form.no-value": "لم يتم إدخال أي قيمة", + + // "form.other-information.email": "Email", "form.other-information.email": "البريد الإلكتروني", + + // "form.other-information.first-name": "First Name", "form.other-information.first-name": "الاسم الأول", + + // "form.other-information.insolr": "In Solr Index", "form.other-information.insolr": "في فهرس سولر", + + // "form.other-information.institution": "Institution", "form.other-information.institution": "المؤسسة", + + // "form.other-information.last-name": "Last Name", "form.other-information.last-name": "اسم العائلة", + + // "form.other-information.orcid": "ORCID", "form.other-information.orcid": "أوركيد", + + // "form.remove": "Remove", "form.remove": "إزالة", + + // "form.save": "Save", "form.save": "حفظ", + + // "form.save-help": "Save changes", "form.save-help": "حفظ التغييرات", + + // "form.search": "Search", "form.search": "بحث", + + // "form.search-help": "Click here to look for an existing correspondence", "form.search-help": "انقر هنا للبحث عن المراسلات الحالية", + + // "form.submit": "Save", "form.submit": "حفظ", + + // "form.create": "Create", "form.create": "إنشاء", - "form.number-picker.decrement": "إن.قاص {{field}}", + + // "form.number-picker.decrement": "Decrement {{field}}", + "form.number-picker.decrement": "إنقاص {{field}}", + + // "form.number-picker.increment": "Increment {{field}}", "form.number-picker.increment": "زيادة {{field}}", + + // "form.repeatable.sort.tip": "Drop the item in the new position", "form.repeatable.sort.tip": "قم بإسقاط المادة في الموضع الجديد", - "grant-deny-request-copy.deny": "لا تهتم بقراءة", + + // "grant-deny-request-copy.deny": "Don't send copy", + "grant-deny-request-copy.deny": "لا تقم بإرسال نسخة", + + // "grant-deny-request-copy.email.back": "Back", "grant-deny-request-copy.email.back": "رجوع", + + // "grant-deny-request-copy.email.message": "Optional additional message", "grant-deny-request-copy.email.message": "رسالة إضافية اختيارية", - "grant-deny-request-copy.email.message.empty": "الرجاء إرسال الرسالة", - "grant-deny-request-copy.email.permissions.info": "يمكنك إلغاء هذه الطريقة لإلغاء النظر في الإلكترونيات للوصول إلى أكسفورد، وتقليل الاضطرار إلى الرد على هذه الطلبات. ", - "grant-deny-request-copy.email.permissions.label": "تغيير للوصول حر", + + // "grant-deny-request-copy.email.message.empty": "Please enter a message", + "grant-deny-request-copy.email.message.empty": "يرجى إدخال رسالة", + + // "grant-deny-request-copy.email.permissions.info": "You may use this occasion to reconsider the access restrictions on the document, to avoid having to respond to these requests. If you’d like to ask the repository administrators to remove these restrictions, please check the box below.", + "grant-deny-request-copy.email.permissions.info": "يمكنك استغلال هذه المناسبة لإعادة النظر في قيود الوصول على الوثيقة، لتجنب الاضطرار إلى الرد على هذه الطلبات. إذا كنت ترغب في مطالبة مديري المستودع بإزالة هذه القيود، فيرجى تحديد المربع أدناه.", + + // "grant-deny-request-copy.email.permissions.label": "Change to open access", + "grant-deny-request-copy.email.permissions.label": "تغيير إلى وصول حر", + + // "grant-deny-request-copy.email.send": "Send", "grant-deny-request-copy.email.send": "إرسال", + + // "grant-deny-request-copy.email.subject": "Subject", "grant-deny-request-copy.email.subject": "الموضوع", - "grant-deny-request-copy.email.subject.empty": "يرجى الإرسال موضوع", + + // "grant-deny-request-copy.email.subject.empty": "Please enter a subject", + "grant-deny-request-copy.email.subject.empty": "يرجى إدخال موضوع", + + // "grant-deny-request-copy.grant": "Send copy", "grant-deny-request-copy.grant": "إرسال نسخة", - "grant-deny-request-copy.header": "نسخة الطلب من أوكسلي", + + // "grant-deny-request-copy.header": "Document copy request", + "grant-deny-request-copy.header": "طلب نسخة من الوثيقة", + + // "grant-deny-request-copy.home-page": "Take me to the home page", "grant-deny-request-copy.home-page": "انتقل بي إلى الصفحة الرئيسية", - "grant-deny-request-copy.intro1": "إذا كنت أحد الكتبي في جامعة أكسفورد {{ name }}، يرجى استخدام أحد الخيارات أدناه للرد على طلب المستخدم.", - "grant-deny-request-copy.intro2": "بعد اختيار أحد الخيارات، سيُعرض عليك رسالة رد على آلية البريد الإلكتروني يمكنك تحريرها.", - "grant-deny-request-copy.processed": "تنفيذ هذا الطلب بالفعل. ", - "grant-request-copy.email.subject": "طلب نسخة من الوثيقة", + + // "grant-deny-request-copy.intro1": "If you are one of the authors of the document {{ name }}, then please use one of the options below to respond to the user's request.", + "grant-deny-request-copy.intro1": "إذا كنت أحد مؤلفي الوثيقة {{ name }}, فيرجى استخدام أحد الخيارات أدناه للرد على طلب المستخدم.", + + // "grant-deny-request-copy.intro2": "After choosing an option, you will be presented with a suggested email reply which you may edit.", + "grant-deny-request-copy.intro2": "بعد اختيار أحد الخيارات، سيُعرض عليك رسالة رد مقترحة بالبريد الإلكتروني يمكنك تحريرها.", + + // "grant-deny-request-copy.processed": "This request has already been processed. You can use the button below to get back to the home page.", + "grant-deny-request-copy.processed": "تمت معالجة هذا الطلب بالفعل. يمكنك استخدام الزر أدناه للعودة إلى الصفحة الرئيسية.", + + // "grant-request-copy.email.subject": "Request copy of document", + "grant-request-copy.email.subject": "طلب نسخة من وثيقة", + + // "grant-request-copy.error": "An error occurred", "grant-request-copy.error": "لقد حدث خطأ", - "grant-request-copy.header": "طلب منح نسخة من أوسكار", - "grant-request-copy.intro": "سيتم إرسال هذه الرسالة إلى مقدم الطلب. ", - "grant-request-copy.success": "تم تقديم المساعدة الفعالة", + + // "grant-request-copy.header": "Grant document copy request", + "grant-request-copy.header": "طلب منح نسخة من الوثيقة", + + // "grant-request-copy.intro": "A message will be sent to the applicant of the request. The requested document(s) will be attached.", + "grant-request-copy.intro": "سيتم إرسال هذه الرسالة إلى مقدم الطلب. وسيتم إرفاق الوثيقة المطلوبة.", + + // "grant-request-copy.success": "Successfully granted item request", + "grant-request-copy.success": "تم منح طلب المادة بنجاح", + + // "health.breadcrumbs": "Health", "health.breadcrumbs": "كشف الصحة", + + // "health-page.heading": "Health", "health-page.heading": "كشف الصحة", + + // "health-page.info-tab": "Info", "health-page.info-tab": "معلومات", + + // "health-page.status-tab": "Status", "health-page.status-tab": "الحالة", - "health-page.error.msg": "خدمة الكتاب العام غير المؤقت", + + // "health-page.error.msg": "The health check service is temporarily unavailable", + "health-page.error.msg": "خدمة الفحص الصحي غير متاحة مؤقتاً", + + // "health-page.property.status": "Status code", "health-page.property.status": "رمز الحالة", - "health-page.section.db.title": "قاعدة بيانات البيانات", + + // "health-page.section.db.title": "Database", + "health-page.section.db.title": "قاعدة البيانات", + + // "health-page.section.geoIp.title": "GeoIp", "health-page.section.geoIp.title": "GeoIp", + + // "health-page.section.solrAuthorityCore.title": "Solr: authority core", "health-page.section.solrAuthorityCore.title": "سولر: جوهر الاستناد", - "health-page.section.solrOaiCore.title": "سولر: جو أوي", + + // "health-page.section.solrOaiCore.title": "Solr: oai core", + "health-page.section.solrOaiCore.title": "سولر: جوهر oai", + + // "health-page.section.solrSearchCore.title": "Solr: search core", "health-page.section.solrSearchCore.title": "سولر: جوهر البحث", + + // "health-page.section.solrStatisticsCore.title": "Solr: statistics core", "health-page.section.solrStatisticsCore.title": "سولر: جوهر الإحصائيات", - "health-page.section-info.app.title": "النهاية", + + // "health-page.section-info.app.title": "Application Backend", + "health-page.section-info.app.title": "الواجهة الخلفية للتطبيق", + + // "health-page.section-info.java.title": "Java", "health-page.section-info.java.title": "جافا", + + // "health-page.status": "Status", "health-page.status": "الحالة", + + // "health-page.status.ok.info": "Operational", "health-page.status.ok.info": "تشغيلي", - "health-page.status.error.info": "تم كشف المشاكل", - "health-page.status.warning.info": "تم الكشف عن المشاكل الصغيرة", + + // "health-page.status.error.info": "Problems detected", + "health-page.status.error.info": "تم الكشف عن مشاكل", + + // "health-page.status.warning.info": "Possible issues detected", + "health-page.status.warning.info": "تم الكشف عن مشاكل محتملة", + + // "health-page.title": "Health", "health-page.title": "كشف الصحة", - "health-page.section.no-issues": "لم يتم اكتشاف أي شيء", + + // "health-page.section.no-issues": "No issues detected", + "health-page.section.no-issues": "لم يتم اكتشاف أي مشكلات", + + // "home.description": "", "home.description": "", + + // "home.breadcrumbs": "Home", "home.breadcrumbs": "الرئيسية", - "home.search-form.placeholder": "بحث المستودع...", + + // "home.search-form.placeholder": "Search the repository ...", + "home.search-form.placeholder": "بحث المستودع ...", + + // "home.title": "Home", "home.title": "الرئيسية", + + // "home.top-level-communities.head": "Communities in DSpace", "home.top-level-communities.head": "المجتمعات في دي سبيس", - "home.top-level-communities.help": "هيا مجتمع لاستعراض مستحضراته.", - "info.end-user-agreement.accept": "لقد قمت بقراءة المنتج النهائي ووافقت عليه", - "info.end-user-agreement.accept.error": "حدث خطأ أثناء استخدام الاستخدام النهائي", - "info.end-user-agreement.accept.success": "تم تحديث الاستخدام النهائي بشكل فعال", - "info.end-user-agreement.breadcrumbs": "الاستخدام النهائي", + + // "home.top-level-communities.help": "Select a community to browse its collections.", + "home.top-level-communities.help": "قم بتحديد مجتمع لاستعراض حاوياته.", + + // "info.end-user-agreement.accept": "I have read and I agree to the End User Agreement", + "info.end-user-agreement.accept": "لقد قمت بقراءة اتفاقية المستخدم النهائي وأوافق عليها", + + // "info.end-user-agreement.accept.error": "An error occurred accepting the End User Agreement", + "info.end-user-agreement.accept.error": "حدث خطأ أثناء قبول اتفاقية المستخدم النهائي", + + // "info.end-user-agreement.accept.success": "Successfully updated the End User Agreement", + "info.end-user-agreement.accept.success": "تم بنجاح تحديث اتفاقية المستخدم النهائي", + + // "info.end-user-agreement.breadcrumbs": "End User Agreement", + "info.end-user-agreement.breadcrumbs": "اتفاقية المستخدم النهائي", + + // "info.end-user-agreement.buttons.cancel": "Cancel", "info.end-user-agreement.buttons.cancel": "إلغاء", + + // "info.end-user-agreement.buttons.save": "Save", "info.end-user-agreement.buttons.save": "حفظ", - "info.end-user-agreement.head": "الاستخدام النهائي", - "info.end-user-agreement.title": "الاستخدام النهائي", + + // "info.end-user-agreement.head": "End User Agreement", + "info.end-user-agreement.head": "اتفاقية المستخدم النهائي", + + // "info.end-user-agreement.title": "End User Agreement", + "info.end-user-agreement.title": "اتفاقية المستخدم النهائي", + + // "info.end-user-agreement.hosting-country": "the United States", "info.end-user-agreement.hosting-country": "الولايات المتحدة", + + // "info.privacy.breadcrumbs": "Privacy Statement", "info.privacy.breadcrumbs": "بيان الخصوصية", + + // "info.privacy.head": "Privacy Statement", "info.privacy.head": "بيان الخصوصية", + + // "info.privacy.title": "Privacy Statement", "info.privacy.title": "بيان الخصوصية", - "info.feedback.breadcrumbs": "مراجعة", - "info.feedback.head": "مراجعة", - "info.feedback.title": "مراجعة", - "info.feedback.info": "شكراً لمشاركتنا آراءك حول نظام دي سبيس. ", - "info.feedback.email_help": "سيتم استخدام هذا البريد الالكتروني لمتابعة بياناتك.", - "info.feedback.send": "قم بزيارة تعليقاتك", + + // "info.feedback.breadcrumbs": "Feedback", + "info.feedback.breadcrumbs": "ملاحظات", + + // "info.feedback.head": "Feedback", + "info.feedback.head": "ملاحظات", + + // "info.feedback.title": "Feedback", + "info.feedback.title": "ملاحظات", + + // "info.feedback.info": "Thanks for sharing your feedback about the DSpace system. Your comments are appreciated!", + "info.feedback.info": "شكراً لمشاركتنا ملاحظاتك حول نظام دي سبيس. نقدر تعليقاتكم!", + + // "info.feedback.email_help": "This address will be used to follow up on your feedback.", + "info.feedback.email_help": "سيتم استخدام هذا البريد الالكتروني لمتابعة ملاحظاتك.", + + // "info.feedback.send": "Send Feedback", + "info.feedback.send": "قم بإرسال ملاحظاتك", + + // "info.feedback.comments": "Comments", "info.feedback.comments": "تعليقات", + + // "info.feedback.email-label": "Your Email", "info.feedback.email-label": "البريد الإلكتروني الخاص بك", - "info.feedback.create.success": "تم تحفيزه بشكل فعال!", - "info.feedback.error.email.required": "مطلوب عنوان بريد الإلكتروني صالح", + + // "info.feedback.create.success": "Feedback Sent Successfully!", + "info.feedback.create.success": "تم إرسال الملاحظات بنجاح!", + + // "info.feedback.error.email.required": "A valid email address is required", + "info.feedback.error.email.required": "مطلوب عنوان بريد إلكتروني صالح", + + // "info.feedback.error.message.required": "A comment is required", "info.feedback.error.message.required": "مطلوب تعليق", + + // "info.feedback.page-label": "Page", "info.feedback.page-label": "صفحة", + + // "info.feedback.page_help": "The page related to your feedback", "info.feedback.page_help": "الصفحة ذات الصلة بملاحظاتك", - "info.coar-notify-support.title": "COAR إخطار الدعم", - "info.coar-notify-support.breadcrumbs": "COAR إخطار الدعم", + + // "info.coar-notify-support.title": "COAR Notify Support", + // TODO New key - Add a translation + "info.coar-notify-support.title": "COAR Notify Support", + + // "info.coar-notify-support.breadcrumbs": "COAR Notify Support", + // TODO New key - Add a translation + "info.coar-notify-support.breadcrumbs": "COAR Notify Support", + + // "item.alerts.private": "This item is non-discoverable", "item.alerts.private": "هذه المادة غير قابلة للاكتشاف", + + // "item.alerts.withdrawn": "This item has been withdrawn", "item.alerts.withdrawn": "تم سحب هذه المادة", - "item.alerts.reinstate-request": "طلب إعادة", - "quality-assurance.event.table.person-who-requested": "بتوصية من", - "item.edit.authorizations.heading": "باستخدام هذا المحرر، يمكنك عرض تغيير سياساتنا، بالإضافة إلى تغيير سياسات عناصر العناصر: الحزم والبنية. ", - "item.edit.authorizations.title": "تحرير سياسة المادة", - "item.badge.private": "غير للاكتشاف", + + // "item.alerts.reinstate-request": "Request reinstate", + // TODO New key - Add a translation + "item.alerts.reinstate-request": "Request reinstate", + + // "quality-assurance.event.table.person-who-requested": "Requested by", + // TODO New key - Add a translation + "quality-assurance.event.table.person-who-requested": "Requested by", + + // "item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.", + "item.edit.authorizations.heading": "باستخدام هذا المحرر ، يمكنك عرض وتغيير سياسات مادة ما، بالإضافة إلى تغيير سياسات مكونات المادة الفردية: الحزم وتدفق البت. باختصار، المادة عبارة عن حاوية من الحزم، والحزم عبارة عن حاويات لتدفقات البت. للحاويات في المعتاد سياسات ADD/REMOVE/READ/WRITE ، بينما يكون لتدفقات البت سياسات READ/WRITE فقط.", + + // "item.edit.authorizations.title": "Edit item's Policies", + "item.edit.authorizations.title": "تحرير سياسات المادة", + + // "item.badge.private": "Non-discoverable", + "item.badge.private": "غير قابل للاكتشاف", + + // "item.badge.withdrawn": "Withdrawn", "item.badge.withdrawn": "مسحوب", + + // "item.bitstreams.upload.bundle": "Bundle", "item.bitstreams.upload.bundle": "الحزمة", - "item.bitstreams.upload.bundle.placeholder": "قم بالضغط على حزمة أو تسجيل اسم حزمة جديدة", + + // "item.bitstreams.upload.bundle.placeholder": "Select a bundle or input new bundle name", + "item.bitstreams.upload.bundle.placeholder": "قم بتحديد حزمة أو إدخال اسم حزمة جديدة", + + // "item.bitstreams.upload.bundle.new": "Create bundle", "item.bitstreams.upload.bundle.new": "إنشاء حزمة", - "item.bitstreams.upload.bundles.empty": "لا تحتوي على هذه المادة على أي حزم لتحميل تدفقات البت لها.", + + // "item.bitstreams.upload.bundles.empty": "This item doesn't contain any bundles to upload a bitstream to.", + "item.bitstreams.upload.bundles.empty": "لا تحتوي هذه المادة على أية حزم لتحميل تدفقات البت لها.", + + // "item.bitstreams.upload.cancel": "Cancel", "item.bitstreams.upload.cancel": "إلغاء", - "item.bitstreams.upload.drop-message": "قم بإسقاط ملف PDFه", + + // "item.bitstreams.upload.drop-message": "Drop a file to upload", + "item.bitstreams.upload.drop-message": "قم بإسقاط ملف لتحميله", + + // "item.bitstreams.upload.item": "Item: ", "item.bitstreams.upload.item": "المواد: ", - "item.bitstreams.upload.notifications.bundle.created.content": "تم إنشاء حزمة جديدة وفعالة.", - "item.bitstreams.upload.notifications.bundle.created.title": "الحزمة التي تم تحديدها", - "item.bitstreams.upload.notifications.upload.failed": "فشل التحميل. ", + + // "item.bitstreams.upload.notifications.bundle.created.content": "Successfully created new bundle.", + "item.bitstreams.upload.notifications.bundle.created.content": "تم إنشاء حزمة جديدة بنجاح.", + + // "item.bitstreams.upload.notifications.bundle.created.title": "Created bundle", + "item.bitstreams.upload.notifications.bundle.created.title": "الحزمة التي تم إنشاؤها", + + // "item.bitstreams.upload.notifications.upload.failed": "Upload failed. Please verify the content before retrying.", + "item.bitstreams.upload.notifications.upload.failed": "فشل التحميل. يرجى التحقق من المحتوى قبل إعادة المحاولة.", + + // "item.bitstreams.upload.title": "Upload bitstream", "item.bitstreams.upload.title": "تحميل تدفق البت", + + // "item.edit.bitstreams.bundle.edit.buttons.upload": "Upload", "item.edit.bitstreams.bundle.edit.buttons.upload": "تحميل", - "item.edit.bitstreams.bundle.displaying": "يتم العرض حاليًا {{ amount }} تدفقات بت من {{ total }}.", + + // "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", + "item.edit.bitstreams.bundle.displaying": "يتم حالياً عرض {{ amount }} تدفقات بت من {{ total }}.", + + // "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", "item.edit.bitstreams.bundle.load.all": "تحميل الكل ({{ total }})", + + // "item.edit.bitstreams.bundle.load.more": "Load more", "item.edit.bitstreams.bundle.load.more": "تحميل المزيد", - "item.edit.bitstreams.bundle.name": "الصندوق: {{ name }}", - "item.edit.bitstreams.discard-button": "لا", + + // "item.edit.bitstreams.bundle.name": "BUNDLE: {{ name }}", + "item.edit.bitstreams.bundle.name": "الحزمة: {{ name }}", + + // "item.edit.bitstreams.discard-button": "Discard", + "item.edit.bitstreams.discard-button": "تجاهل", + + // "item.edit.bitstreams.edit.buttons.download": "Download", "item.edit.bitstreams.edit.buttons.download": "تنزيل", - "item.edit.bitstreams.edit.buttons.drag": "يسحب", + + // "item.edit.bitstreams.edit.buttons.drag": "Drag", + "item.edit.bitstreams.edit.buttons.drag": "سحب", + + // "item.edit.bitstreams.edit.buttons.edit": "Edit", "item.edit.bitstreams.edit.buttons.edit": "تحرير", + + // "item.edit.bitstreams.edit.buttons.remove": "Remove", "item.edit.bitstreams.edit.buttons.remove": "إزالة", - "item.edit.bitstreams.edit.buttons.undo": "الحكمة عن التغييرات", - "item.edit.bitstreams.empty": "لا تحتوي على هذه المادة على أي تدفقات بت. ", + + // "item.edit.bitstreams.edit.buttons.undo": "Undo changes", + "item.edit.bitstreams.edit.buttons.undo": "التراجع عن التغييرات", + + // "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", + "item.edit.bitstreams.empty": "لا تحتوي هذه المادة على أية تدفقات بت. انقر على زر التحميل لإنشاء واحد.", + + // "item.edit.bitstreams.headers.actions": "Actions", "item.edit.bitstreams.headers.actions": "إجراءات", + + // "item.edit.bitstreams.headers.bundle": "Bundle", "item.edit.bitstreams.headers.bundle": "الحزمة", + + // "item.edit.bitstreams.headers.description": "Description", "item.edit.bitstreams.headers.description": "الوصف", - "item.edit.bitstreams.headers.format": "حتى", + + // "item.edit.bitstreams.headers.format": "Format", + "item.edit.bitstreams.headers.format": "التنسيق", + + // "item.edit.bitstreams.headers.name": "Name", "item.edit.bitstreams.headers.name": "الاسم", - "item.edit.bitstreams.notifications.discarded.content": "تم تجاهل تجاهلك. ", + + // "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.bitstreams.notifications.discarded.content": "تم تجاهل تغييراتك. لإعادة تعيين تغييراتك قم بالنقر على زر 'تراجع'", + + // "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", "item.edit.bitstreams.notifications.discarded.title": "تم تجاهل التغييرات", + + // "item.edit.bitstreams.notifications.move.failed.title": "Error moving bitstreams", "item.edit.bitstreams.notifications.move.failed.title": "خطأ أثناء نقل تدفقات البت", - "item.edit.bitstreams.notifications.move.saved.content": "تم حفظ التطورات الجديدة بك على حزم وتدفقات بت هذه المادة.", - "item.edit.bitstreams.notifications.move.saved.title": "تم الحفاظ على التطورات الجديدة", - "item.edit.bitstreams.notifications.outdated.content": "المادة التي تعمل بها حاليًا تم تغييرها بواسطة مستخدم آخر. ", - "item.edit.bitstreams.notifications.outdated.title": "اختر التغييرات", - "item.edit.bitstreams.notifications.remove.failed.title": "حدث خطأ أثناء حذف تدفق البت", - "item.edit.bitstreams.notifications.remove.saved.content": "تم حفظ التغييرات الخاصة بك على تدفقات بت هذه المادة.", - "item.edit.bitstreams.notifications.remove.saved.title": "تم حفظ التغييرات الإزالة", - "item.edit.bitstreams.reinstate-button": "ديب", + + // "item.edit.bitstreams.notifications.move.saved.content": "Your move changes to this item's bitstreams and bundles have been saved.", + "item.edit.bitstreams.notifications.move.saved.content": "تم حفظ تغييرات النقل الخاصة بك على حزم وتدفقات بت هذه المادة.", + + // "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", + "item.edit.bitstreams.notifications.move.saved.title": "تم حفظ تغييرات النقل", + + // "item.edit.bitstreams.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + "item.edit.bitstreams.notifications.outdated.content": "المادة التي تعمل عليها حالياً تم تغييرها بواسطة مستخدم آخر. تم تجاهل تغييراتك الحالية لتجنب التعارض", + + // "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", + "item.edit.bitstreams.notifications.outdated.title": "انتهت صلاحية التغييرات", + + // "item.edit.bitstreams.notifications.remove.failed.title": "Error deleting bitstream", + "item.edit.bitstreams.notifications.remove.failed.title": "خطأ أثناء حذف تدفق البت", + + // "item.edit.bitstreams.notifications.remove.saved.content": "Your removal changes to this item's bitstreams have been saved.", + "item.edit.bitstreams.notifications.remove.saved.content": "تم حفظ تغييرات الإزالة الخاصة بك على تدفقات بت هذه المادة.", + + // "item.edit.bitstreams.notifications.remove.saved.title": "Removal changes saved", + "item.edit.bitstreams.notifications.remove.saved.title": "تم حفظ تغييرات الإزالة", + + // "item.edit.bitstreams.reinstate-button": "Undo", + "item.edit.bitstreams.reinstate-button": "تراجع", + + // "item.edit.bitstreams.save-button": "Save", "item.edit.bitstreams.save-button": "حفظ", + + // "item.edit.bitstreams.upload-button": "Upload", "item.edit.bitstreams.upload-button": "تحميل", + + // "item.edit.delete.cancel": "Cancel", "item.edit.delete.cancel": "إلغاء", + + // "item.edit.delete.confirm": "Delete", "item.edit.delete.confirm": "حذف", - "item.edit.delete.description": "هل أنت متأكد من حذف هذه المادة التجارية؟ ", + + // "item.edit.delete.description": "Are you sure this item should be completely deleted? Caution: At present, no tombstone would be left.", + "item.edit.delete.description": "هل أنت متأكد من حذف هذه المادة تماماً؟ تحذير: في الوقت الحالي لن تتبقى أي آثار.", + + // "item.edit.delete.error": "An error occurred while deleting the item", "item.edit.delete.error": "حدث خطأ أثناء حذف المادة", + + // "item.edit.delete.header": "Delete item: {{ id }}", "item.edit.delete.header": "حذف المادة: {{ id }}", + + // "item.edit.delete.success": "The item has been deleted", "item.edit.delete.success": "تم حذف هذه المادة", + + // "item.edit.head": "Edit Item", "item.edit.head": "تحرير المادة", + + // "item.edit.breadcrumbs": "Edit Item", "item.edit.breadcrumbs": "تحرير المادة", + + // "item.edit.tabs.disabled.tooltip": "You're not authorized to access this tab", "item.edit.tabs.disabled.tooltip": "غير مصرح لك بالوصول إلى هذا التبويب", - "item.edit.tabs.mapper.head": "خطة مخططة", - "item.edit.tabs.item-mapper.title": "تحرير المادة - مخطط الغذاء", + + // "item.edit.tabs.mapper.head": "Collection Mapper", + "item.edit.tabs.mapper.head": "مخطط الحاوية", + + // "item.edit.tabs.item-mapper.title": "Item Edit - Collection Mapper", + "item.edit.tabs.item-mapper.title": "تحرير المادة - مخطط الحاوية", + + // "item.edit.identifiers.doi.status.UNKNOWN": "Unknown", "item.edit.identifiers.doi.status.UNKNOWN": "غير معروف", - "item.edit.identifiers.doi.status.TO_BE_REGISTERED": "في قائمة الانتظار للتشغيل", + + // "item.edit.identifiers.doi.status.TO_BE_REGISTERED": "Queued for registration", + "item.edit.identifiers.doi.status.TO_BE_REGISTERED": "في قائمة الانتظار للتسجيل", + + // "item.edit.identifiers.doi.status.TO_BE_RESERVED": "Queued for reservation", "item.edit.identifiers.doi.status.TO_BE_RESERVED": "في قائمة الانتظار للحجز", + + // "item.edit.identifiers.doi.status.IS_REGISTERED": "Registered", "item.edit.identifiers.doi.status.IS_REGISTERED": "مسجل", + + // "item.edit.identifiers.doi.status.IS_RESERVED": "Reserved", "item.edit.identifiers.doi.status.IS_RESERVED": "محجوز", + + // "item.edit.identifiers.doi.status.UPDATE_RESERVED": "Reserved (update queued)", "item.edit.identifiers.doi.status.UPDATE_RESERVED": "محجوز (تحديث قائمة الانتظار)", + + // "item.edit.identifiers.doi.status.UPDATE_REGISTERED": "Registered (update queued)", "item.edit.identifiers.doi.status.UPDATE_REGISTERED": "مسجل (تحديث قائمة الانتظار)", + + // "item.edit.identifiers.doi.status.UPDATE_BEFORE_REGISTRATION": "Queued for update and registration", "item.edit.identifiers.doi.status.UPDATE_BEFORE_REGISTRATION": "في قائمة الانتظار للتحديث والتسجيل", + + // "item.edit.identifiers.doi.status.TO_BE_DELETED": "Queued for deletion", "item.edit.identifiers.doi.status.TO_BE_DELETED": "في قائمة الانتظار للحذف", + + // "item.edit.identifiers.doi.status.DELETED": "Deleted", "item.edit.identifiers.doi.status.DELETED": "تم الحذف", + + // "item.edit.identifiers.doi.status.PENDING": "Pending (not registered)", "item.edit.identifiers.doi.status.PENDING": "في الانتظار (غير مسجل)", + + // "item.edit.identifiers.doi.status.MINTED": "Minted (not registered)", "item.edit.identifiers.doi.status.MINTED": "مسكوك (غير مسجل)", - "item.edit.tabs.status.buttons.register-doi.label": "تسجيل الكائن المعرفي الرقمي الجديد أو في الانتظار", - "item.edit.tabs.status.buttons.register-doi.button": "تسجيل الهوية الرقمية...", - "item.edit.register-doi.header": "تسجيل الكائن المعرفي الرقمي الجديد أو في الانتظار", - "item.edit.register-doi.description": "قم بمراجعة أي معرفات في الانتظار وميتاداتا المادة أدناه والنقر المؤكد على متابعة تسجيل المعرفة الرقمية، أو إلغاء القفل للتراجع", - "item.edit.register-doi.confirm": "بالتأكيد", + + // "item.edit.tabs.status.buttons.register-doi.label": "Register a new or pending DOI", + "item.edit.tabs.status.buttons.register-doi.label": "تسجيل معرف كائن رقمي جديد أو في الانتظار", + + // "item.edit.tabs.status.buttons.register-doi.button": "Register DOI...", + "item.edit.tabs.status.buttons.register-doi.button": "تسجيل معرف كائن رقمي...", + + // "item.edit.register-doi.header": "Register a new or pending DOI", + "item.edit.register-doi.header": "تسجيل معرف كائن رقمي جديد أو في الانتظار", + + // "item.edit.register-doi.description": "Review any pending identifiers and item metadata below and click Confirm to proceed with DOI registration, or Cancel to back out", + "item.edit.register-doi.description": "قم بمراجعة أي معرفات في الانتظار وميتاداتا المادة أدناه والنقر على تأكيد لمتابعة تسجيل معرف الكائن الرقمي، أو إلغاء للتراجع", + + // "item.edit.register-doi.confirm": "Confirm", + "item.edit.register-doi.confirm": "تأكيد", + + // "item.edit.register-doi.cancel": "Cancel", "item.edit.register-doi.cancel": "إلغاء", - "item.edit.register-doi.success": "تم وضع الإعدادات الرقمية في قائمة الانتظار الفعالة.", - "item.edit.register-doi.error": "خطأ في تسجيل المدخلات الرقمية", - "item.edit.register-doi.to-update": "لقد تم بالفعل إنشاء المفتاح الرقمي التالي ووضعه في قائمة الانتظار للتشغيل عبر الإنترنت", - "item.edit.item-mapper.buttons.add": "تخطيط المادة إلى مادة محددة", + + // "item.edit.register-doi.success": "DOI queued for registration successfully.", + "item.edit.register-doi.success": "تم وضع معرف الكائن الرقمي في قائمة الانتظار للتسجيل بنجاح.", + + // "item.edit.register-doi.error": "Error registering DOI", + "item.edit.register-doi.error": "خطأ في تسجيل معرف الكائن الرقمي", + + // "item.edit.register-doi.to-update": "The following DOI has already been minted and will be queued for registration online", + "item.edit.register-doi.to-update": "لقد تم بالفعل سك معرف الكائن الرقمي التالي وسيتم وضعه في قائمة الانتظار للتسجيل عبر الإنترنت", + + // "item.edit.item-mapper.buttons.add": "Map item to selected collections", + "item.edit.item-mapper.buttons.add": "تخطيط مادة إلى حاويات محددة", + + // "item.edit.item-mapper.buttons.remove": "Remove item's mapping for selected collections", "item.edit.item-mapper.buttons.remove": "إزالة تحطيط مادة لحاويات محددة", + + // "item.edit.item-mapper.cancel": "Cancel", "item.edit.item-mapper.cancel": "إلغاء", - "item.edit.item-mapper.description": "هذه أداة مخططة للمادة التي بدأت لمديرين تخطيط هذه المادة لتوثيق أخرى. ", - "item.edit.item-mapper.head": "المادة - تخطيط المادة إلى مادة الفينيل", + + // "item.edit.item-mapper.description": "This is the item mapper tool that allows administrators to map this item to other collections. You can search for collections and map them, or browse the list of collections the item is currently mapped to.", + "item.edit.item-mapper.description": "هذه أداة مخطط المادة التي تتيح للمديرين تخطيط هذه المادة إلى حاويات أخرى. يمكنك البحث عن الحاويات وتخطيطها، أو استعراض قائمة بالحاويات التي تم تخطيط هذه المادة لها حالياً.", + + // "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", + "item.edit.item-mapper.head": "مخطط المادة - تخطيط مادة إلى حاويات", + + // "item.edit.item-mapper.item": "Item: \"{{name}}\"", "item.edit.item-mapper.item": "المادة: \"{{name}}\"", - "item.edit.item-mapper.no-search": "يرجى الاتصال باستعلام للبحث", - "item.edit.item-mapper.notifications.add.error.content": "أحدث الأخطاء أثناء تخطيط المادة إلى {{amount}} حاوية.", + + // "item.edit.item-mapper.no-search": "Please enter a query to search", + "item.edit.item-mapper.no-search": "يرجى إدخال استعلام للبحث", + + // "item.edit.item-mapper.notifications.add.error.content": "Errors occurred for mapping of item to {{amount}} collections.", + "item.edit.item-mapper.notifications.add.error.content": "حدثت أخطاء أثناء تخطيط مادة إلى {{amount}} حاوية.", + + // "item.edit.item-mapper.notifications.add.error.head": "Mapping errors", "item.edit.item-mapper.notifications.add.error.head": "أخطاء التخطيط", - "item.edit.item-mapper.notifications.add.success.content": "تم تخطيط المادة {{amount}} حاوية فعالة.", + + // "item.edit.item-mapper.notifications.add.success.content": "Successfully mapped item to {{amount}} collections.", + "item.edit.item-mapper.notifications.add.success.content": "تم تخطيط المادة إلى {{amount}} حاوية بنجاح.", + + // "item.edit.item-mapper.notifications.add.success.head": "Mapping completed", "item.edit.item-mapper.notifications.add.success.head": "اكتمل التخطيط", - "item.edit.item-mapper.notifications.remove.error.content": "أخطاء أثناء إزالة التخطيط إلى {{amount}} حاوية.", + + // "item.edit.item-mapper.notifications.remove.error.content": "Errors occurred for the removal of the mapping to {{amount}} collections.", + "item.edit.item-mapper.notifications.remove.error.content": "حدثت أخطاء أثناء إزالة التخطيط إلى {{amount}} حاوية.", + + // "item.edit.item-mapper.notifications.remove.error.head": "Removal of mapping errors", "item.edit.item-mapper.notifications.remove.error.head": "أخطاء إزالة التخطيط", - "item.edit.item-mapper.notifications.remove.success.content": "بعد إزالة تخطيط المادة {{amount}} حاوية فعالة.", + + // "item.edit.item-mapper.notifications.remove.success.content": "Successfully removed mapping of item to {{amount}} collections.", + "item.edit.item-mapper.notifications.remove.success.content": "تمت إزالة تخطيط المادة إلى {{amount}} حاوية بنجاح.", + + // "item.edit.item-mapper.notifications.remove.success.head": "Removal of mapping completed", "item.edit.item-mapper.notifications.remove.success.head": "اكتملت إزالة التخطيط", - "item.edit.item-mapper.search-form.placeholder": "بحث مقبول...", - "item.edit.item-mapper.tabs.browse": "تم الاسترجاع المؤجل", - "item.edit.item-mapper.tabs.map": "تخطيط وثيقة جديدة", + + // "item.edit.item-mapper.search-form.placeholder": "Search collections...", + "item.edit.item-mapper.search-form.placeholder": "بحث الحاويات...", + + // "item.edit.item-mapper.tabs.browse": "Browse mapped collections", + "item.edit.item-mapper.tabs.browse": "استعراض الحاويات المخططة", + + // "item.edit.item-mapper.tabs.map": "Map new collections", + "item.edit.item-mapper.tabs.map": "تخطيط حاويات جديدة", + + // "item.edit.metadata.add-button": "Add", "item.edit.metadata.add-button": "إضافة", - "item.edit.metadata.discard-button": "لا", + + // "item.edit.metadata.discard-button": "Discard", + "item.edit.metadata.discard-button": "تجاهل", + + // "item.edit.metadata.edit.language": "Edit language", "item.edit.metadata.edit.language": "تحرير اللغة", + + // "item.edit.metadata.edit.value": "Edit value", "item.edit.metadata.edit.value": "تحرير القيمة", - "item.edit.metadata.edit.authority.key": "تحرير مفتاح السلطة", - "item.edit.metadata.edit.buttons.confirm": "بالتأكيد", - "item.edit.metadata.edit.buttons.drag": "احصل على إعادة الترتيب", + + // "item.edit.metadata.edit.authority.key": "Edit authority key", + // TODO New key - Add a translation + "item.edit.metadata.edit.authority.key": "Edit authority key", + + // "item.edit.metadata.edit.buttons.confirm": "Confirm", + "item.edit.metadata.edit.buttons.confirm": "تأكيد", + + // "item.edit.metadata.edit.buttons.drag": "Drag to reorder", + "item.edit.metadata.edit.buttons.drag": "اسحب لإعادة ترتيب", + + // "item.edit.metadata.edit.buttons.edit": "Edit", "item.edit.metadata.edit.buttons.edit": "تحرير", + + // "item.edit.metadata.edit.buttons.remove": "Remove", "item.edit.metadata.edit.buttons.remove": "إزالة", - "item.edit.metadata.edit.buttons.undo": "انقلب عن التغييرات", + + // "item.edit.metadata.edit.buttons.undo": "Undo changes", + "item.edit.metadata.edit.buttons.undo": "تراجع عن التغييرات", + + // "item.edit.metadata.edit.buttons.unedit": "Stop editing", "item.edit.metadata.edit.buttons.unedit": "توقف عن التحرير", - "item.edit.metadata.edit.buttons.virtual": "هذه القيمة ميتا افتراضية، أي قيمة موروثة من كينونة ذات صلة. ", - "item.edit.metadata.empty": "لا تحتوي المادة حاليا على أي ميتاداتا. ", + + // "item.edit.metadata.edit.buttons.virtual": "This is a virtual metadata value, i.e. a value inherited from a related entity. It can’t be modified directly. Add or remove the corresponding relationship in the \"Relationships\" tab", + "item.edit.metadata.edit.buttons.virtual": "هذه قيمة ميتاداتا افتراضية، أي قيمة موروثة من كينونة ذات صلة. ولا يمكن تعديلها مباشرة. إضافة أو إزالة العلاقة المقابلة في تبويب \"العلاقات\" ", + + // "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", + "item.edit.metadata.empty": "لا تحتوي المادة حاليًا على أي ميتاداتا. انقر فوق إضافة لبدء إضافة قيمة ميتاداتا.", + + // "item.edit.metadata.headers.edit": "Edit", "item.edit.metadata.headers.edit": "تحرير", - "item.edit.metadata.headers.field": "حقل", + + // "item.edit.metadata.headers.field": "Field", + "item.edit.metadata.headers.field": "الحقل", + + // "item.edit.metadata.headers.language": "Lang", "item.edit.metadata.headers.language": "اللغة", + + // "item.edit.metadata.headers.value": "Value", "item.edit.metadata.headers.value": "القيمة", + + // "item.edit.metadata.metadatafield": "Edit field", "item.edit.metadata.metadatafield": "تحرير الحقل", - "item.edit.metadata.metadatafield.error": "حدث خطأ أثناء التحقق من صحة البحث في الميتاداتا", - "item.edit.metadata.metadatafield.invalid": "يرجى اختيار البحث ميتاداتا صالح", - "item.edit.metadata.notifications.discarded.content": "تم تجاهل تجاهلك. ", + + // "item.edit.metadata.metadatafield.error": "An error occurred validating the metadata field", + "item.edit.metadata.metadatafield.error": "حدث خطأ أثناء التحقق من صحة حقل الميتاداتا", + + // "item.edit.metadata.metadatafield.invalid": "Please choose a valid metadata field", + "item.edit.metadata.metadatafield.invalid": "يرجى اختيار حقل ميتاداتا صالح", + + // "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.metadata.notifications.discarded.content": "تم تجاهل تغييراتك. لإعادة تعيين التغييرات قم بالنقر على زر 'تراجع'", + + // "item.edit.metadata.notifications.discarded.title": "Changes discarded", "item.edit.metadata.notifications.discarded.title": "تم تجاهل التغييرات", + + // "item.edit.metadata.notifications.error.title": "An error occurred", "item.edit.metadata.notifications.error.title": "لقد حدث خطأ", - "item.edit.metadata.notifications.invalid.content": "لم يتم الحفاظ على جديدك. ", - "item.edit.metadata.notifications.invalid.title": "دياداتا غير صالحة", - "item.edit.metadata.notifications.outdated.content": "المادة التي تعمل بها حاليًا تم تغييرها بواسطة مستخدم آخر. ", - "item.edit.metadata.notifications.outdated.title": "اختر التغييرات", - "item.edit.metadata.notifications.saved.content": "تم الحفاظ على نقصانك في ميتاداتا لهذه المادة.", + + // "item.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + "item.edit.metadata.notifications.invalid.content": "لم يتم حفظ تغييراتك. يرجى التأكد من صحة جميع الحقول قبل الحفظ.", + + // "item.edit.metadata.notifications.invalid.title": "Metadata invalid", + "item.edit.metadata.notifications.invalid.title": "الميتاداتا غير صالحة", + + // "item.edit.metadata.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + "item.edit.metadata.notifications.outdated.content": "المادة التي تعمل عليها حالياً تم تغييرها بواسطة مستخدم آخر. تم تجاهل تغييراتك الحالية لتجنب التعارض", + + // "item.edit.metadata.notifications.outdated.title": "Changes outdated", + "item.edit.metadata.notifications.outdated.title": "انتهت صلاحية التغييرات", + + // "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", + "item.edit.metadata.notifications.saved.content": "تم حفظ تغييراتك على ميتاداتا هذه المادة.", + + // "item.edit.metadata.notifications.saved.title": "Metadata saved", "item.edit.metadata.notifications.saved.title": "تم حفظ الميتاداتا", - "item.edit.metadata.reinstate-button": "ديب", - "item.edit.metadata.reset-order-button": "انعكاس عن إعادة الترتيب", + + // "item.edit.metadata.reinstate-button": "Undo", + "item.edit.metadata.reinstate-button": "تراجع", + + // "item.edit.metadata.reset-order-button": "Undo reorder", + "item.edit.metadata.reset-order-button": "تراجع عن إعادة الترتيب", + + // "item.edit.metadata.save-button": "Save", "item.edit.metadata.save-button": "حفظ", - "item.edit.metadata.authority.label": "سلطة: ", - "item.edit.metadata.edit.buttons.open-authority-edition": "افتح قيمة مفتاح السلطة للتحرير اليدوي", - "item.edit.metadata.edit.buttons.close-authority-edition": "قفل قيمة مفتاح السلطة للتحرير اليدوي", - "item.edit.modify.overview.field": "بحث متقدم", + + // "item.edit.metadata.authority.label": "Authority: ", + // TODO New key - Add a translation + "item.edit.metadata.authority.label": "Authority: ", + + // "item.edit.metadata.edit.buttons.open-authority-edition": "Unlock the authority key value for manual editing", + // TODO New key - Add a translation + "item.edit.metadata.edit.buttons.open-authority-edition": "Unlock the authority key value for manual editing", + + // "item.edit.metadata.edit.buttons.close-authority-edition": "Lock the authority key value for manual editing", + // TODO New key - Add a translation + "item.edit.metadata.edit.buttons.close-authority-edition": "Lock the authority key value for manual editing", + + // "item.edit.modify.overview.field": "Field", + "item.edit.modify.overview.field": "حقل", + + // "item.edit.modify.overview.language": "Language", "item.edit.modify.overview.language": "اللغة", - "item.edit.modify.overview.value": "القيمة", + + // "item.edit.modify.overview.value": "Value", + "item.edit.modify.overview.value": "قيمة", + + // "item.edit.move.cancel": "Back", "item.edit.move.cancel": "رجوع", + + // "item.edit.move.save-button": "Save", "item.edit.move.save-button": "حفظ", - "item.edit.move.discard-button": "لا", - "item.edit.move.description": "اختر ما تريد في نقل هذه المادة لها. ", + + // "item.edit.move.discard-button": "Discard", + "item.edit.move.discard-button": "تجاهل", + + // "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", + "item.edit.move.description": "اختر الحاوية التي ترغب في نقل هذه المادة لها. لتضييق قائمة الحاويات المعروضة، يمكنك إدخال استعلام بحث في المربع.", + + // "item.edit.move.error": "An error occurred when attempting to move the item", "item.edit.move.error": "حدث خطأ أثناء محاولة نقل المادة", - "item.edit.move.head": "المادة: {{id}}", - "item.edit.move.inheritpolicies.checkbox": "توريث", - "item.edit.move.inheritpolicies.description": "توريث خصيصاً للضوءية", - "item.edit.move.inheritpolicies.tooltip": "تحذير: عند التفعيل، ستستبدل سيجروم الوصول للقراءة الخاصة بالمادة وأي ملفات لاستخدام بسياسة الوصول للقراءة افتراضية للغاوية. ", + + // "item.edit.move.head": "Move item: {{id}}", + "item.edit.move.head": "نقل المادة: {{id}}", + + // "item.edit.move.inheritpolicies.checkbox": "Inherit policies", + "item.edit.move.inheritpolicies.checkbox": "توريث السياسات", + + // "item.edit.move.inheritpolicies.description": "Inherit the default policies of the destination collection", + "item.edit.move.inheritpolicies.description": "توريث السياسات الافتراضية للحاوية المقصودة", + + // "item.edit.move.inheritpolicies.tooltip": "Warning: When enabled, the read access policy for the item and any files associated with the item will be replaced by the default read access policy of the collection. This cannot be undone.", + "item.edit.move.inheritpolicies.tooltip": "تحذير: عند التفعيل، سيتم استبدال سياسة الوصول للقراءة الخاصة بالمادة وأي ملفات مرتبطة بالمادة بسياسة الوصول للقراءة الافتراضية للحاوية. لا يمكن التراجع عنه هذا الإجراء.", + + // "item.edit.move.move": "Move", "item.edit.move.move": "نقل", + + // "item.edit.move.processing": "Moving...", "item.edit.move.processing": "جاري النقل...", - "item.edit.move.search.placeholder": "قم برجاء التأكيد على البحث عن تيفين", - "item.edit.move.success": "تم نقل المادة الفعالة", + + // "item.edit.move.search.placeholder": "Enter a search query to look for collections", + "item.edit.move.search.placeholder": "قم بإدخال استعلام بحث للبحث عن حاويات", + + // "item.edit.move.success": "The item has been moved successfully", + "item.edit.move.success": "تم نقل المادة بنجاح", + + // "item.edit.move.title": "Move item", "item.edit.move.title": "نقل المادة", + + // "item.edit.private.cancel": "Cancel", "item.edit.private.cancel": "إلغاء", + + // "item.edit.private.confirm": "Make it non-discoverable", "item.edit.private.confirm": "اجعلها غير قابلة للاكتشاف", + + // "item.edit.private.description": "Are you sure this item should be made non-discoverable in the archive?", "item.edit.private.description": "هل أنت متأكد من أن هذه المادة يجب أن تكون غير قابلة للاكتشاف في الأرشيف؟", - "item.edit.private.error": "حدث خطأ أثناء وضع المادة غير قابلة للاكتشاف", - "item.edit.private.header": "المادة غير قابلة للاكتشاف: {{ id }}", + + // "item.edit.private.error": "An error occurred while making the item non-discoverable", + "item.edit.private.error": "حدث خطأ أثناء جعل المادة غير قابلة للاكتشاف", + + // "item.edit.private.header": "Make item non-discoverable: {{ id }}", + "item.edit.private.header": "اجعل المادة غير قابلة للاكتشاف: {{ id }}", + + // "item.edit.private.success": "The item is now non-discoverable", "item.edit.private.success": "المادة الآن غير قابلة للاكتشاف", + + // "item.edit.public.cancel": "Cancel", "item.edit.public.cancel": "إلغاء", - "item.edit.public.confirm": "اجعلها للاكتشاف", - "item.edit.public.description": "هل أنت متأكد من أنه يجب أن تمتلك هذه المادة القابلة للاكتشاف في الأرشيف؟", - "item.edit.public.error": "حدث خطأ أثناء المادة القابلة للاكتشاف", - "item.edit.public.header": "المادة قابلة للاكتشاف: {{ id }}", - "item.edit.public.success": "المادة الآن للاكتشاف", + + // "item.edit.public.confirm": "Make it discoverable", + "item.edit.public.confirm": "اجعلها قابلة للاكتشاف", + + // "item.edit.public.description": "Are you sure this item should be made discoverable in the archive?", + "item.edit.public.description": "هل أنت متأكد من أنه يجب جعل هذه المادة قابلة للاكتشاف في الأرشيف؟", + + // "item.edit.public.error": "An error occurred while making the item discoverable", + "item.edit.public.error": "حدث خطأ أثناء جعل المادة قابلة للاكتشاف", + + // "item.edit.public.header": "Make item discoverable: {{ id }}", + "item.edit.public.header": "اجعل المادة قابلة للاكتشاف: {{ id }}", + + // "item.edit.public.success": "The item is now discoverable", + "item.edit.public.success": "المادة الآن قابلة للاكتشاف", + + // "item.edit.reinstate.cancel": "Cancel", "item.edit.reinstate.cancel": "إلغاء", + + // "item.edit.reinstate.confirm": "Reinstate", "item.edit.reinstate.confirm": "إعادة تعيين", + + // "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", "item.edit.reinstate.description": "هل أنت متأكد من إعادة تعيين هذه المادة إلى الأرشيف؟", + + // "item.edit.reinstate.error": "An error occurred while reinstating the item", "item.edit.reinstate.error": "حدث خطأ أثناء إعادة تعيين المادة", + + // "item.edit.reinstate.header": "Reinstate item: {{ id }}", "item.edit.reinstate.header": "إعادة تعيين المادة: {{ id }}", - "item.edit.reinstate.success": "إعادة تعيين المادة الفعالة", - "item.edit.relationships.discard-button": "لا", + + // "item.edit.reinstate.success": "The item was reinstated successfully", + "item.edit.reinstate.success": "تمت إعادة تعيين المادة بنجاح", + + // "item.edit.relationships.discard-button": "Discard", + "item.edit.relationships.discard-button": "تجاهل", + + // "item.edit.relationships.edit.buttons.add": "Add", "item.edit.relationships.edit.buttons.add": "إضافة", + + // "item.edit.relationships.edit.buttons.remove": "Remove", "item.edit.relationships.edit.buttons.remove": "إزالة", - "item.edit.relationships.edit.buttons.undo": "انقلب عن التغييرات", + + // "item.edit.relationships.edit.buttons.undo": "Undo changes", + "item.edit.relationships.edit.buttons.undo": "تراجع عن التغييرات", + + // "item.edit.relationships.no-relationships": "No relationships", "item.edit.relationships.no-relationships": "لا توجد علاقات", - "item.edit.relationships.notifications.discarded.content": "تم تجاهل تجاهلك. ", + + // "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.relationships.notifications.discarded.content": "تم تجاهل تغييراتك. لإعادة تعيين التغييرات قم بالنقر على زر 'تراجع'", + + // "item.edit.relationships.notifications.discarded.title": "Changes discarded", "item.edit.relationships.notifications.discarded.title": "تم تجاهل التغييرات", + + // "item.edit.relationships.notifications.failed.title": "Error editing relationships", "item.edit.relationships.notifications.failed.title": "حدث خطأ أثناء تحرير العلاقات", - "item.edit.relationships.notifications.outdated.content": "المادة التي تعمل بها حاليًا تم تغييرها بواسطة مستخدم آخر. ", - "item.edit.relationships.notifications.outdated.title": "اختر التغييرات", - "item.edit.relationships.notifications.saved.content": "تم الحفاظ على أفكارك على علاقات هذه المادة.", + + // "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + "item.edit.relationships.notifications.outdated.content": "المادة التي تعمل عليها حالياً تم تغييرها بواسطة مستخدم آخر. تم تجاهل تغييراتك الحالية لتجنب التعارض", + + // "item.edit.relationships.notifications.outdated.title": "Changes outdated", + "item.edit.relationships.notifications.outdated.title": "انتهت صلاحية التغييرات", + + // "item.edit.relationships.notifications.saved.content": "Your changes to this item's relationships were saved.", + "item.edit.relationships.notifications.saved.content": "تم حفظ تغييراتك على علاقات هذه المادة.", + + // "item.edit.relationships.notifications.saved.title": "Relationships saved", "item.edit.relationships.notifications.saved.title": "تم حفظ العلاقات", - "item.edit.relationships.reinstate-button": "ديب", + + // "item.edit.relationships.reinstate-button": "Undo", + "item.edit.relationships.reinstate-button": "تراجع", + + // "item.edit.relationships.save-button": "Save", "item.edit.relationships.save-button": "حفظ", - "item.edit.relationships.no-entity-type": "قم بإضافة ميتا 'dspace.entity.type' لتفعيل هذه العلاقات", + + // "item.edit.relationships.no-entity-type": "Add 'dspace.entity.type' metadata to enable relationships for this item", + "item.edit.relationships.no-entity-type": "قم بإضافة ميتاداتا 'dspace.entity.type' لتفعيل العلاقات لهذه المادة", + + // "item.edit.return": "Back", "item.edit.return": "رجوع", + + // "item.edit.tabs.bitstreams.head": "Bitstreams", "item.edit.tabs.bitstreams.head": "تدفقات البت", - "item.edit.tabs.bitstreams.title": "المادة الخام - تدفقات البت", + + // "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", + "item.edit.tabs.bitstreams.title": "تحرير المادة - تدفقات البت", + + // "item.edit.tabs.curate.head": "Curate", "item.edit.tabs.curate.head": "أكرتة", + + // "item.edit.tabs.curate.title": "Item Edit - Curate", "item.edit.tabs.curate.title": "تحرير المادة - أكرتة", - "item.edit.curate.title": "المادة المادة: {{item}}", + + // "item.edit.curate.title": "Curate Item: {{item}}", + "item.edit.curate.title": "أكرتة المادة: {{item}}", + + // "item.edit.tabs.access-control.head": "Access Control", "item.edit.tabs.access-control.head": "التحكم في الوصول", + + // "item.edit.tabs.access-control.title": "Item Edit - Access Control", "item.edit.tabs.access-control.title": "تحرير المادة - التحكم في الوصول", - "item.edit.tabs.metadata.head": "ميداداتا", - "item.edit.tabs.metadata.title": "تحرير المادة - الميتاداتا", + + // "item.edit.tabs.metadata.head": "Metadata", + "item.edit.tabs.metadata.head": "الميتاداتا", + + // "item.edit.tabs.metadata.title": "Item Edit - Metadata", + "item.edit.tabs.metadata.title": "تحرير المادة - الميتاداتا", + + // "item.edit.tabs.relationships.head": "Relationships", "item.edit.tabs.relationships.head": "العلاقات", + + // "item.edit.tabs.relationships.title": "Item Edit - Relationships", "item.edit.tabs.relationships.title": "تحرير الماة - العلاقات", - "item.edit.tabs.status.buttons.authorizations.button": "...تصاريح", - "item.edit.tabs.status.buttons.authorizations.label": "تحرير سياسات المادة", - "item.edit.tabs.status.buttons.delete.button": "حذف", - "item.edit.tabs.status.buttons.delete.label": "شطب المادة", - "item.edit.tabs.status.buttons.mappedCollections.button": "وثيقة الوثيقة", - "item.edit.tabs.status.buttons.mappedCollections.label": "غير متوقعة", - "item.edit.tabs.status.buttons.move.button": "قم بنقل هذه المادة إلى حاوية مختلفة", - "item.edit.tabs.status.buttons.move.label": "قم بنقل هذه المادة إلى حاوية مختلفة", + + // "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", + "item.edit.tabs.status.buttons.authorizations.button": "تصاريح...", + + // "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", + "item.edit.tabs.status.buttons.authorizations.label": "تحرير سياسات تصاريح المادة", + + // "item.edit.tabs.status.buttons.delete.button": "Permanently delete", + "item.edit.tabs.status.buttons.delete.button": "حذف نهائي", + + // "item.edit.tabs.status.buttons.delete.label": "Completely expunge item", + "item.edit.tabs.status.buttons.delete.label": "شطب المادة تماماً", + + // "item.edit.tabs.status.buttons.mappedCollections.button": "Mapped collections", + "item.edit.tabs.status.buttons.mappedCollections.button": "حاويات مخططة", + + // "item.edit.tabs.status.buttons.mappedCollections.label": "Manage mapped collections", + "item.edit.tabs.status.buttons.mappedCollections.label": "أدر الحاويات المخططة", + + // "item.edit.tabs.status.buttons.move.button": "Move this Item to a different Collection", + "item.edit.tabs.status.buttons.move.button": "نقل هذه المادة إلى حاوية مختلفة", + + // "item.edit.tabs.status.buttons.move.label": "Move item to another collection", + "item.edit.tabs.status.buttons.move.label": "نقل هذه المادة إلى حاوية مختلفة", + + // "item.edit.tabs.status.buttons.private.button": "Make it non-discoverable...", "item.edit.tabs.status.buttons.private.button": "اجعلها غير قابلة للاكتشاف...", - "item.edit.tabs.status.buttons.private.label": "المادة غير قابلة للاكتشاف", - "item.edit.tabs.status.buttons.public.button": "اجعلها للاكتشاف...", - "item.edit.tabs.status.buttons.public.label": "المادة قابلة للاكتشاف", + + // "item.edit.tabs.status.buttons.private.label": "Make item non-discoverable", + "item.edit.tabs.status.buttons.private.label": "اجعل المادة غير قابلة للاكتشاف", + + // "item.edit.tabs.status.buttons.public.button": "Make it discoverable...", + "item.edit.tabs.status.buttons.public.button": "اجعلها قابلة للاكتشاف...", + + // "item.edit.tabs.status.buttons.public.label": "Make item discoverable", + "item.edit.tabs.status.buttons.public.label": "اجعل المادة قابلة للاكتشاف", + + // "item.edit.tabs.status.buttons.reinstate.button": "Reinstate...", "item.edit.tabs.status.buttons.reinstate.button": "إعادة تعيين...", + + // "item.edit.tabs.status.buttons.reinstate.label": "Reinstate item into the repository", "item.edit.tabs.status.buttons.reinstate.label": "إعادة تعيين المادة في المستودع", - "item.edit.tabs.status.buttons.unauthorized": "غير مصرح لك بهذا الاقتراح", - "item.edit.tabs.status.buttons.withdraw.button": "اسحب هذه المادة", - "item.edit.tabs.status.buttons.withdraw.label": "اسحب هذه المادة من المستودع", - "item.edit.tabs.status.description": "مرحبا بك في صفحة إدارة المادة. ", + + // "item.edit.tabs.status.buttons.unauthorized": "You're not authorized to perform this action", + "item.edit.tabs.status.buttons.unauthorized": "غير مصرح لك بالقيام بهذا الإجراء", + + // "item.edit.tabs.status.buttons.withdraw.button": "Withdraw this item", + "item.edit.tabs.status.buttons.withdraw.button": "سحب هذه المادة", + + // "item.edit.tabs.status.buttons.withdraw.label": "Withdraw item from the repository", + "item.edit.tabs.status.buttons.withdraw.label": "سحب هذه المادة من المستودع", + + // "item.edit.tabs.status.description": "Welcome to the item management page. From here you can withdraw, reinstate, move or delete the item. You may also update or add new metadata / bitstreams on the other tabs.", + "item.edit.tabs.status.description": "مرحباً بك في صفحة إدارة المادة. من هنا يمكنك سحب المادة، أو إعادة تعيينها، أو نقلها أو حذفها. كما يمكنك تحديث أو إضافة ميتاداتا/ تدفقات بت جديدة في التبويبات الأخرى.", + + // "item.edit.tabs.status.head": "Status", "item.edit.tabs.status.head": "الحالة", - "item.edit.tabs.status.labels.handle": "مقبض", - "item.edit.tabs.status.labels.id": "تم تعريف المادة داخليًا", + + // "item.edit.tabs.status.labels.handle": "Handle", + "item.edit.tabs.status.labels.handle": "هاندل", + + // "item.edit.tabs.status.labels.id": "Item Internal ID", + "item.edit.tabs.status.labels.id": "معرّف المادة الداخلي", + + // "item.edit.tabs.status.labels.itemPage": "Item Page", "item.edit.tabs.status.labels.itemPage": "صفحة المادة", + + // "item.edit.tabs.status.labels.lastModified": "Last Modified", "item.edit.tabs.status.labels.lastModified": "آخر تعديل", - "item.edit.tabs.status.title": "تحرير المادة - الحالة", - "item.edit.tabs.versionhistory.head": "نسخة السجل", - "item.edit.tabs.versionhistory.title": "تحرير المادة - سجل النسخة", - "item.edit.tabs.versionhistory.under-construction": "تحرير أو إضافة إصدار جديد ليس ممكناً بعد في واجهة المستخدم هذه..", + + // "item.edit.tabs.status.title": "Item Edit - Status", + "item.edit.tabs.status.title": "تحرير المادة - الحالة", + + // "item.edit.tabs.versionhistory.head": "Version History", + "item.edit.tabs.versionhistory.head": "سجل الإصدارة", + + // "item.edit.tabs.versionhistory.title": "Item Edit - Version History", + "item.edit.tabs.versionhistory.title": "تحرير المادة - سجل الإصدارة", + + // "item.edit.tabs.versionhistory.under-construction": "Editing or adding new versions is not yet possible in this user interface.", + "item.edit.tabs.versionhistory.under-construction": "تحرير أو إضافة إصدارات جديدة ليس ممكناً بعد في واجهة المستخدم هذه..", + + // "item.edit.tabs.view.head": "View Item", "item.edit.tabs.view.head": "عرض المادة", - "item.edit.tabs.view.title": "تحرير المادة - عرض", + + // "item.edit.tabs.view.title": "Item Edit - View", + "item.edit.tabs.view.title": "تحرير المادة - عرض", + + // "item.edit.withdraw.cancel": "Cancel", "item.edit.withdraw.cancel": "إلغاء", - "item.edit.withdraw.confirm": "يسحب", - "item.edit.withdraw.description": "هل أنت متأكد من أنك لا تستطيع سحب هذه المادة من الأرشيف؟", - "item.edit.withdraw.error": "حدث خطأ أثناء المادة", - "item.edit.withdraw.header": "المادة: {{ id }}", - "item.edit.withdraw.success": "تم سحب المادة الفعالة", + + // "item.edit.withdraw.confirm": "Withdraw", + "item.edit.withdraw.confirm": "سحب", + + // "item.edit.withdraw.description": "Are you sure this item should be withdrawn from the archive?", + "item.edit.withdraw.description": "هل أنت متأكد من ضرورة سحب هذه المادة من الأرشيف؟", + + // "item.edit.withdraw.error": "An error occurred while withdrawing the item", + "item.edit.withdraw.error": "حدث خطأ أثناء سحب المادة", + + // "item.edit.withdraw.header": "Withdraw item: {{ id }}", + "item.edit.withdraw.header": "سحب المادة: {{ id }}", + + // "item.edit.withdraw.success": "The item was withdrawn successfully", + "item.edit.withdraw.success": "تم سحب المادة بنجاح", + + // "item.orcid.return": "Back", "item.orcid.return": "رجوع", + + // "item.listelement.badge": "Item", "item.listelement.badge": "المادة", + + // "item.page.description": "Description", "item.page.description": "الوصف", + + // "item.page.journal-issn": "Journal ISSN", "item.page.journal-issn": "ردمد الدورية", - "item.page.journal-title": "عنوان الدوري", + + // "item.page.journal-title": "Journal Title", + "item.page.journal-title": "عنوان الدورية", + + // "item.page.publisher": "Publisher", "item.page.publisher": "الناشر", + + // "item.page.titleprefix": "Item: ", "item.page.titleprefix": "المادة: ", + + // "item.page.volume-title": "Volume Title", "item.page.volume-title": "عنوان المجلد", - "item.search.results.head": "نتائج بحثت المواد", - "item.search.title": "بحثت المواد", + + // "item.search.results.head": "Item Search Results", + "item.search.results.head": "نتائج بحث المواد", + + // "item.search.title": "Item Search", + "item.search.title": "بحث المواد", + + // "item.truncatable-part.show-more": "Show more", "item.truncatable-part.show-more": "عرض المواد", - "item.truncatable-part.show-less": "طيء", - "item.qa-event-notification.check.notification-info": "هناك {{num}} في انتظار الاقتراحات المتعلقة بحسابك", - "item.qa-event-notification-info.check.button": "منظر", - "mydspace.qa-event-notification.check.notification-info": "هناك {{num}} في انتظار الاقتراحات المتعلقة بحسابك", - "mydspace.qa-event-notification-info.check.button": "منظر", + + // "item.truncatable-part.show-less": "Collapse", + "item.truncatable-part.show-less": "طي", + + // "item.qa-event-notification.check.notification-info": "There are {{num}} pending suggestions related to your account", + // TODO New key - Add a translation + "item.qa-event-notification.check.notification-info": "There are {{num}} pending suggestions related to your account", + + // "item.qa-event-notification-info.check.button": "View", + // TODO New key - Add a translation + "item.qa-event-notification-info.check.button": "View", + + // "mydspace.qa-event-notification.check.notification-info": "There are {{num}} pending suggestions related to your account", + // TODO New key - Add a translation + "mydspace.qa-event-notification.check.notification-info": "There are {{num}} pending suggestions related to your account", + + // "mydspace.qa-event-notification-info.check.button": "View", + // TODO New key - Add a translation + "mydspace.qa-event-notification-info.check.button": "View", + + // "workflow-item.search.result.delete-supervision.modal.header": "Delete Supervision Order", "workflow-item.search.result.delete-supervision.modal.header": "حذف أمر الإشراف", - "workflow-item.search.result.delete-supervision.modal.info": "هل أنت متأكد من أنك تريد حذف أمر مهم؟", + + // "workflow-item.search.result.delete-supervision.modal.info": "Are you sure you want to delete Supervision Order", + "workflow-item.search.result.delete-supervision.modal.info": "هل أنت متأكد من أنك تريد حذف أمر الإشراف", + + // "workflow-item.search.result.delete-supervision.modal.cancel": "Cancel", "workflow-item.search.result.delete-supervision.modal.cancel": "إلغاء", + + // "workflow-item.search.result.delete-supervision.modal.confirm": "Delete", "workflow-item.search.result.delete-supervision.modal.confirm": "حذف", - "workflow-item.search.result.notification.deleted.success": "تم الحذف أمر فعال فعال \"{{name}}\"", + + // "workflow-item.search.result.notification.deleted.success": "Successfully deleted supervision order \"{{name}}\"", + "workflow-item.search.result.notification.deleted.success": "تم حذف أمر الإشراف بنجاح \"{{name}}\"", + + // "workflow-item.search.result.notification.deleted.failure": "Failed to delete supervision order \"{{name}}\"", "workflow-item.search.result.notification.deleted.failure": "فشل في حذف أمر الإشراف \"{{name}}\"", - "workflow-item.search.result.list.element.supervised-by": "تحت الضربة:", + + // "workflow-item.search.result.list.element.supervised-by": "Supervised by:", + "workflow-item.search.result.list.element.supervised-by": "تحت إشراف:", + + // "workflow-item.search.result.list.element.supervised.remove-tooltip": "Remove supervision group", "workflow-item.search.result.list.element.supervised.remove-tooltip": "إزالة مجموعة الإشراف", - "confidence.indicator.help-text.accepted": "تم تأكيد دقة قيمة الاستناد هذه من قبل مستخدم تفاعلي", - "confidence.indicator.help-text.uncertain": "القيمة مفردة وصالحة ولكن لم يراها الإنسان ويقبلها، لذا فهي لا تزال غير مؤكدة", - "confidence.indicator.help-text.ambiguous": "هناك العديد من قيم السلطة المطابقة ذات الصلاحية المتساوية", - "confidence.indicator.help-text.notfound": "لا توجد إجابات مطابقة في السلطة", - "confidence.indicator.help-text.failed": "واجهت السلطة فشلا داخليا", - "confidence.indicator.help-text.rejected": "توصي الهيئة برفض هذا التقديم", - "confidence.indicator.help-text.novalue": "ولم يتم إرجاع أي قيمة ثقة معقولة من الهيئة", - "confidence.indicator.help-text.unset": "لم يتم تسجيل الثقة بهذه القيمة أبدًا", - "confidence.indicator.help-text.unknown": "قيمة ثقة غير معروفة", - "item.page.abstract": "أ", + + // "confidence.indicator.help-text.accepted": "This authority value has been confirmed as accurate by an interactive user", + // TODO New key - Add a translation + "confidence.indicator.help-text.accepted": "This authority value has been confirmed as accurate by an interactive user", + + // "confidence.indicator.help-text.uncertain": "Value is singular and valid but has not been seen and accepted by a human so it is still uncertain", + // TODO New key - Add a translation + "confidence.indicator.help-text.uncertain": "Value is singular and valid but has not been seen and accepted by a human so it is still uncertain", + + // "confidence.indicator.help-text.ambiguous": "There are multiple matching authority values of equal validity", + // TODO New key - Add a translation + "confidence.indicator.help-text.ambiguous": "There are multiple matching authority values of equal validity", + + // "confidence.indicator.help-text.notfound": "There are no matching answers in the authority", + // TODO New key - Add a translation + "confidence.indicator.help-text.notfound": "There are no matching answers in the authority", + + // "confidence.indicator.help-text.failed": "The authority encountered an internal failure", + // TODO New key - Add a translation + "confidence.indicator.help-text.failed": "The authority encountered an internal failure", + + // "confidence.indicator.help-text.rejected": "The authority recommends this submission be rejected", + // TODO New key - Add a translation + "confidence.indicator.help-text.rejected": "The authority recommends this submission be rejected", + + // "confidence.indicator.help-text.novalue": "No reasonable confidence value was returned from the authority", + // TODO New key - Add a translation + "confidence.indicator.help-text.novalue": "No reasonable confidence value was returned from the authority", + + // "confidence.indicator.help-text.unset": "Confidence was never recorded for this value", + // TODO New key - Add a translation + "confidence.indicator.help-text.unset": "Confidence was never recorded for this value", + + // "confidence.indicator.help-text.unknown": "Unknown confidence value", + // TODO New key - Add a translation + "confidence.indicator.help-text.unknown": "Unknown confidence value", + + // "item.page.abstract": "Abstract", + "item.page.abstract": "خلاصة", + + // "item.page.author": "Authors", "item.page.author": "المؤلفين", - "item.page.citation": "المرسل", - "item.page.collections": "مقبول", + + // "item.page.citation": "Citation", + "item.page.citation": "اقتباس", + + // "item.page.collections": "Collections", + "item.page.collections": "الحاويات", + + // "item.page.collections.loading": "Loading...", "item.page.collections.loading": "جاري التحميل...", + + // "item.page.collections.load-more": "Load more", "item.page.collections.load-more": "تحميل المزيد", + + // "item.page.date": "Date", "item.page.date": "التاريخ", + + // "item.page.edit": "Edit this item", "item.page.edit": "تحرير هذه المادة", + + // "item.page.files": "Files", "item.page.files": "ملفات", + + // "item.page.filesection.description": "Description:", "item.page.filesection.description": "الوصف:", + + // "item.page.filesection.download": "Download", "item.page.filesection.download": "تنزيل", - "item.page.filesection.format": "التنسيق:", + + // "item.page.filesection.format": "Format:", + "item.page.filesection.format": "تنسيق:", + + // "item.page.filesection.name": "Name:", "item.page.filesection.name": "الاسم:", + + // "item.page.filesection.size": "Size:", "item.page.filesection.size": "الحجم:", + + // "item.page.journal.search.title": "Articles in this journal", "item.page.journal.search.title": "مقالات في هذه الدورية", - "item.page.link.full": "صفحة المادة كاملة", + + // "item.page.link.full": "Full item page", + "item.page.link.full": "صفحة المادة الكاملة", + + // "item.page.link.simple": "Simple item page", "item.page.link.simple": "صفحة المادة البسيطة", + + // "item.page.orcid.title": "ORCID", "item.page.orcid.title": "أوركيد", + + // "item.page.orcid.tooltip": "Open ORCID setting page", "item.page.orcid.tooltip": "فتح صفحة إعداد أوركيد", + + // "item.page.person.search.title": "Articles by this author", "item.page.person.search.title": "مقالات بواسطة هذا المؤلف", - "item.page.related-items.view-more": "الإظهار {{ amount }} أكثر", + + // "item.page.related-items.view-more": "Show {{ amount }} more", + "item.page.related-items.view-more": "إظهار {{ amount }} أكثر", + + // "item.page.related-items.view-less": "Hide last {{ amount }}", "item.page.related-items.view-less": "إخفاء آخر {{ amount }}", - "item.page.relationships.isAuthorOfPublication": "منشورات", - "item.page.relationships.isJournalOfPublication": "منشورات", + + // "item.page.relationships.isAuthorOfPublication": "Publications", + "item.page.relationships.isAuthorOfPublication": "المنشورات", + + // "item.page.relationships.isJournalOfPublication": "Publications", + "item.page.relationships.isJournalOfPublication": "المنشورات", + + // "item.page.relationships.isOrgUnitOfPerson": "Authors", "item.page.relationships.isOrgUnitOfPerson": "المؤلفين", + + // "item.page.relationships.isOrgUnitOfProject": "Research Projects", "item.page.relationships.isOrgUnitOfProject": "مشاريع البحث", - "item.page.subject": "الكلمات الرئيسية", + + // "item.page.subject": "Keywords", + "item.page.subject": "كلمات رئيسية", + + // "item.page.uri": "URI", "item.page.uri": "URI", + + // "item.page.bitstreams.view-more": "Show more", "item.page.bitstreams.view-more": "عرض المزيد", - "item.page.bitstreams.collapse": "طيء", - "item.page.bitstreams.primary": "أساسي", + + // "item.page.bitstreams.collapse": "Collapse", + "item.page.bitstreams.collapse": "طي", + + // "item.page.bitstreams.primary": "Primary", + // TODO New key - Add a translation + "item.page.bitstreams.primary": "Primary", + + // "item.page.filesection.original.bundle": "Original bundle", "item.page.filesection.original.bundle": "الحزمة الرئيسية", - "item.page.filesection.license.bundle": "حزمة الحزمة", + + // "item.page.filesection.license.bundle": "License bundle", + "item.page.filesection.license.bundle": "حزمة الترخيص", + + // "item.page.return": "Back", "item.page.return": "رجوع", - "item.page.version.create": "إنشاء طبعة جديدة", - "item.page.withdrawn": "طلب سحب لهذا البند", - "item.page.reinstate": "طلب الإعادة", - "item.page.version.hasDraft": "لا يمكن إنشاء نسخة جديدة إذًا هناك تقديم قيد التقدم في نسخة النسخة", + + // "item.page.version.create": "Create new version", + "item.page.version.create": "إنشاء إصدارة جديدة", + + // "item.page.withdrawn": "Request a withdrawal for this item", + // TODO New key - Add a translation + "item.page.withdrawn": "Request a withdrawal for this item", + + // "item.page.reinstate": "Request reinstatement", + // TODO New key - Add a translation + "item.page.reinstate": "Request reinstatement", + + // "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history", + "item.page.version.hasDraft": "لا يمكن إنشاء إصدارة جديدة نظراً لوجود تقديم قيد التقدم في سجل الإصدارة", + + // "item.page.claim.button": "Claim", "item.page.claim.button": "مطالبة", - "item.page.claim.tooltip": "بسبب هذه المادة الشخصية", - "item.page.image.alt.ROR": "شعار ROR", + + // "item.page.claim.tooltip": "Claim this item as profile", + "item.page.claim.tooltip": "المطالبة بهذه المادة كملف شخصي", + + // "item.page.image.alt.ROR": "ROR logo", + "item.page.image.alt.ROR": "ROR شعار", + + // "item.preview.dc.identifier.uri": "Identifier:", "item.preview.dc.identifier.uri": "المعرف:", + + // "item.preview.dc.contributor.author": "Authors:", "item.preview.dc.contributor.author": "المؤلفين:", + + // "item.preview.dc.date.issued": "Published date:", "item.preview.dc.date.issued": "تاريخ النشر:", - "item.preview.dc.description.abstract": "السرعة:", + + // "item.preview.dc.description.abstract": "Abstract:", + "item.preview.dc.description.abstract": "مستخلص:", + + // "item.preview.dc.identifier.other": "Other identifier:", "item.preview.dc.identifier.other": "معرف آخر:", + + // "item.preview.dc.language.iso": "Language:", "item.preview.dc.language.iso": "اللغة:", - "item.preview.dc.subject": "الموضوع:", - "item.preview.dc.title": "عنوان العنوان:", + + // "item.preview.dc.subject": "Subjects:", + "item.preview.dc.subject": "الموضوعات:", + + // "item.preview.dc.title": "Title:", + "item.preview.dc.title": "العنوان:", + + // "item.preview.dc.type": "Type:", "item.preview.dc.type": "النوع:", + + // "item.preview.oaire.citation.issue": "Issue", "item.preview.oaire.citation.issue": "العدد", - "item.preview.oaire.citation.volume": "مجلد", - "item.preview.dc.relation.issn": "الرقم الدولي الموحد للدوريات", - "item.preview.dc.identifier.isbn": "رقم ISBN", + + // "item.preview.oaire.citation.volume": "Volume", + "item.preview.oaire.citation.volume": "المجلد", + + // "item.preview.dc.relation.issn": "ISSN", + "item.preview.dc.relation.issn": "ISSN", + + // "item.preview.dc.identifier.isbn": "ISBN", + "item.preview.dc.identifier.isbn": "ISBN", + + // "item.preview.dc.identifier": "Identifier:", "item.preview.dc.identifier": "المعرف:", - "item.preview.dc.relation.ispartof": "الدوري", - "item.preview.dc.identifier.doi": "المعرفة الرقمية", + + // "item.preview.dc.relation.ispartof": "Journal or Series", + "item.preview.dc.relation.ispartof": "الدورية", + + // "item.preview.dc.identifier.doi": "DOI", + "item.preview.dc.identifier.doi": "معرف الكائن الرقمي", + + // "item.preview.dc.publisher": "Publisher:", "item.preview.dc.publisher": "الناشر:", - "item.preview.person.familyName": "يتمنى:", + + // "item.preview.person.familyName": "Surname:", + "item.preview.person.familyName": "اللقب:", + + // "item.preview.person.givenName": "Name:", "item.preview.person.givenName": "الاسم:", + + // "item.preview.person.identifier.orcid": "ORCID:", "item.preview.person.identifier.orcid": "أوركيد:", + + // "item.preview.project.funder.name": "Funder:", "item.preview.project.funder.name": "الممول:", + + // "item.preview.project.funder.identifier": "Funder Identifier:", "item.preview.project.funder.identifier": "معرف الممول:", + + // "item.preview.oaire.awardNumber": "Funding ID:", "item.preview.oaire.awardNumber": "معرف التمويل:", + + // "item.preview.dc.title.alternative": "Acronym:", "item.preview.dc.title.alternative": "الحروف المختصرة:", - "item.preview.dc.coverage.spatial": "عدم التفويض:", - "item.preview.oaire.fundingStream": "التدفق:", + + // "item.preview.dc.coverage.spatial": "Jurisdiction:", + "item.preview.dc.coverage.spatial": "الاختصاص القضائي:", + + // "item.preview.oaire.fundingStream": "Funding Stream:", + "item.preview.oaire.fundingStream": "تدفق التمويل:", + + // "item.preview.oairecerif.identifier.url": "URL", "item.preview.oairecerif.identifier.url": "عنوان URL", + + // "item.preview.organization.address.addressCountry": "Country", "item.preview.organization.address.addressCountry": "البلد", + + // "item.preview.organization.foundingDate": "Founding Date", "item.preview.organization.foundingDate": "تاريخ التأسيس", - "item.preview.organization.identifier.crossrefid": "معرف Crossref", - "item.preview.organization.identifier.isni": "إسني", - "item.preview.organization.identifier.ror": "معرف ROR", - "item.preview.organization.legalName": "الاسم الساقي", - "item.preview.dspace.entity.type": "نوع الكيان:", - "item.select.confirm": "بالتأكيد", - "item.select.empty": "لا يوجد شيء للعرض", + + // "item.preview.organization.identifier.crossrefid": "CrossRef ID", + "item.preview.organization.identifier.crossrefid": "CrossRef معرف", + + // "item.preview.organization.identifier.isni": "ISNI", + "item.preview.organization.identifier.isni": "ISNI", + + // "item.preview.organization.identifier.ror": "ROR ID", + "item.preview.organization.identifier.ror": "ROR معرف", + + // "item.preview.organization.legalName": "Legal Name", + "item.preview.organization.legalName": "الاسم القانوني", + + // "item.preview.dspace.entity.type": "Entity Type:", + // TODO New key - Add a translation + "item.preview.dspace.entity.type": "Entity Type:", + + // "item.select.confirm": "Confirm selected", + "item.select.confirm": "تأكيد المحدد", + + // "item.select.empty": "No items to show", + "item.select.empty": "لا توجد مواد للعرض", + + // "item.select.table.selected": "Selected items", "item.select.table.selected": "المواد المحددة", - "item.select.table.select": "المادة المحددة", - "item.select.table.deselect": "قم بإلغاء تحديد المادة", + + // "item.select.table.select": "Select item", + "item.select.table.select": "تحديد المادة", + + // "item.select.table.deselect": "Deselect item", + "item.select.table.deselect": "إلغاء تحديد المادة", + + // "item.select.table.author": "Author", "item.select.table.author": "المؤلف", - "item.select.table.collection": "ابدأ", - "item.select.table.title": "عنوان العنوان", - "item.version.history.empty": "لا توجد إصدارات أخرى من هذه الخامة حتى الآن.", - "item.version.history.head": "نسخة السجل", + + // "item.select.table.collection": "Collection", + "item.select.table.collection": "الحاوية", + + // "item.select.table.title": "Title", + "item.select.table.title": "العنوان", + + // "item.version.history.empty": "There are no other versions for this item yet.", + "item.version.history.empty": "لا توجد إصدارات أخرى لهذه المادة حتى الآن.", + + // "item.version.history.head": "Version History", + "item.version.history.head": "سجل الإصدارة", + + // "item.version.history.return": "Back", "item.version.history.return": "رجوع", + + // "item.version.history.selected": "Selected version", "item.version.history.selected": "افصدارة المحددة", - "item.version.history.selected.alert": "أنت حاليا تقوم بعرض النسخة {{version}} لذلك.", - "item.version.history.table.version": "النسخة", + + // "item.version.history.selected.alert": "You are currently viewing version {{version}} of the item.", + "item.version.history.selected.alert": "أنت حالياً تقوم بعرض الإصدارة {{version}} للمادة.", + + // "item.version.history.table.version": "Version", + "item.version.history.table.version": "الإصدارة", + + // "item.version.history.table.item": "Item", "item.version.history.table.item": "المادة", + + // "item.version.history.table.editor": "Editor", "item.version.history.table.editor": "المحرر", + + // "item.version.history.table.date": "Date", "item.version.history.table.date": "التاريخ", + + // "item.version.history.table.summary": "Summary", "item.version.history.table.summary": "الملخص", - "item.version.history.table.workspaceItem": "نطاق العمل", + + // "item.version.history.table.workspaceItem": "Workspace item", + "item.version.history.table.workspaceItem": "مادة نطاق العمل", + + // "item.version.history.table.workflowItem": "Workflow item", "item.version.history.table.workflowItem": "مادة سير العمل", + + // "item.version.history.table.actions": "Action", "item.version.history.table.actions": "الإجراء", - "item.version.history.table.action.editWorkspaceItem": "تحرير مساحة العمل", + + // "item.version.history.table.action.editWorkspaceItem": "Edit workspace item", + "item.version.history.table.action.editWorkspaceItem": "تحرير مادة نطاق العمل", + + // "item.version.history.table.action.editSummary": "Edit summary", "item.version.history.table.action.editSummary": "تحرير الملخص", - "item.version.history.table.action.saveSummary": "حفظ الملخص", - "item.version.history.table.action.discardSummary": "أهمل الملخص", - "item.version.history.table.action.newVersion": "إنشاء نسخة جديدة من هذه النسخة", - "item.version.history.table.action.deleteVersion": "حذف النسخة", - "item.version.history.table.action.hasDraft": "لا يمكن إنشاء نسخة جديدة إذًا هناك تقديم قيد التقدم في نسخة النسخة", - "item.version.notice": "هذه ليست آخر نسخة من هذه المادة. هنا.", - "item.version.create.modal.header": "نسخة جديدة", - "item.qa.withdrawn.modal.header": "طلب الانسحاب", - "item.qa.reinstate.modal.header": "طلب إعادة", - "item.qa.reinstate.create.modal.header": "نسخة جديدة", - "item.version.create.modal.text": "خلق نسخة جديدة لهذه المادة", - "item.version.create.modal.text.startingFrom": "البدء من النسخة {{version}}", + + // "item.version.history.table.action.saveSummary": "Save summary edits", + "item.version.history.table.action.saveSummary": "حفظ تعديلات الملخص", + + // "item.version.history.table.action.discardSummary": "Discard summary edits", + "item.version.history.table.action.discardSummary": "تجاهل تعديلات الملخص", + + // "item.version.history.table.action.newVersion": "Create new version from this one", + "item.version.history.table.action.newVersion": "إنشاء إصدارة جديدة من هذه الإصدارة", + + // "item.version.history.table.action.deleteVersion": "Delete version", + "item.version.history.table.action.deleteVersion": "حذف الإصدارة", + + // "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history", + "item.version.history.table.action.hasDraft": "لا يمكن إنشاء إصدارة جديدة نظراً لوجود تقديم قيد التقدم في سجل الإصدارة", + + // "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", + "item.version.notice": "هذه ليست آخر إصدارة من هذه المادة. يمكن العثور على آخر إصدارة من هنا.", + + // "item.version.create.modal.header": "New version", + "item.version.create.modal.header": "إصدارة جديدة", + + // "item.qa.withdrawn.modal.header": "Request withdrawal", + // TODO New key - Add a translation + "item.qa.withdrawn.modal.header": "Request withdrawal", + + // "item.qa.reinstate.modal.header": "Request reinstate", + // TODO New key - Add a translation + "item.qa.reinstate.modal.header": "Request reinstate", + + // "item.qa.reinstate.create.modal.header": "New version", + // TODO New key - Add a translation + "item.qa.reinstate.create.modal.header": "New version", + + // "item.version.create.modal.text": "Create a new version for this item", + "item.version.create.modal.text": "إنشاء إصدارة جديدة لهذه المادة", + + // "item.version.create.modal.text.startingFrom": "starting from version {{version}}", + "item.version.create.modal.text.startingFrom": "بدءاً من الإصدارة {{version}}", + + // "item.version.create.modal.button.confirm": "Create", "item.version.create.modal.button.confirm": "إنشاء", - "item.version.create.modal.button.confirm.tooltip": "إنشاء طبعة جديدة", - "item.qa.withdrawn-reinstate.modal.button.confirm.tooltip": "ارسل طلب", - "qa-withdrown.create.modal.button.confirm": "ينسحب", - "qa-reinstate.create.modal.button.confirm": "إعادة", + + // "item.version.create.modal.button.confirm.tooltip": "Create new version", + "item.version.create.modal.button.confirm.tooltip": "إنشاء إصدارة جديدة", + + // "item.qa.withdrawn-reinstate.modal.button.confirm.tooltip": "Send request", + // TODO New key - Add a translation + "item.qa.withdrawn-reinstate.modal.button.confirm.tooltip": "Send request", + + // "qa-withdrown.create.modal.button.confirm": "Withdraw", + // TODO New key - Add a translation + "qa-withdrown.create.modal.button.confirm": "Withdraw", + + // "qa-reinstate.create.modal.button.confirm": "Reinstate", + // TODO New key - Add a translation + "qa-reinstate.create.modal.button.confirm": "Reinstate", + + // "item.version.create.modal.button.cancel": "Cancel", "item.version.create.modal.button.cancel": "إلغاء", - "item.qa.withdrawn-reinstate.create.modal.button.cancel": "يلغي", - "item.version.create.modal.button.cancel.tooltip": "لا لتوقف عن الاصدار الجديد", - "item.qa.withdrawn-reinstate.create.modal.button.cancel.tooltip": "لا ترسل الطلب", + + // "item.qa.withdrawn-reinstate.create.modal.button.cancel": "Cancel", + // TODO New key - Add a translation + "item.qa.withdrawn-reinstate.create.modal.button.cancel": "Cancel", + + // "item.version.create.modal.button.cancel.tooltip": "Do not create new version", + "item.version.create.modal.button.cancel.tooltip": "لا تقم بإنشاء إصدارة جديدة", + + // "item.qa.withdrawn-reinstate.create.modal.button.cancel.tooltip": "Do not send request", + // TODO New key - Add a translation + "item.qa.withdrawn-reinstate.create.modal.button.cancel.tooltip": "Do not send request", + + // "item.version.create.modal.form.summary.label": "Summary", "item.version.create.modal.form.summary.label": "الملخص", - "qa-withdrawn.create.modal.form.summary.label": "أنت تطلب سحب هذا البند", - "qa-withdrawn.create.modal.form.summary2.label": "الرجاء إدخال سبب الانسحاب", - "qa-reinstate.create.modal.form.summary.label": "أنت تطلب إعادة هذا العنصر", - "qa-reinstate.create.modal.form.summary2.label": "الرجاء إدخال سبب الإعادة", - "item.version.create.modal.form.summary.placeholder": "قم بالضغط على النسخة الجديدة", - "qa-withdrown.modal.form.summary.placeholder": "أدخل سبب السحب", - "qa-reinstate.modal.form.summary.placeholder": "أدخل سبب الإعادة", - "item.version.create.modal.submitted.header": "إنشاء طبعة جديدة...", - "item.qa.withdrawn.modal.submitted.header": "جارٍ إرسال الطلب المسحوب...", - "correction-type.manage-relation.action.notification.reinstate": "تم إرسال طلب الاستعادة.", - "correction-type.manage-relation.action.notification.withdrawn": "تم إرسال طلب السحب.", - "item.version.create.modal.submitted.text": "جاري إنشاء نسخة جديدة. ", - "item.version.create.notification.success": "تم إنشاء نسخة جديدة برقم الإصدار {{version}}", - "item.version.create.notification.failure": "لم يتم إنشاء إصدار جديد", - "item.version.create.notification.inProgress": "لا يمكن إنشاء نسخة جديدة إذًا هناك تقديم قيد التقدم في نسخة النسخة", - "item.version.delete.modal.header": "حذف النسخة", - "item.version.delete.modal.text": "هل ترغب في حذف النسخة {{version}}؟", + + // "qa-withdrawn.create.modal.form.summary.label": "You are requesting to withdraw this item", + // TODO New key - Add a translation + "qa-withdrawn.create.modal.form.summary.label": "You are requesting to withdraw this item", + + // "qa-withdrawn.create.modal.form.summary2.label": "Please enter the reason for the withdrawal", + // TODO New key - Add a translation + "qa-withdrawn.create.modal.form.summary2.label": "Please enter the reason for the withdrawal", + + // "qa-reinstate.create.modal.form.summary.label": "You are requesting to reinstate this item", + // TODO New key - Add a translation + "qa-reinstate.create.modal.form.summary.label": "You are requesting to reinstate this item", + + // "qa-reinstate.create.modal.form.summary2.label": "Please enter the reason for the reinstatment", + // TODO New key - Add a translation + "qa-reinstate.create.modal.form.summary2.label": "Please enter the reason for the reinstatment", + + // "item.version.create.modal.form.summary.placeholder": "Insert the summary for the new version", + "item.version.create.modal.form.summary.placeholder": "قم بإدخال ملخص الإصدارة الجديدة", + + // "qa-withdrown.modal.form.summary.placeholder": "Enter the reason for the withdrawal", + // TODO New key - Add a translation + "qa-withdrown.modal.form.summary.placeholder": "Enter the reason for the withdrawal", + + // "qa-reinstate.modal.form.summary.placeholder": "Enter the reason for the reinstatement", + // TODO New key - Add a translation + "qa-reinstate.modal.form.summary.placeholder": "Enter the reason for the reinstatement", + + // "item.version.create.modal.submitted.header": "Creating new version...", + "item.version.create.modal.submitted.header": "إنشاء إصدارة جديدة...", + + // "item.qa.withdrawn.modal.submitted.header": "Sending withdrawn request...", + // TODO New key - Add a translation + "item.qa.withdrawn.modal.submitted.header": "Sending withdrawn request...", + + // "correction-type.manage-relation.action.notification.reinstate": "Reinstate request sent.", + // TODO New key - Add a translation + "correction-type.manage-relation.action.notification.reinstate": "Reinstate request sent.", + + // "correction-type.manage-relation.action.notification.withdrawn": "Withdraw request sent.", + // TODO New key - Add a translation + "correction-type.manage-relation.action.notification.withdrawn": "Withdraw request sent.", + + // "item.version.create.modal.submitted.text": "The new version is being created. This may take some time if the item has a lot of relationships.", + "item.version.create.modal.submitted.text": "جاري إنشاء الإصدارة الجديدة. قد يستغرق هذا بعض الوقت إذا كان لهذه المادة الكثير من العلاقات.", + + // "item.version.create.notification.success": "New version has been created with version number {{version}}", + "item.version.create.notification.success": "تم إنشاء إصدارة جديدة برقم الإصدار {{version}}", + + // "item.version.create.notification.failure": "New version has not been created", + "item.version.create.notification.failure": "لم يتم إنشاء إصدارة جديدة", + + // "item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history", + "item.version.create.notification.inProgress": "لا يمكن إنشاء إصدارة جديدة نظراً لوجود تقديم قيد التقدم في سجل الإصدارة", + + // "item.version.delete.modal.header": "Delete version", + "item.version.delete.modal.header": "حذف الإصدارة", + + // "item.version.delete.modal.text": "Do you want to delete version {{version}}?", + "item.version.delete.modal.text": "هل ترغب في حذف الإصدارة {{version}}؟", + + // "item.version.delete.modal.button.confirm": "Delete", "item.version.delete.modal.button.confirm": "حذف", - "item.version.delete.modal.button.confirm.tooltip": "حذف هذه النسخة", + + // "item.version.delete.modal.button.confirm.tooltip": "Delete this version", + "item.version.delete.modal.button.confirm.tooltip": "حذف هذه الإصدارة", + + // "item.version.delete.modal.button.cancel": "Cancel", "item.version.delete.modal.button.cancel": "إلغاء", - "item.version.delete.modal.button.cancel.tooltip": "لا تنسى حذف هذه النسخة", - "item.version.delete.notification.success": "تم حذف النسخة رقم {{version}}", - "item.version.delete.notification.failure": "لن يتم حذف النسخة رقم {{version}}", - "item.version.edit.notification.success": "تم تغيير ملخص النسخة رقم {{version}}", - "item.version.edit.notification.failure": "لم يتم تغيير ملخص النسخة رقم {{version}}", + + // "item.version.delete.modal.button.cancel.tooltip": "Do not delete this version", + "item.version.delete.modal.button.cancel.tooltip": "لا تقم بحذف هذه الإصدارة", + + // "item.version.delete.notification.success": "Version number {{version}} has been deleted", + "item.version.delete.notification.success": "تم حذف الإصدارة رقم {{version}}", + + // "item.version.delete.notification.failure": "Version number {{version}} has not been deleted", + "item.version.delete.notification.failure": "لم يتم حذف الإصدارة رقم {{version}}", + + // "item.version.edit.notification.success": "The summary of version number {{version}} has been changed", + "item.version.edit.notification.success": "تم تغيير ملخص الإصدارة رقم {{version}}", + + // "item.version.edit.notification.failure": "The summary of version number {{version}} has not been changed", + "item.version.edit.notification.failure": "لم يتم تغيير ملخص الإصدارة رقم {{version}}", + + // "itemtemplate.edit.metadata.add-button": "Add", "itemtemplate.edit.metadata.add-button": "إضافة", - "itemtemplate.edit.metadata.discard-button": "لا", + + // "itemtemplate.edit.metadata.discard-button": "Discard", + "itemtemplate.edit.metadata.discard-button": "تجاهل", + + // "itemtemplate.edit.metadata.edit.language": "Edit language", "itemtemplate.edit.metadata.edit.language": "تحرير اللغة", + + // "itemtemplate.edit.metadata.edit.value": "Edit value", "itemtemplate.edit.metadata.edit.value": "تحرير القيمة", - "itemtemplate.edit.metadata.edit.buttons.confirm": "بالتأكيد", - "itemtemplate.edit.metadata.edit.buttons.drag": "قم بإعادة الترتيب", + + // "itemtemplate.edit.metadata.edit.buttons.confirm": "Confirm", + "itemtemplate.edit.metadata.edit.buttons.confirm": "تأكيد", + + // "itemtemplate.edit.metadata.edit.buttons.drag": "Drag to reorder", + "itemtemplate.edit.metadata.edit.buttons.drag": "اسحب لإعادة الترتيب", + + // "itemtemplate.edit.metadata.edit.buttons.edit": "Edit", "itemtemplate.edit.metadata.edit.buttons.edit": "تحرير", + + // "itemtemplate.edit.metadata.edit.buttons.remove": "Remove", "itemtemplate.edit.metadata.edit.buttons.remove": "إزالة", - "itemtemplate.edit.metadata.edit.buttons.undo": "انقلب عن التغييرات", + + // "itemtemplate.edit.metadata.edit.buttons.undo": "Undo changes", + "itemtemplate.edit.metadata.edit.buttons.undo": "تراجع عن التغييرات", + + // "itemtemplate.edit.metadata.edit.buttons.unedit": "Stop editing", "itemtemplate.edit.metadata.edit.buttons.unedit": "إيقاف التحرير", - "itemtemplate.edit.metadata.empty": "القالب الحالي لا يحتوي على أي ميتاداتا. ", + + // "itemtemplate.edit.metadata.empty": "The item template currently doesn't contain any metadata. Click Add to start adding a metadata value.", + "itemtemplate.edit.metadata.empty": "قالب العنصر حاليًا لا يحتوي على أي ميتاداتا. انقر فوق إضافة لبدء إضافة قيمة ميتاداتا.", + + // "itemtemplate.edit.metadata.headers.edit": "Edit", "itemtemplate.edit.metadata.headers.edit": "تحرير", - "itemtemplate.edit.metadata.headers.field": "حقل", + + // "itemtemplate.edit.metadata.headers.field": "Field", + "itemtemplate.edit.metadata.headers.field": "الحقل", + + // "itemtemplate.edit.metadata.headers.language": "Lang", "itemtemplate.edit.metadata.headers.language": "اللغة", + + // "itemtemplate.edit.metadata.headers.value": "Value", "itemtemplate.edit.metadata.headers.value": "القيمة", + + // "itemtemplate.edit.metadata.metadatafield": "Edit field", "itemtemplate.edit.metadata.metadatafield": "تحرير الحقل", - "itemtemplate.edit.metadata.metadatafield.error": "حدث خطأ أثناء التحقق من البحث في الميتاداتا", - "itemtemplate.edit.metadata.metadatafield.invalid": "يرجى اختيار البحث ميتاداتا صالح", - "itemtemplate.edit.metadata.notifications.discarded.content": "تم تجاهل التغييرات التي اختارتها. ", + + // "itemtemplate.edit.metadata.metadatafield.error": "An error occurred validating the metadata field", + "itemtemplate.edit.metadata.metadatafield.error": "حدث خطأ أثناء التحقق من حقل الميتاداتا", + + // "itemtemplate.edit.metadata.metadatafield.invalid": "Please choose a valid metadata field", + "itemtemplate.edit.metadata.metadatafield.invalid": "يرجى اختيار حقل ميتاداتا صالح", + + // "itemtemplate.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "itemtemplate.edit.metadata.notifications.discarded.content": "تم تجاهل التغييرات التي أجريتها. لاستعادة التغييرات، قم بالنقر على زر 'تراجع' ", + + // "itemtemplate.edit.metadata.notifications.discarded.title": "Changes discarded", "itemtemplate.edit.metadata.notifications.discarded.title": "تم تجاهل التغييرات", + + // "itemtemplate.edit.metadata.notifications.error.title": "An error occurred", "itemtemplate.edit.metadata.notifications.error.title": "حدث خطأ", - "itemtemplate.edit.metadata.notifications.invalid.content": "لم يتم حفظ التغييرات. ", - "itemtemplate.edit.metadata.notifications.invalid.title": "دياداتا غير صالحة", - "itemtemplate.edit.metadata.notifications.outdated.content": "تم تغيير المادة التي تعمل حاليا بواسطة مستخدم آخر. ", - "itemtemplate.edit.metadata.notifications.outdated.title": "اختر التغييرات", - "itemtemplate.edit.metadata.notifications.saved.content": "تم حفظ التغييرات التي استخدمتها على الميتاداتا لقالب المادة هذه.", + + // "itemtemplate.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + "itemtemplate.edit.metadata.notifications.invalid.content": "لم يتم حفظ التغييرات. يرجى التأكد من أن جميع الحقول صالحة قبل الحفظ.", + + // "itemtemplate.edit.metadata.notifications.invalid.title": "Metadata invalid", + "itemtemplate.edit.metadata.notifications.invalid.title": "الميتاداتا غير صالحة", + + // "itemtemplate.edit.metadata.notifications.outdated.content": "The item template you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + "itemtemplate.edit.metadata.notifications.outdated.content": "تم تغيير قالب المادة الذي تعمل عليه حالياً بواسطة مستخدم آخر. تم تجاهل التغييرات الحالية لمنع التعارضات", + + // "itemtemplate.edit.metadata.notifications.outdated.title": "Changes outdated", + "itemtemplate.edit.metadata.notifications.outdated.title": "انتهت صلاحية التغييرات", + + // "itemtemplate.edit.metadata.notifications.saved.content": "Your changes to this item template's metadata were saved.", + "itemtemplate.edit.metadata.notifications.saved.content": "تم حفظ التغييرات التي أجريتها على الميتاداتا لقالب المادة هذا.", + + // "itemtemplate.edit.metadata.notifications.saved.title": "Metadata saved", "itemtemplate.edit.metadata.notifications.saved.title": "تم حفظ الميتاداتا", - "itemtemplate.edit.metadata.reinstate-button": "ديب", - "itemtemplate.edit.metadata.reset-order-button": "الادارة عن إعادة الترتيب", + + // "itemtemplate.edit.metadata.reinstate-button": "Undo", + "itemtemplate.edit.metadata.reinstate-button": "تراجع", + + // "itemtemplate.edit.metadata.reset-order-button": "Undo reorder", + "itemtemplate.edit.metadata.reset-order-button": "التراجع عن إعادة الترتيب", + + // "itemtemplate.edit.metadata.save-button": "Save", "itemtemplate.edit.metadata.save-button": "حفظ", - "journal.listelement.badge": "الدوري", + + // "journal.listelement.badge": "Journal", + "journal.listelement.badge": "الدورية", + + // "journal.page.description": "Description", "journal.page.description": "الوصف", + + // "journal.page.edit": "Edit this item", "journal.page.edit": "تحرير هذه المادة", + + // "journal.page.editor": "Editor-in-Chief", "journal.page.editor": "رئيس التحرير", - "journal.page.issn": "الرقم الدولي الموحد للدوريات", + + // "journal.page.issn": "ISSN", + "journal.page.issn": "ISSN", + + // "journal.page.publisher": "Publisher", "journal.page.publisher": "الناشر", - "journal.page.titleprefix": "الدوري: ", - "journal.search.results.head": "نتائج الدورية التي بحثتها", - "journal-relationships.search.results.head": "نتائج الدورية التي بحثتها", - "journal.search.title": "الدورية الدورية", - "journalissue.listelement.badge": "عدد الدوري", + + // "journal.page.titleprefix": "Journal: ", + "journal.page.titleprefix": "الدورية: ", + + // "journal.search.results.head": "Journal Search Results", + "journal.search.results.head": "نتائج بحث الدورية", + + // "journal-relationships.search.results.head": "Journal Search Results", + "journal-relationships.search.results.head": "نتائج بحث الدورية", + + // "journal.search.title": "Journal Search", + "journal.search.title": "بحث الدورية", + + // "journalissue.listelement.badge": "Journal Issue", + "journalissue.listelement.badge": "عدد الدورية", + + // "journalissue.page.description": "Description", "journalissue.page.description": "الوصف", + + // "journalissue.page.edit": "Edit this item", "journalissue.page.edit": "تحرير هذه المادة", + + // "journalissue.page.issuedate": "Issue Date", "journalissue.page.issuedate": "تاريخ العدد", + + // "journalissue.page.journal-issn": "Journal ISSN", "journalissue.page.journal-issn": "ردمد الدورية", - "journalissue.page.journal-title": "عنوان الدوري", - "journalissue.page.keyword": "الكلمات الرئيسية", + + // "journalissue.page.journal-title": "Journal Title", + "journalissue.page.journal-title": "عنوان الدورية", + + // "journalissue.page.keyword": "Keywords", + "journalissue.page.keyword": "كلمات رئيسية", + + // "journalissue.page.number": "Number", "journalissue.page.number": "رقم", - "journalissue.page.titleprefix": "عدد الدوري: ", - "journalissue.search.results.head": "نتائج البحث عدد الدوري", - "journalvolume.listelement.badge": "سلسلة الدورية", + + // "journalissue.page.titleprefix": "Journal Issue: ", + "journalissue.page.titleprefix": "عدد الدورية: ", + + // "journalissue.search.results.head": "Journal Issue Search Results", + "journalissue.search.results.head": "نتائج بحث عدد الدورية", + + // "journalvolume.listelement.badge": "Journal Volume", + "journalvolume.listelement.badge": "مجلد الدورية", + + // "journalvolume.page.description": "Description", "journalvolume.page.description": "الوصف", + + // "journalvolume.page.edit": "Edit this item", "journalvolume.page.edit": "تحرير هذه المادة", + + // "journalvolume.page.issuedate": "Issue Date", "journalvolume.page.issuedate": "تاريخ الإصدار", - "journalvolume.page.titleprefix": "دورة دورية: ", - "journalvolume.page.volume": "مجلد", - "journalvolume.search.results.head": "نتائج البحث في الدوري", - "iiifsearchable.listelement.badge": "وسائط الوسائط", - "iiifsearchable.page.titleprefix": "أوكلاند: ", - "iiifsearchable.page.doi": "الرابط الجديد: ", + + // "journalvolume.page.titleprefix": "Journal Volume: ", + "journalvolume.page.titleprefix": "مجلد دورية: ", + + // "journalvolume.page.volume": "Volume", + "journalvolume.page.volume": "المجلد", + + // "journalvolume.search.results.head": "Journal Volume Search Results", + "journalvolume.search.results.head": "نتائج بحث مجلد الدورية", + + // "iiifsearchable.listelement.badge": "Document Media", + "iiifsearchable.listelement.badge": "وسائط الوثائق", + + // "iiifsearchable.page.titleprefix": "Document: ", + "iiifsearchable.page.titleprefix": "الوثيقة: ", + + // "iiifsearchable.page.doi": "Permanent Link: ", + "iiifsearchable.page.doi": "الرابط الدائم: ", + + // "iiifsearchable.page.issue": "Issue: ", "iiifsearchable.page.issue": "العدد: ", + + // "iiifsearchable.page.description": "Description: ", "iiifsearchable.page.description": "الوصف: ", - "iiifviewer.fullscreen.notice": "استخدم الشاشة بالكامل لمشاهدة أفضل.", + + // "iiifviewer.fullscreen.notice": "Use full screen for better viewing.", + "iiifviewer.fullscreen.notice": "استخدم الشاشة الكاملة لمشاهدة أفضل.", + + // "iiif.listelement.badge": "Image Media", "iiif.listelement.badge": "وسائط الصور", + + // "iiif.page.titleprefix": "Image: ", "iiif.page.titleprefix": "الصورة: ", - "iiif.page.doi": "الرابط الجديد: ", + + // "iiif.page.doi": "Permanent Link: ", + "iiif.page.doi": "الرابط الدائم: ", + + // "iiif.page.issue": "Issue: ", "iiif.page.issue": "العدد: ", + + // "iiif.page.description": "Description: ", "iiif.page.description": "الوصف: ", + + // "loading.bitstream": "Loading bitstream...", "loading.bitstream": "جاري تحميل تدفق البت...", + + // "loading.bitstreams": "Loading bitstreams...", "loading.bitstreams": "جاري تحميل تدفقات البت...", + + // "loading.browse-by": "Loading items...", "loading.browse-by": "جاري تحميل المواد...", + + // "loading.browse-by-page": "Loading page...", "loading.browse-by-page": "جاري تحميل الصفحة...", - "loading.collection": "جاري تحميل...", - "loading.collections": "جاري التحميل ...", + + // "loading.collection": "Loading collection...", + "loading.collection": "جاري تحميل الحاوية...", + + // "loading.collections": "Loading collections...", + "loading.collections": "جاري تحميل الحاويات...", + + // "loading.content-source": "Loading content source...", "loading.content-source": "جاري تحميل مصدر المحتوى...", + + // "loading.community": "Loading community...", "loading.community": "جاري تحميل المجتمع...", + + // "loading.default": "Loading...", "loading.default": "جاري التحميل...", + + // "loading.item": "Loading item...", "loading.item": "جاري تحميل المادة...", + + // "loading.items": "Loading items...", "loading.items": "جاري تحميل المواد...", + + // "loading.mydspace-results": "Loading items...", "loading.mydspace-results": "جاري تحميل المواد...", + + // "loading.objects": "Loading...", "loading.objects": "جاري التحميل...", - "loading.recent-submissions": "جاري تحميل أحدث العروض...", + + // "loading.recent-submissions": "Loading recent submissions...", + "loading.recent-submissions": "جاري تحميل أحدث التقديمات...", + + // "loading.search-results": "Loading search results...", "loading.search-results": "جاري تحميل نتائج البحث...", - "loading.sub-collections": "جاري تحميل مؤقت...", - "loading.sub-communities": "جاري تحميل الكنيسة...", + + // "loading.sub-collections": "Loading sub-collections...", + "loading.sub-collections": "جاري تحميل الحاويات الفرعية...", + + // "loading.sub-communities": "Loading sub-communities...", + "loading.sub-communities": "جاري تحميل المجتمعات الفرعية...", + + // "loading.top-level-communities": "Loading top-level communities...", "loading.top-level-communities": "جاري تحميل مجتمعات المستوى الأعلى...", + + // "login.form.email": "Email address", "login.form.email": "عنوان البريد الإلكتروني", + + // "login.form.forgot-password": "Have you forgotten your password?", "login.form.forgot-password": "هل نسيت كلمة المرور؟", + + // "login.form.header": "Please log in to DSpace", "login.form.header": "يرجى تسجيل الدخول إلى دي سبيس", - "login.form.new-user": "مستخدم جديد؟ ", + + // "login.form.new-user": "New user? Click here to register.", + "login.form.new-user": "مستخدم جديد؟ اضغط هنا للتسجيل.", + + // "login.form.oidc": "Log in with OIDC", "login.form.oidc": "تسجيل الدخول باستخدام أوركيد", + + // "login.form.orcid": "Log in with ORCID", "login.form.orcid": "تسجيل الدخول باستخدام أوركيد", + + // "login.form.password": "Password", "login.form.password": "كلمة المرور", + + // "login.form.shibboleth": "Log in with Shibboleth", "login.form.shibboleth": "تسجيل الدخول باستخدام Shibboleth", + + // "login.form.submit": "Log in", "login.form.submit": "تسجيل الدخول", + + // "login.title": "Login", "login.title": "تسجيل الدخول", + + // "login.breadcrumbs": "Login", "login.breadcrumbs": "تسجيل الدخول", + + // "logout.form.header": "Log out from DSpace", "logout.form.header": "تسجيل الخروج من دي سبيس", + + // "logout.form.submit": "Log out", "logout.form.submit": "خروج", + + // "logout.title": "Logout", "logout.title": "خروج", - "menu.header.nav.description": "شريط التنقل المشرف", + + // "menu.header.nav.description": "Admin navigation bar", + // TODO New key - Add a translation + "menu.header.nav.description": "Admin navigation bar", + + // "menu.header.admin": "Management", "menu.header.admin": "إدارة", - "menu.header.image.logo": "مستودع الشعار", + + // "menu.header.image.logo": "Repository logo", + "menu.header.image.logo": "شعار المستودع", + + // "menu.header.admin.description": "Management menu", "menu.header.admin.description": "قائمة الإدارة", + + // "menu.section.access_control": "Access Control", "menu.section.access_control": "التحكم في الوصول", - "menu.section.access_control_authorizations": ".تصاريح", + + // "menu.section.access_control_authorizations": "Authorizations", + "menu.section.access_control_authorizations": "تصاريح", + + // "menu.section.access_control_bulk": "Bulk Access Management", "menu.section.access_control_bulk": "إدارة الوصول بالجملة", + + // "menu.section.access_control_groups": "Groups", "menu.section.access_control_groups": "مجموعات", - "menu.section.access_control_people": "الأشخاص", - "menu.section.reports": "التقارير", - "menu.section.reports.collections": "المجموعات التي تمت تصفيتها", - "menu.section.reports.queries": "استعلام بيانات التعريف", + + // "menu.section.access_control_people": "People", + "menu.section.access_control_people": "أشخاص", + + // "menu.section.reports": "Reports", + // TODO New key - Add a translation + "menu.section.reports": "Reports", + + // "menu.section.reports.collections": "Filtered Collections", + // TODO New key - Add a translation + "menu.section.reports.collections": "Filtered Collections", + + // "menu.section.reports.queries": "Metadata Query", + // TODO New key - Add a translation + "menu.section.reports.queries": "Metadata Query", + + // "menu.section.admin_search": "Admin Search", "menu.section.admin_search": "بحث إداري", + + // "menu.section.browse_community": "This Community", "menu.section.browse_community": "هذا المجتمع", + + // "menu.section.browse_community_by_author": "By Author", "menu.section.browse_community_by_author": "حسب المؤلف", + + // "menu.section.browse_community_by_issue_date": "By Issue Date", "menu.section.browse_community_by_issue_date": "حسب تاريخ الإصدار", - "menu.section.browse_community_by_title": "عنوان حسب الطلب", + + // "menu.section.browse_community_by_title": "By Title", + "menu.section.browse_community_by_title": "حسب العنوان", + + // "menu.section.browse_global": "All of DSpace", "menu.section.browse_global": "كل دي سبيس", + + // "menu.section.browse_global_by_author": "By Author", "menu.section.browse_global_by_author": "حسب المؤلف", + + // "menu.section.browse_global_by_dateissued": "By Issue Date", "menu.section.browse_global_by_dateissued": "حسب تاريخ الإصدار", + + // "menu.section.browse_global_by_subject": "By Subject", "menu.section.browse_global_by_subject": "حسب الموضوع", + + // "menu.section.browse_global_by_srsc": "By Subject Category", "menu.section.browse_global_by_srsc": "حسب فئة الموضوع", - "menu.section.browse_global_by_nsi": "حسب فرس العلوم النرويجي", - "menu.section.browse_global_by_title": "عنوان حسب الطلب", - "menu.section.browse_global_communities_and_collections": "المجتمعات والاويات", - "menu.section.control_panel": "التحكم باللوحة", - "menu.section.curation_task": "مهمة اخرى", + + // "menu.section.browse_global_by_nsi": "By Norwegian Science Index", + "menu.section.browse_global_by_nsi": "حسب فهرس العلوم النرويجي", + + // "menu.section.browse_global_by_title": "By Title", + "menu.section.browse_global_by_title": "حسب العنوان", + + // "menu.section.browse_global_communities_and_collections": "Communities & Collections", + "menu.section.browse_global_communities_and_collections": "المجتمعات والحاويات", + + // "menu.section.control_panel": "Control Panel", + "menu.section.control_panel": "لوحة التحكم", + + // "menu.section.curation_task": "Curation Task", + "menu.section.curation_task": "مهمة الأكرتة", + + // "menu.section.edit": "Edit", "menu.section.edit": "تحرير", + + // "menu.section.edit_collection": "Collection", "menu.section.edit_collection": "حاوية", + + // "menu.section.edit_community": "Community", "menu.section.edit_community": "مجتمع", + + // "menu.section.edit_item": "Item", "menu.section.edit_item": "مادة", + + // "menu.section.export": "Export", "menu.section.export": "تصدير", + + // "menu.section.export_collection": "Collection", "menu.section.export_collection": "حاوية", + + // "menu.section.export_community": "Community", "menu.section.export_community": "مجتمع", + + // "menu.section.export_item": "Item", "menu.section.export_item": "مادة", + + // "menu.section.export_metadata": "Metadata", "menu.section.export_metadata": "ميتاداتا", - "menu.section.export_batch": "التصدير بالدفعة (ZIP)", + + // "menu.section.export_batch": "Batch Export (ZIP)", + "menu.section.export_batch": "تصدير بالدفعة (ZIP)", + + // "menu.section.icon.access_control": "Access Control menu section", "menu.section.icon.access_control": "قسم قائمة التحكم في الوصول", - "menu.section.icon.reports": "قسم قائمة التقارير", - "menu.section.icon.admin_search": "قسم قائمة البحث الإضافي", + + // "menu.section.icon.reports": "Reports menu section", + // TODO New key - Add a translation + "menu.section.icon.reports": "Reports menu section", + + // "menu.section.icon.admin_search": "Admin search menu section", + "menu.section.icon.admin_search": "قسم قائمة البحث الإداري", + + // "menu.section.icon.control_panel": "Control Panel menu section", "menu.section.icon.control_panel": "قسم قائمة لوحة التحكم", - "menu.section.icon.curation_tasks": "قسم قائمة مهمة الاخرة", + + // "menu.section.icon.curation_tasks": "Curation Task menu section", + "menu.section.icon.curation_tasks": "قسم قائمة مهمة الأكرتة", + + // "menu.section.icon.edit": "Edit menu section", "menu.section.icon.edit": "قسم قائمة التحرير", + + // "menu.section.icon.export": "Export menu section", "menu.section.icon.export": "قسم قائمة التصدير", + + // "menu.section.icon.find": "Find menu section", "menu.section.icon.find": "قسم قائمة البحث", + + // "menu.section.icon.health": "Health check menu section", "menu.section.icon.health": "قسم قائمة التحقق من الصحة", + + // "menu.section.icon.import": "Import menu section", "menu.section.icon.import": "قسم قائمة الاستيراد", - "menu.section.icon.new": "قسم قائمة جديدة", + + // "menu.section.icon.new": "New menu section", + "menu.section.icon.new": "قسم قائمة جديد", + + // "menu.section.icon.pin": "Pin sidebar", "menu.section.icon.pin": "تدبيس الشريط الجانبي", + + // "menu.section.icon.processes": "Processes Health", "menu.section.icon.processes": "قسم قائمة العمليات", - "menu.section.icon.registries": "قسم تسجيل التسجيل", + + // "menu.section.icon.registries": "Registries menu section", + "menu.section.icon.registries": "قسم قائمة السجلات", + + // "menu.section.icon.statistics_task": "Statistics Task menu section", "menu.section.icon.statistics_task": "قسم قائمة مهام الإحصائيات", + + // "menu.section.icon.workflow": "Administer workflow menu section", "menu.section.icon.workflow": "قسم قائمة إدارة عمليات سير العمل", + + // "menu.section.icon.unpin": "Unpin sidebar", "menu.section.icon.unpin": "إلغاء تدبيس الشريط الجانبي", - "menu.section.icon.notifications": "قسم قائمة الإخطارات", + + // "menu.section.icon.notifications": "Notifications menu section", + "menu.section.icon.notifications": "قسم قائمة الإشعارات", + + // "menu.section.import": "Import", "menu.section.import": "استيراد", - "menu.section.import_batch": "اتصل بالدفعة (ملف صيفي)", + + // "menu.section.import_batch": "Batch Import (ZIP)", + "menu.section.import_batch": "استيراد بالدفعة (ملف مضغوط)", + + // "menu.section.import_metadata": "Metadata", "menu.section.import_metadata": "ميتاداتا", + + // "menu.section.new": "New", "menu.section.new": "جديد", + + // "menu.section.new_collection": "Collection", "menu.section.new_collection": "حاوية", + + // "menu.section.new_community": "Community", "menu.section.new_community": "مجتمع", + + // "menu.section.new_item": "Item", "menu.section.new_item": "مادة", - "menu.section.new_item_version": "المادة الإصدار", + + // "menu.section.new_item_version": "Item Version", + "menu.section.new_item_version": "إصدارة المادة", + + // "menu.section.new_process": "Process", "menu.section.new_process": "عملية", + + // "menu.section.notifications": "Notifications", "menu.section.notifications": "الإشعارات", + + // "menu.section.quality-assurance": "Quality Assurance", "menu.section.quality-assurance": "ضمان الجودة", - "menu.section.notifications_publication-claim": "المطالبة بالنشر", + + // "menu.section.notifications_publication-claim": "Publication Claim", + // TODO New key - Add a translation + "menu.section.notifications_publication-claim": "Publication Claim", + + // "menu.section.pin": "Pin sidebar", "menu.section.pin": "تدبيس الشريط الجانبي", + + // "menu.section.unpin": "Unpin sidebar", "menu.section.unpin": "إلغاء تدبيس الشريط الجانبي", + + // "menu.section.processes": "Processes", "menu.section.processes": "العمليات", + + // "menu.section.health": "Health", "menu.section.health": "كشف الصحة", - "menu.section.registries": "TI", - "menu.section.registries_format": "حتى", - "menu.section.registries_metadata": "ميداداتا", + + // "menu.section.registries": "Registries", + "menu.section.registries": "السجلات", + + // "menu.section.registries_format": "Format", + "menu.section.registries_format": "التنسيق", + + // "menu.section.registries_metadata": "Metadata", + "menu.section.registries_metadata": "الميتاداتا", + + // "menu.section.statistics": "Statistics", "menu.section.statistics": "الإحصائيات", + + // "menu.section.statistics_task": "Statistics Task", "menu.section.statistics_task": "مهمة الإحصائيات", + + // "menu.section.toggle.access_control": "Toggle Access Control section", "menu.section.toggle.access_control": "قسم التحكم في الوصول للبدل", - "menu.section.toggle.reports": "تبديل قسم التقارير", + + // "menu.section.toggle.reports": "Toggle Reports section", + // TODO New key - Add a translation + "menu.section.toggle.reports": "Toggle Reports section", + + // "menu.section.toggle.control_panel": "Toggle Control Panel section", "menu.section.toggle.control_panel": "قسم لوحة التحكم في البدل", + + // "menu.section.toggle.curation_task": "Toggle Curation Task section", "menu.section.toggle.curation_task": "قسم مهمة أكرتة البدل", + + // "menu.section.toggle.edit": "Toggle Edit section", "menu.section.toggle.edit": "قسم تحرير البدل", + + // "menu.section.toggle.export": "Toggle Export section", "menu.section.toggle.export": "قسم تصدير البدل", + + // "menu.section.toggle.find": "Toggle Find section", "menu.section.toggle.find": "قسم بحث البدل", + + // "menu.section.toggle.import": "Toggle Import section", "menu.section.toggle.import": "قسم استيراد البدل", + + // "menu.section.toggle.new": "Toggle New section", "menu.section.toggle.new": "قسم بدل جديد", + + // "menu.section.toggle.registries": "Toggle Registries section", "menu.section.toggle.registries": "قسم سجلات البدل", + + // "menu.section.toggle.statistics_task": "Toggle Statistics Task section", "menu.section.toggle.statistics_task": "قسم مهمة إحصائيات البدل", + + // "menu.section.workflow": "Administer Workflow", "menu.section.workflow": "أدر سير العمل", + + // "metadata-export-search.tooltip": "Export search results as CSV", "metadata-export-search.tooltip": "تصدير نتائج البحث كملف CSV", - "metadata-export-search.submit.success": "تم تفعيل التنفيذ الفعال", - "metadata-export-search.submit.error": "فشل في إنشاء التصدير", + + // "metadata-export-search.submit.success": "The export was started successfully", + "metadata-export-search.submit.success": "تم بدء التصدير بنجاح", + + // "metadata-export-search.submit.error": "Starting the export has failed", + "metadata-export-search.submit.error": "فشل بدء التصدير", + + // "mydspace.breadcrumbs": "MyDSpace", "mydspace.breadcrumbs": "ماي دي سبيس", + + // "mydspace.description": "", "mydspace.description": "", - "mydspace.messages.controller-help": "حدد هذا الخيار لإنشاء رسالة إلى مقدم المادة.", - "mydspace.messages.description-placeholder": "قم بتأكيد رسالتك هنا...", - "mydspace.messages.hide-msg": "استمرار الرسالة", + + // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", + "mydspace.messages.controller-help": "حدد هذا الخيار لإرسال رسالة إلى مقدم المادة.", + + // "mydspace.messages.description-placeholder": "Insert your message here...", + "mydspace.messages.description-placeholder": "قم بإدخال رسالتك هنا...", + + // "mydspace.messages.hide-msg": "Hide message", + "mydspace.messages.hide-msg": "إخفاء الرسالة", + + // "mydspace.messages.mark-as-read": "Mark as read", "mydspace.messages.mark-as-read": "حدد كمقروء", + + // "mydspace.messages.mark-as-unread": "Mark as unread", "mydspace.messages.mark-as-unread": "حدد كغير مقروء", + + // "mydspace.messages.no-content": "No content.", "mydspace.messages.no-content": "لا يوجد محتوى.", + + // "mydspace.messages.no-messages": "No messages yet.", "mydspace.messages.no-messages": "لا توجد رسائل بعد.", + + // "mydspace.messages.send-btn": "Send", "mydspace.messages.send-btn": "إرسال", + + // "mydspace.messages.show-msg": "Show message", "mydspace.messages.show-msg": "عرض الرسالة", + + // "mydspace.messages.subject-placeholder": "Subject...", "mydspace.messages.subject-placeholder": "الموضوع...", - "mydspace.messages.submitter-help": "حدد هذا الخيار لرسالة إلى وحدة التحكم.", + + // "mydspace.messages.submitter-help": "Select this option to send a message to controller.", + "mydspace.messages.submitter-help": "حدد هذا الخيار لإرسال رسالة إلى وحدة التحكم.", + + // "mydspace.messages.title": "Messages", "mydspace.messages.title": "الرسائل", + + // "mydspace.messages.to": "To", "mydspace.messages.to": "إلى", + + // "mydspace.new-submission": "New submission", "mydspace.new-submission": "تقديم جديد", - "mydspace.new-submission-external": "استيراد الميتاداتا من المصدر الخارجي", - "mydspace.new-submission-external-short": "قم باستيراد الميتاداتا", - "mydspace.results.head": "تقديمك", - "mydspace.results.no-abstract": "لا يوجد روح", - "mydspace.results.no-authors": "لا يوجد كاتبين", - "mydspace.results.no-collections": "لا توجد الوثيقة", + + // "mydspace.new-submission-external": "Import metadata from external source", + "mydspace.new-submission-external": "استيراد الميتاداتا من مصدر خارجي", + + // "mydspace.new-submission-external-short": "Import metadata", + "mydspace.new-submission-external-short": "استيراد الميتاداتا", + + // "mydspace.results.head": "Your submissions", + "mydspace.results.head": "تقديماتك", + + // "mydspace.results.no-abstract": "No Abstract", + "mydspace.results.no-abstract": "لا يوجد مستخلص", + + // "mydspace.results.no-authors": "No Authors", + "mydspace.results.no-authors": "لا يوجد مؤلفين", + + // "mydspace.results.no-collections": "No Collections", + "mydspace.results.no-collections": "لا توجد حاويات", + + // "mydspace.results.no-date": "No Date", "mydspace.results.no-date": "لا يوجد تاريخ", - "mydspace.results.no-files": "لا يوجد ملفات", - "mydspace.results.no-results": "لا يوجد شيء للعرض", + + // "mydspace.results.no-files": "No Files", + "mydspace.results.no-files": "لا توجد ملفات", + + // "mydspace.results.no-results": "There were no items to show", + "mydspace.results.no-results": "لا توجد مواد للعرض", + + // "mydspace.results.no-title": "No title", "mydspace.results.no-title": "لا يوجد عنوان", - "mydspace.results.no-uri": "لا يوجد أوري", + + // "mydspace.results.no-uri": "No URI", + "mydspace.results.no-uri": "لا يوجد Uri", + + // "mydspace.search-form.placeholder": "Search in MyDSpace...", "mydspace.search-form.placeholder": "بحث في ما دي سبيس...", + + // "mydspace.show.workflow": "Workflow tasks", "mydspace.show.workflow": "مهام سير العمل", - "mydspace.show.workspace": "تقديمك", + + // "mydspace.show.workspace": "Your submissions", + "mydspace.show.workspace": "تقديماتك", + + // "mydspace.show.supervisedWorkspace": "Supervised items", "mydspace.show.supervisedWorkspace": "مواد تحت الإشراف", + + // "mydspace.status.mydspaceArchived": "Archived", "mydspace.status.mydspaceArchived": "في الأرشيف", + + // "mydspace.status.mydspaceValidation": "Validation", "mydspace.status.mydspaceValidation": "تحقق", + + // "mydspace.status.mydspaceWaitingController": "Waiting for reviewer", "mydspace.status.mydspaceWaitingController": "في انتظار المتحكم", + + // "mydspace.status.mydspaceWorkflow": "Workflow", "mydspace.status.mydspaceWorkflow": "سير العمل", + + // "mydspace.status.mydspaceWorkspace": "Workspace", "mydspace.status.mydspaceWorkspace": "مساحة العمل", + + // "mydspace.title": "MyDSpace", "mydspace.title": "ماي دي سبيس", - "mydspace.upload.upload-failed": "خطأ أثناء إنشاء نطاق عمل جديد. ", - "mydspace.upload.upload-failed-manyentries": "ملف غير قابل للمعالجة. ", - "mydspace.upload.upload-failed-moreonefile": "طلب غير قابل للمعالجة. ", - "mydspace.upload.upload-multiple-successful": "تم إنشاء {{qty}} نطاق عمل جديد.", + + // "mydspace.upload.upload-failed": "Error creating new workspace. Please verify the content uploaded before retry.", + "mydspace.upload.upload-failed": "خطأ اثناء إنشاء نطاق عمل جديد. يرجى التأكد من المحتوى المرفوع قبل إعادة المحاولة.", + + // "mydspace.upload.upload-failed-manyentries": "Unprocessable file. Detected too many entries but allowed only one for file.", + "mydspace.upload.upload-failed-manyentries": "ملف غير قابل للمعالجة. تم اكتشاف عدد كبير جدًا من المدخلات ولكن تم السماح بإدخال واحد فقط للملف.", + + // "mydspace.upload.upload-failed-moreonefile": "Unprocessable request. Only one file is allowed.", + "mydspace.upload.upload-failed-moreonefile": "طلب غير قابل للمعالجة. يسمح بملف واحد فقط.", + + // "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", + "mydspace.upload.upload-multiple-successful": "تم إنشاء {{qty}} مادة نطاق عمل جديدة.", + + // "mydspace.view-btn": "View", "mydspace.view-btn": "عرض", - "nav.expandable-navbar-section-suffix": "(قائمة فرعية)", - "notification.suggestion": "وجدنا {{count}} المنشورات في ال {{source}} يبدو أن هذا مرتبط بملفك الشخصي.
", - "notification.suggestion.review": "مراجعة الاقتراحات", - "notification.suggestion.please": "لو سمحت", + + // "nav.expandable-navbar-section-suffix": "(submenu)", + // TODO New key - Add a translation + "nav.expandable-navbar-section-suffix": "(submenu)", + + // "notification.suggestion": "We found {{count}} publications in the {{source}} that seems to be related to your profile.
", + // TODO New key - Add a translation + "notification.suggestion": "We found {{count}} publications in the {{source}} that seems to be related to your profile.
", + + // "notification.suggestion.review": "review the suggestions", + // TODO New key - Add a translation + "notification.suggestion.review": "review the suggestions", + + // "notification.suggestion.please": "Please", + // TODO New key - Add a translation + "notification.suggestion.please": "Please", + + // "nav.browse.header": "All of DSpace", "nav.browse.header": "كل دي سبيس", + + // "nav.community-browse.header": "By Community", "nav.community-browse.header": "حسب المجتمع", - "nav.context-help-toggle": "مساعدة تعطيل السياق", - "nav.language": "تغيير اللغة", + + // "nav.context-help-toggle": "Toggle context help", + "nav.context-help-toggle": "مساعدة تبديل السياق", + + // "nav.language": "Language switch", + "nav.language": "تبديل اللغة", + + // "nav.login": "Log In", "nav.login": "تسجيل الدخول", + + // "nav.user-profile-menu-and-logout": "User profile menu and log out", "nav.user-profile-menu-and-logout": "قائمة ملف تعريف المستخدم وتسجيل الخروج", + + // "nav.logout": "Log Out", "nav.logout": "خروج", + + // "nav.main.description": "Main navigation bar", "nav.main.description": "شريط التصفح الرئيسي", + + // "nav.mydspace": "MyDSpace", "nav.mydspace": "ماي دي سبيس", + + // "nav.profile": "Profile", "nav.profile": "الملف الشخصي", + + // "nav.search": "Search", "nav.search": "بحث", + + // "nav.search.button": "Submit search", "nav.search.button": "تقديم بحث", + + // "nav.statistics.header": "Statistics", "nav.statistics.header": "الإحصائيات", - "nav.stop-impersonating": "ضبط التصرف كشخص إلكتروني", + + // "nav.stop-impersonating": "Stop impersonating EPerson", + "nav.stop-impersonating": "التوقف عن التصرف كشخص إلكتروني", + + // "nav.subscriptions": "Subscriptions", "nav.subscriptions": "الاشتراكات", - "nav.toggle": "تغيير التصفح", - "nav.user.description": "شريط تعريف المستخدم", + + // "nav.toggle": "Toggle navigation", + "nav.toggle": "تبديل التصفح", + + // "nav.user.description": "User profile bar", + "nav.user.description": "شريط ملف تعريف المستخدم", + + // "none.listelement.badge": "Item", "none.listelement.badge": "المادة", + + // "quality-assurance.title": "Quality Assurance", "quality-assurance.title": "ضمان الجودة", - "quality-assurance.topics.description": "أدناه يمكنك رؤية جميع المواضيع المرسلة من الاشتراكات في {{source}}.", - "quality-assurance.source.description": "فيما يلي يمكنك رؤية جميع مصادر التنبيهات.", + + // "quality-assurance.topics.description": "Below you can see all the topics received from the subscriptions to {{source}}.", + "quality-assurance.topics.description": "أدناه يمكنك رؤية جميع المواضيع الواردة من الاشتراكات في {{source}}.", + + // "quality-assurance.source.description": "Below you can see all the notification's sources.", + "quality-assurance.source.description": "أدناه يمكنك رؤية جميع مصادر الإشعارات.", + + // "quality-assurance.topics": "Current Topics", "quality-assurance.topics": "المواضيع الحالية", - "quality-assurance.source": "المصدر الحالي", + + // "quality-assurance.source": "Current Sources", + "quality-assurance.source": "المصادر الحالية", + + // "quality-assurance.table.topic": "Topic", "quality-assurance.table.topic": "الموضوع", + + // "quality-assurance.table.source": "Source", "quality-assurance.table.source": "المصدر", - "quality-assurance.table.last-event": "نهاية المطاف فعالة", + + // "quality-assurance.table.last-event": "Last Event", + "quality-assurance.table.last-event": "آخر فعالية", + + // "quality-assurance.table.actions": "Actions", "quality-assurance.table.actions": "إجراءات", - "quality-assurance.source-list.button.detail": "عرض المواضيع ل {{param}}", - "quality-assurance.topics-list.button.detail": "عرض اقتراحات ل {{param}}", - "quality-assurance.noTopics": "لم يتم توفيرها على المواضيع.", - "quality-assurance.noSource": "لم يتم العثور على المصادر.", + + // "quality-assurance.source-list.button.detail": "Show topics for {{param}}", + // TODO New key - Add a translation + "quality-assurance.source-list.button.detail": "Show topics for {{param}}", + + // "quality-assurance.topics-list.button.detail": "Show suggestions for {{param}}", + // TODO New key - Add a translation + "quality-assurance.topics-list.button.detail": "Show suggestions for {{param}}", + + // "quality-assurance.noTopics": "No topics found.", + "quality-assurance.noTopics": "لم يتم العثور على مواضيع.", + + // "quality-assurance.noSource": "No sources found.", + "quality-assurance.noSource": "لم يتم العثور على مصادر.", + + // "notifications.events.title": "Quality Assurance Suggestions", "notifications.events.title": "اقتراحات ضمان الجودة", + + // "quality-assurance.topic.error.service.retrieve": "An error occurred while loading the Quality Assurance topics", "quality-assurance.topic.error.service.retrieve": "حدث خطأ أثناء تحميل موضوعات ضمان الجودة", - "quality-assurance.source.error.service.retrieve": "حدث خطأ أثناء تحميل ضمان الجودة", + + // "quality-assurance.source.error.service.retrieve": "An error occurred while loading the Quality Assurance source", + "quality-assurance.source.error.service.retrieve": "حدث خطأ أثناء تحميل مصدر ضمان الجودة", + + // "quality-assurance.loading": "Loading ...", "quality-assurance.loading": "جاري التحميل ...", + + // "quality-assurance.events.topic": "Topic:", "quality-assurance.events.topic": "الموضوع:", + + // "quality-assurance.noEvents": "No suggestions found.", "quality-assurance.noEvents": "لم يتم العثور على أي اقتراحات.", - "quality-assurance.event.table.trust": "ثا", + + // "quality-assurance.event.table.trust": "Trust", + "quality-assurance.event.table.trust": "ثقة", + + // "quality-assurance.event.table.publication": "Publication", "quality-assurance.event.table.publication": "النشر", + + // "quality-assurance.event.table.details": "Details", "quality-assurance.event.table.details": "تفاصيل", + + // "quality-assurance.event.table.project-details": "Project details", "quality-assurance.event.table.project-details": "تفاصيل المشروع", - "quality-assurance.event.table.reasons": "الأسباب", + + // "quality-assurance.event.table.reasons": "Reasons", + // TODO New key - Add a translation + "quality-assurance.event.table.reasons": "Reasons", + + // "quality-assurance.event.table.actions": "Actions", "quality-assurance.event.table.actions": "إجراءات", - "quality-assurance.event.action.accept": "قبول الاقتراحات", - "quality-assurance.event.action.ignore": "تجاهل الاقتراحات", - "quality-assurance.event.action.undo": "يمسح", + + // "quality-assurance.event.action.accept": "Accept suggestion", + "quality-assurance.event.action.accept": "قبول الاقتراح", + + // "quality-assurance.event.action.ignore": "Ignore suggestion", + "quality-assurance.event.action.ignore": "تجاهل الاقتراح", + + // "quality-assurance.event.action.undo": "DELETE", + // TODO New key - Add a translation + "quality-assurance.event.action.undo": "DELETE", + + // "quality-assurance.event.action.reject": "Reject suggestion", "quality-assurance.event.action.reject": "رفض الاقتراح", - "quality-assurance.event.action.import": "استيراد المشروع وقبول الاقتراحات", - "quality-assurance.event.table.pidtype": "نوع معرف المنتج:", - "quality-assurance.event.table.pidvalue": "قيمة معرف المنتج:", - "quality-assurance.event.table.subjectValue": "موضوع القيمة:", - "quality-assurance.event.table.abstract": "أخيرًا:", - "quality-assurance.event.table.suggestedProject": "بيانات المشروع من OpenAIRE", + + // "quality-assurance.event.action.import": "Import project and accept suggestion", + "quality-assurance.event.action.import": "استيراد المشروع وقبول الاقتراح", + + // "quality-assurance.event.table.pidtype": "PID Type:", + "quality-assurance.event.table.pidtype": "PID نوع:", + + // "quality-assurance.event.table.pidvalue": "PID Value:", + "quality-assurance.event.table.pidvalue": "PID قيمة:", + + // "quality-assurance.event.table.subjectValue": "Subject Value:", + "quality-assurance.event.table.subjectValue": "قيمة الموضوع:", + + // "quality-assurance.event.table.abstract": "Abstract:", + "quality-assurance.event.table.abstract": "خلاصة:", + + // "quality-assurance.event.table.suggestedProject": "OpenAIRE Suggested Project data", + "quality-assurance.event.table.suggestedProject": "بيانات المشروع المقترحة من OpenAIRE", + + // "quality-assurance.event.table.project": "Project title:", "quality-assurance.event.table.project": "عنوان المشروع:", + + // "quality-assurance.event.table.acronym": "Acronym:", "quality-assurance.event.table.acronym": "حروف مختصرة:", + + // "quality-assurance.event.table.code": "Code:", "quality-assurance.event.table.code": "رمز:", + + // "quality-assurance.event.table.funder": "Funder:", "quality-assurance.event.table.funder": "الممول:", + + // "quality-assurance.event.table.fundingProgram": "Funding program:", "quality-assurance.event.table.fundingProgram": "برنامج التمويل:", - "quality-assurance.event.table.jurisdiction": "عدم التفويض:", - "quality-assurance.events.back": "العودة إلى المواضيع", - "quality-assurance.events.back-to-sources": "العودة إلى المصادر", + + // "quality-assurance.event.table.jurisdiction": "Jurisdiction:", + "quality-assurance.event.table.jurisdiction": "الاختصاص القضائي:", + + // "quality-assurance.events.back": "Back to topics", + "quality-assurance.events.back": "رجوع إلى المواضيع", + + // "quality-assurance.events.back-to-sources": "Back to sources", + // TODO New key - Add a translation + "quality-assurance.events.back-to-sources": "Back to sources", + + // "quality-assurance.event.table.less": "Show less", "quality-assurance.event.table.less": "عرض أقل", + + // "quality-assurance.event.table.more": "Show more", "quality-assurance.event.table.more": "عرض المزيد", - "quality-assurance.event.project.found": "الارتباط المحلي:", - "quality-assurance.event.project.notFound": "لم يتم العثور على تسجيل محلي", + + // "quality-assurance.event.project.found": "Bound to the local record:", + "quality-assurance.event.project.found": "ربط بالتسجيلة المحلية:", + + // "quality-assurance.event.project.notFound": "No local record found", + "quality-assurance.event.project.notFound": "لم يتم العثور على تسجيلة محلية", + + // "quality-assurance.event.sure": "Are you sure?", "quality-assurance.event.sure": "هل أنت متأكد؟", - "quality-assurance.event.ignore.description": "لا يمكن السماء عن هذه الطريقة. ", - "quality-assurance.event.undo.description": "لا يمكن التراجع عن هذه العملية!", - "quality-assurance.event.reject.description": "لا يمكن السماء عن هذه الطريقة. ", - "quality-assurance.event.accept.description": "لم يتم تحديد أي مشروع من التجسس. ", + + // "quality-assurance.event.ignore.description": "This operation can't be undone. Ignore this suggestion?", + "quality-assurance.event.ignore.description": "لا يمكن التراجع عن هذه العملية. تجاهل هذا الاقتراح؟", + + // "quality-assurance.event.undo.description": "This operation can't be undone!", + // TODO New key - Add a translation + "quality-assurance.event.undo.description": "This operation can't be undone!", + + // "quality-assurance.event.reject.description": "This operation can't be undone. Reject this suggestion?", + "quality-assurance.event.reject.description": "لا يمكن التراجع عن هذه العملية. هل ترفض هذا الاقتراح؟", + + // "quality-assurance.event.accept.description": "No DSpace project selected. A new project will be created based on the suggestion data.", + "quality-assurance.event.accept.description": "لم يتم تحديد أي مشروع دي سبيس. سيتم إنشاء مشروع جديد بناءً على بيانات الاقتراح.", + + // "quality-assurance.event.action.cancel": "Cancel", "quality-assurance.event.action.cancel": "إلغاء", - "quality-assurance.event.action.saved": "لقد تم حفظك الفعال.", - "quality-assurance.event.action.error": "حدث خطأ. ", - "quality-assurance.event.modal.project.title": "قم بإنشاء مشروعاً للربط", + + // "quality-assurance.event.action.saved": "Your decision has been saved successfully.", + "quality-assurance.event.action.saved": "لقد تم حفظ قرارك بنجاح.", + + // "quality-assurance.event.action.error": "An error has occurred. Your decision has not been saved.", + "quality-assurance.event.action.error": "حدث خطأ. لم يتم حفظ قرارك.", + + // "quality-assurance.event.modal.project.title": "Choose a project to bound", + "quality-assurance.event.modal.project.title": "اختر مشروعاً للربط", + + // "quality-assurance.event.modal.project.publication": "Publication:", "quality-assurance.event.modal.project.publication": "النشر:", - "quality-assurance.event.modal.project.bountToLocal": "الارتباط المحلي:", + + // "quality-assurance.event.modal.project.bountToLocal": "Bound to the local record:", + "quality-assurance.event.modal.project.bountToLocal": "ربط بالتسجيلة المحلية:", + + // "quality-assurance.event.modal.project.select": "Project search", "quality-assurance.event.modal.project.select": "بحث المشروع", + + // "quality-assurance.event.modal.project.search": "Search", "quality-assurance.event.modal.project.search": "بحث", - "quality-assurance.event.modal.project.clear": "تعديل التعديل", + + // "quality-assurance.event.modal.project.clear": "Clear", + "quality-assurance.event.modal.project.clear": "مسح", + + // "quality-assurance.event.modal.project.cancel": "Cancel", "quality-assurance.event.modal.project.cancel": "إلغاء", + + // "quality-assurance.event.modal.project.bound": "Bound project", "quality-assurance.event.modal.project.bound": "ربط المشروع", + + // "quality-assurance.event.modal.project.remove": "Remove", "quality-assurance.event.modal.project.remove": "إزالة", - "quality-assurance.event.modal.project.placeholder": "قم بتأكيد اسم المشروع", - "quality-assurance.event.modal.project.notFound": "لم يتم العثور على المشروع.", - "quality-assurance.event.project.bounded": "تم التركيب الفعال.", - "quality-assurance.event.project.removed": "تم إلغاء الربط الفعال.", - "quality-assurance.event.project.error": "حدث خطأ. ", - "quality-assurance.event.reason": "هذا", + + // "quality-assurance.event.modal.project.placeholder": "Enter a project name", + "quality-assurance.event.modal.project.placeholder": "قم بإدخال اسم المشروع", + + // "quality-assurance.event.modal.project.notFound": "No project found.", + "quality-assurance.event.modal.project.notFound": "لم يتم العثور على مشروع.", + + // "quality-assurance.event.project.bounded": "The project has been linked successfully.", + "quality-assurance.event.project.bounded": "تم ربط المشروع بنجاح.", + + // "quality-assurance.event.project.removed": "The project has been successfully unlinked.", + "quality-assurance.event.project.removed": "تم إلغاء ربط المشروع بنجاح.", + + // "quality-assurance.event.project.error": "An error has occurred. No operation performed.", + "quality-assurance.event.project.error": "حدث خطأ. لم يتم تنفيذ أي عملية.", + + // "quality-assurance.event.reason": "Reason", + "quality-assurance.event.reason": "السبب", + + // "orgunit.listelement.badge": "Organizational Unit", "orgunit.listelement.badge": "وحدة مؤسسية", + + // "orgunit.listelement.no-title": "Untitled", "orgunit.listelement.no-title": "بدون عنوان", + + // "orgunit.page.city": "City", "orgunit.page.city": "المدينة", + + // "orgunit.page.country": "Country", "orgunit.page.country": "البلد", + + // "orgunit.page.dateestablished": "Date established", "orgunit.page.dateestablished": "تاريخ التأسيس", + + // "orgunit.page.description": "Description", "orgunit.page.description": "الوصف", + + // "orgunit.page.edit": "Edit this item", "orgunit.page.edit": "تحرير هذه المادة", + + // "orgunit.page.id": "ID", "orgunit.page.id": "المعرف", - "orgunit.page.titleprefix": "الوحدة الوطنية: ", - "orgunit.page.ror": "معرف ROR", + + // "orgunit.page.titleprefix": "Organizational Unit: ", + "orgunit.page.titleprefix": "الوحدة المؤسسية: ", + + // "orgunit.page.ror": "ROR Identifier", + "orgunit.page.ror": "ROR معرف", + + // "pagination.options.description": "Pagination options", "pagination.options.description": "خيارات ترقيم الصفحات", + + // "pagination.results-per-page": "Results Per Page", "pagination.results-per-page": "النتائج لكل صفحة", + + // "pagination.showing.detail": "{{ range }} of {{ total }}", "pagination.showing.detail": "{{ range }} من {{ total }}", + + // "pagination.showing.label": "Now showing ", "pagination.showing.label": "يظهر الآن ", + + // "pagination.sort-direction": "Sort Options", "pagination.sort-direction": "خيارات الفرز", - "person.listelement.badge": "شخصي", - "person.listelement.no-title": "لم يتم العثور على الأسماء", - "person.page.birthdate": "تاريخ ميلادي", + + // "person.listelement.badge": "Person", + "person.listelement.badge": "شخص", + + // "person.listelement.no-title": "No name found", + "person.listelement.no-title": "لم يتم العثور على أسماء", + + // "person.page.birthdate": "Birth Date", + "person.page.birthdate": "تاريخ الميلاد الميلادي", + + // "person.page.edit": "Edit this item", "person.page.edit": "تحرير هذه المادة", + + // "person.page.email": "Email Address", "person.page.email": "عنوان البريد الإلكتروني", - "person.page.firstname": "الاسم الأول", - "person.page.jobtitle": "مسؤول وظيفي", + + // "person.page.firstname": "First Name", + // TODO New key - Add a translation + "person.page.firstname": "First Name", + + // "person.page.jobtitle": "Job Title", + "person.page.jobtitle": "المسمي الوظيفي", + + // "person.page.lastname": "Last Name", "person.page.lastname": "اسم العائلة", + + // "person.page.name": "Name", "person.page.name": "الاسم", - "person.page.link.full": "عرض كل الدعوات", + + // "person.page.link.full": "Show all metadata", + "person.page.link.full": "عرض كل الميتاداتا", + + // "person.page.orcid": "ORCID", "person.page.orcid": "أوركيد", + + // "person.page.staffid": "Staff ID", "person.page.staffid": "معرف الموظف", + + // "person.page.titleprefix": "Person: ", "person.page.titleprefix": "الشخص: ", + + // "person.search.results.head": "Person Search Results", "person.search.results.head": "نتائج بحث الشخص", + + // "person-relationships.search.results.head": "Person Search Results", "person-relationships.search.results.head": "نتائج بحث الشخص", + + // "person.search.title": "Person Search", "person.search.title": "بحث الشخص", - "process.new.select-parameters": "لا تزال", - "process.new.select-parameter": "تحديد النص", - "process.new.add-parameter": "إضافة نصوص...", - "process.new.delete-parameter": "حذف التقليد", + + // "process.new.select-parameters": "Parameters", + "process.new.select-parameters": "المتغيرات", + + // "process.new.select-parameter": "Select parameter", + "process.new.select-parameter": "تحديد متغير", + + // "process.new.add-parameter": "Add a parameter...", + "process.new.add-parameter": "إضافة متغير...", + + // "process.new.delete-parameter": "Delete parameter", + "process.new.delete-parameter": "حذف متغير", + + // "process.new.parameter.label": "Parameter value", "process.new.parameter.label": "قيمة المتغير", + + // "process.new.cancel": "Cancel", "process.new.cancel": "إلغاء", + + // "process.new.submit": "Save", "process.new.submit": "حفظ", + + // "process.new.select-script": "Script", "process.new.select-script": "نص", + + // "process.new.select-script.placeholder": "Choose a script...", "process.new.select-script.placeholder": "اختر نص...", + + // "process.new.select-script.required": "Script is required", "process.new.select-script.required": "النص مطلوب", + + // "process.new.parameter.file.upload-button": "Select file...", "process.new.parameter.file.upload-button": "اختر ملف...", - "process.new.parameter.file.required": "يرجى تحديد الملف", + + // "process.new.parameter.file.required": "Please select a file", + "process.new.parameter.file.required": "يرجى تحديد ملف", + + // "process.new.parameter.string.required": "Parameter value is required", "process.new.parameter.string.required": "قيمة المتغير مطلوبة", + + // "process.new.parameter.type.value": "value", "process.new.parameter.type.value": "القيمة", + + // "process.new.parameter.type.file": "file", "process.new.parameter.type.file": "ملف", - "process.new.parameter.required.missing": "التالية مطلوبة ولكنها لا تزال ناقصة:", + + // "process.new.parameter.required.missing": "The following parameters are required but still missing:", + "process.new.parameter.required.missing": "المتغيرات التالية مطلوبة ولكنها لا تزال ناقصة:", + + // "process.new.notification.success.title": "Success", "process.new.notification.success.title": "نجاح", - "process.new.notification.success.content": "تم إنشاء فعال", + + // "process.new.notification.success.content": "The process was successfully created", + "process.new.notification.success.content": "تم إنشاء العملية بنجاح", + + // "process.new.notification.error.title": "Error", "process.new.notification.error.title": "خطأ", - "process.new.notification.error.content": "حدث خطأ أثناء إنشاء الطريق", - "process.new.notification.error.max-upload.content": "السماح بالملف الأقصى لحجم التحميل", - "process.new.header": "إنشاء إنشاءات جديدة", - "process.new.title": "إنشاء إنشاءات جديدة", - "process.new.breadcrumbs": "إنشاء إنشاءات جديدة", - "process.detail.arguments": "لماذا", - "process.detail.arguments.empty": "لا تحتوي هذه الطريقة على أي أسباب", + + // "process.new.notification.error.content": "An error occurred while creating this process", + "process.new.notification.error.content": "حدث خطأ أثناء إنشاء العملية", + + // "process.new.notification.error.max-upload.content": "The file exceeds the maximum upload size", + "process.new.notification.error.max-upload.content": "يتجاوز الملف الحد الأقصى لحجم التحميل", + + // "process.new.header": "Create a new process", + "process.new.header": "إنشاء عملية جديدة", + + // "process.new.title": "Create a new process", + "process.new.title": "إنشاء عملية جديدة", + + // "process.new.breadcrumbs": "Create a new process", + "process.new.breadcrumbs": "إنشاء عملية جديدة", + + // "process.detail.arguments": "Arguments", + "process.detail.arguments": "حجج", + + // "process.detail.arguments.empty": "This process doesn't contain any arguments", + "process.detail.arguments.empty": "لا تحتوي هذه العملية على أي حجج", + + // "process.detail.back": "Back", "process.detail.back": "رجوع", - "process.detail.output": "مخرجات الطريقة", - "process.detail.logs.button": "استرجاع مخرجات الحرارة", + + // "process.detail.output": "Process Output", + "process.detail.output": "مخرجات العملية", + + // "process.detail.logs.button": "Retrieve process output", + "process.detail.logs.button": "استرجاع مخرجات العملية", + + // "process.detail.logs.loading": "Retrieving", "process.detail.logs.loading": "استرجاع", - "process.detail.logs.none": "ولا يوجد مخرجات لهذه الغاية", - "process.detail.output-files": "ملفات المنتج", - "process.detail.output-files.empty": "لا تحتوي على هذه الطريقة على أي من المواد التي تم إخراجها", + + // "process.detail.logs.none": "This process has no output", + "process.detail.logs.none": "لا توجد مخرجات لهذه العملية", + + // "process.detail.output-files": "Output Files", + "process.detail.output-files": "ملفات الإخراج", + + // "process.detail.output-files.empty": "This process doesn't contain any output files", + "process.detail.output-files.empty": "لا تحتوي هذه العملية على أي ملفات إخراج", + + // "process.detail.script": "Script", "process.detail.script": "النص", - "process.detail.title": "الطريقة: {{ id }} - {{ name }}", + + // "process.detail.title": "Process: {{ id }} - {{ name }}", + "process.detail.title": "العملية: {{ id }} - {{ name }}", + + // "process.detail.start-time": "Start time", "process.detail.start-time": "وقت البدء", - "process.detail.end-time": "انتهى الوقت", + + // "process.detail.end-time": "Finish time", + "process.detail.end-time": "وقت الانتهاء", + + // "process.detail.status": "Status", "process.detail.status": "الحالة", - "process.detail.create": "إنشاء طريقة مماثلة", + + // "process.detail.create": "Create similar process", + "process.detail.create": "إنشاء عملية مماثلة", + + // "process.detail.actions": "Actions", "process.detail.actions": "إجراءات", - "process.detail.delete.button": "حذف المعاملة", - "process.detail.delete.header": "حذف المعاملة", - "process.detail.delete.body": "هل أنت متأكد من أنك ترغب في الحذف الصحيح؟", + + // "process.detail.delete.button": "Delete process", + "process.detail.delete.button": "حذف العملية", + + // "process.detail.delete.header": "Delete process", + "process.detail.delete.header": "حذف العملية", + + // "process.detail.delete.body": "Are you sure you want to delete the current process?", + "process.detail.delete.body": "هل أنت متأكد من أنك تريد حذف العملية الحالية؟", + + // "process.detail.delete.cancel": "Cancel", "process.detail.delete.cancel": "إلغاء", - "process.detail.delete.confirm": "حذف المعاملة", - "process.detail.delete.success": "تم الحذف الفعال.", - "process.detail.delete.error": "حدث خطأ ما أثناء الحذف", - "process.detail.refreshing": "التحديث التلقائي…", - "process.overview.table.completed.info": "وقت الانتهاء (التوقيت العالمي المنسق)", - "process.overview.table.completed.title": "العمليات الناجحة", - "process.overview.table.empty": "لم يتم العثور على عمليات مطابقة.", - "process.overview.table.failed.info": "وقت الانتهاء (التوقيت العالمي المنسق)", - "process.overview.table.failed.title": "العمليات الفاشلة", - "process.overview.table.finish": "انتهى الوقت (التوقيت العالمي)", - "process.overview.table.id": "معرف الطريقة", + + // "process.detail.delete.confirm": "Delete process", + "process.detail.delete.confirm": "حذف العملية", + + // "process.detail.delete.success": "The process was successfully deleted.", + "process.detail.delete.success": "تم حذف العملية بنجاح.", + + // "process.detail.delete.error": "Something went wrong when deleting the process", + "process.detail.delete.error": "حدث خطأ ما أثناء حذف العملية", + + // "process.detail.refreshing": "Auto-refreshing…", + // TODO New key - Add a translation + "process.detail.refreshing": "Auto-refreshing…", + + // "process.overview.table.completed.info": "Finish time (UTC)", + // TODO New key - Add a translation + "process.overview.table.completed.info": "Finish time (UTC)", + + // "process.overview.table.completed.title": "Succeeded processes", + // TODO New key - Add a translation + "process.overview.table.completed.title": "Succeeded processes", + + // "process.overview.table.empty": "No matching processes found.", + // TODO New key - Add a translation + "process.overview.table.empty": "No matching processes found.", + + // "process.overview.table.failed.info": "Finish time (UTC)", + // TODO New key - Add a translation + "process.overview.table.failed.info": "Finish time (UTC)", + + // "process.overview.table.failed.title": "Failed processes", + // TODO New key - Add a translation + "process.overview.table.failed.title": "Failed processes", + + // "process.overview.table.finish": "Finish time (UTC)", + "process.overview.table.finish": "وقت الانتهاء (التوقيت العالمي)", + + // "process.overview.table.id": "Process ID", + "process.overview.table.id": "معرف العملية", + + // "process.overview.table.name": "Name", "process.overview.table.name": "الاسم", - "process.overview.table.running.info": "وقت البدء (التوقيت العالمي المنسق)", - "process.overview.table.running.title": "ادارة العمليات", - "process.overview.table.scheduled.info": "وقت الإنشاء (التوقيت العالمي المنسق)", - "process.overview.table.scheduled.title": "العمليات المجدولة", - "process.overview.table.start": "التوقيت (التوقيت العالمي)", + + // "process.overview.table.running.info": "Start time (UTC)", + // TODO New key - Add a translation + "process.overview.table.running.info": "Start time (UTC)", + + // "process.overview.table.running.title": "Running processes", + // TODO New key - Add a translation + "process.overview.table.running.title": "Running processes", + + // "process.overview.table.scheduled.info": "Creation time (UTC)", + // TODO New key - Add a translation + "process.overview.table.scheduled.info": "Creation time (UTC)", + + // "process.overview.table.scheduled.title": "Scheduled processes", + // TODO New key - Add a translation + "process.overview.table.scheduled.title": "Scheduled processes", + + // "process.overview.table.start": "Start time (UTC)", + "process.overview.table.start": "وقت البدء (التوقيت العالمي)", + + // "process.overview.table.status": "Status", "process.overview.table.status": "الحالة", + + // "process.overview.table.user": "User", "process.overview.table.user": "المستخدم", + + // "process.overview.title": "Processes Overview", "process.overview.title": "نظرة عامة على العمليات", + + // "process.overview.breadcrumbs": "Processes Overview", "process.overview.breadcrumbs": "نظرة عامة على العمليات", + + // "process.overview.new": "New", "process.overview.new": "جديد", + + // "process.overview.table.actions": "Actions", "process.overview.table.actions": "إجراءات", + + // "process.overview.delete": "Delete {{count}} processes", "process.overview.delete": "حذف {{count}} عملية", - "process.overview.delete-process": "حذف المعاملة", - "process.overview.delete.clear": "حذف التحديد والحذف", - "process.overview.delete.processing": "سيتم حذفه {{count}} عملية. ", - "process.overview.delete.body": "هل أنت متأكد أنك تريد الحذف {{count}} العملية؟", + + // "process.overview.delete-process": "Delete process", + "process.overview.delete-process": "حذف العملية", + + // "process.overview.delete.clear": "Clear delete selection", + "process.overview.delete.clear": "مسح تحديد الحذف", + + // "process.overview.delete.processing": "{{count}} process(es) are being deleted. Please wait for the deletion to fully complete. Note that this can take a while.", + "process.overview.delete.processing": "يجري حذف {{count}} عملية. يرجى الانتظار حتى يكتمل الحذف بالكامل. لاحظ أن ذلك قد يستغرق بعض الوقت.", + + // "process.overview.delete.body": "Are you sure you want to delete {{count}} process(es)?", + "process.overview.delete.body": "هل أنت متأكد أنك تريد حذف {{count}} عملية؟", + + // "process.overview.delete.header": "Delete processes", "process.overview.delete.header": "حذف العمليات", + + // "process.bulk.delete.error.head": "Error on deleteing process", "process.bulk.delete.error.head": "خطأ في عملية الحذف", - "process.bulk.delete.error.body": "لا يمكن حذف الطريقة ذات المعرفة {{processId}}. ", - "process.bulk.delete.success": "تم الحذف {{count}} فعالية فعالة", + + // "process.bulk.delete.error.body": "The process with ID {{processId}} could not be deleted. The remaining processes will continue being deleted. ", + "process.bulk.delete.error.body": "لا يمكن حذف العملية ذات المعرف {{processId}}. وسيستمر حذف العمليات المتبقية. ", + + // "process.bulk.delete.success": "{{count}} process(es) have been succesfully deleted", + "process.bulk.delete.success": "تم حذف {{count}} عملية بنجاح", + + // "profile.breadcrumbs": "Update Profile", "profile.breadcrumbs": "تحديث الملف الشخصي", + + // "profile.card.identify": "Identify", "profile.card.identify": "تعريف", + + // "profile.card.security": "Security", "profile.card.security": "الحماية والأمان", + + // "profile.form.submit": "Save", "profile.form.submit": "حفظ", - "profile.groups.head": "المجموعات التي تقترحها", - "profile.special.groups.head": "المجموعات التي تقترحها", + + // "profile.groups.head": "Authorization groups you belong to", + "profile.groups.head": "مجموعات التفويض التي تنتمي إليها", + + // "profile.special.groups.head": "Authorization special groups you belong to", + "profile.special.groups.head": "مجموعات التفويض الخاصة التي تنتمي إليها", + + // "profile.metadata.form.error.firstname.required": "First Name is required", "profile.metadata.form.error.firstname.required": "الاسم الأول مطلوب", + + // "profile.metadata.form.error.lastname.required": "Last Name is required", "profile.metadata.form.error.lastname.required": "اسم العائلة مطلوب", + + // "profile.metadata.form.label.email": "Email Address", "profile.metadata.form.label.email": "عنوان البريد الإلكتروني", + + // "profile.metadata.form.label.firstname": "First Name", "profile.metadata.form.label.firstname": "الاسم الأول", + + // "profile.metadata.form.label.language": "Language", "profile.metadata.form.label.language": "اللغة", + + // "profile.metadata.form.label.lastname": "Last Name", "profile.metadata.form.label.lastname": "اسم العائلة", - "profile.metadata.form.label.phone": "هاتف", - "profile.metadata.form.notifications.success.content": "تم حفظ التغييرات التي استخدمتها على الملف الشخصي.", + + // "profile.metadata.form.label.phone": "Contact Telephone", + "profile.metadata.form.label.phone": "هاتف الاتصال", + + // "profile.metadata.form.notifications.success.content": "Your changes to the profile were saved.", + "profile.metadata.form.notifications.success.content": "تم حفظ التغييرات التي أجريتها على الملف الشخصي.", + + // "profile.metadata.form.notifications.success.title": "Profile saved", "profile.metadata.form.notifications.success.title": "تم حفظ الملف الشخصي", - "profile.notifications.warning.no-changes.content": "لم يتم عمل أي تغييرات على الملف الشخصي.", + + // "profile.notifications.warning.no-changes.content": "No changes were made to the Profile.", + "profile.notifications.warning.no-changes.content": "لم يتم إجراء أي تغييرات على الملف الشخصي.", + + // "profile.notifications.warning.no-changes.title": "No changes", "profile.notifications.warning.no-changes.title": "لا توجد تغييرات", + + // "profile.security.form.error.matching-passwords": "The passwords do not match.", "profile.security.form.error.matching-passwords": "كلمات المرور غير متطابقة.", - "profile.security.form.info": "اختياريًا، يمكنك تسجيل كلمة مرور في القسم السفلي، وتأكيدها عن طريق كتابتها مرة أخرى في الشريط الثاني.", + + // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box.", + "profile.security.form.info": "اختيارياً، يمكنك إدخال كلمة مرور جديدة في المربع أدناه، وتأكيدها عن طريق كتابتها مرة أخرى في المربع الثاني.", + + // "profile.security.form.label.password": "Password", "profile.security.form.label.password": "كلمة المرور", - "profile.security.form.label.passwordrepeat": "إعادة الكتابة للتأكيد", + + // "profile.security.form.label.passwordrepeat": "Retype to confirm", + "profile.security.form.label.passwordrepeat": "أعد الكتابة للتأكيد", + + // "profile.security.form.label.current-password": "Current password", "profile.security.form.label.current-password": "كلمة المرور الحالية", - "profile.security.form.notifications.success.content": "تم حفظ التغييرات التي جربتها على كلمة المرور.", + + // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", + "profile.security.form.notifications.success.content": "تم حفظ التغييرات التي أجريتها على كلمة المرور.", + + // "profile.security.form.notifications.success.title": "Password saved", "profile.security.form.notifications.success.title": "تم حفظ كلمة المرور", + + // "profile.security.form.notifications.error.title": "Error changing passwords", "profile.security.form.notifications.error.title": "حدث خطأ أثناء تغيير كلمات المرور", - "profile.security.form.notifications.error.change-failed": "حدث خطأ أثناء محاولة تغيير كلمة المرور. ", - "profile.security.form.notifications.error.not-same": "كلمات الترويج المختلفة.", - "profile.security.form.notifications.error.general": "يرجى استخدام الأغراض المتعددة في نموذج الحماية والأمان.", + + // "profile.security.form.notifications.error.change-failed": "An error occurred while trying to change the password. Please check if the current password is correct.", + "profile.security.form.notifications.error.change-failed": "حدث خطأ أثناء محاولة تغيير كلمة المرور. يرجى التحقق مما إذا كانت كلمة المرور الحالية صحيحة.", + + // "profile.security.form.notifications.error.not-same": "The provided passwords are not the same.", + "profile.security.form.notifications.error.not-same": "كلمات المرور المقدمة مختلفة.", + + // "profile.security.form.notifications.error.general": "Please fill required fields of security form.", + "profile.security.form.notifications.error.general": "يرجى ملء الحقول المطلوبة في نموذج الحماية والأمان.", + + // "profile.title": "Update Profile", "profile.title": "تحديث الملف الشخصي", - "profile.card.researcher": "الملف للباحث الشخصي", - "project.listelement.badge": "مشروع باحث", + + // "profile.card.researcher": "Researcher Profile", + "profile.card.researcher": "الملف الشخصي للباحث", + + // "project.listelement.badge": "Research Project", + "project.listelement.badge": "مشروع الباحث", + + // "project.page.contributor": "Contributors", "project.page.contributor": "المساهمون", + + // "project.page.description": "Description", "project.page.description": "الوصف", + + // "project.page.edit": "Edit this item", "project.page.edit": "تحرير هذه المادة", - "project.page.expectedcompletion": "الاكمال المصيبة", - "project.page.funder": "الأمولين", + + // "project.page.expectedcompletion": "Expected Completion", + "project.page.expectedcompletion": "الإكمال المتوقع", + + // "project.page.funder": "Funders", + "project.page.funder": "الممولين", + + // "project.page.id": "ID", "project.page.id": "المعرف", - "project.page.keyword": "الكلمات الرئيسية", + + // "project.page.keyword": "Keywords", + "project.page.keyword": "كلمات رئيسية", + + // "project.page.status": "Status", "project.page.status": "الحالة", + + // "project.page.titleprefix": "Research Project: ", "project.page.titleprefix": "مشورع البحث: ", - "project.search.results.head": "نتائج البحث في المشروع", - "project-relationships.search.results.head": "نتائج البحث في المشروع", + + // "project.search.results.head": "Project Search Results", + "project.search.results.head": "نتائج بحث المشروع", + + // "project-relationships.search.results.head": "Project Search Results", + "project-relationships.search.results.head": "نتائج بحث المشروع", + + // "publication.listelement.badge": "Publication", "publication.listelement.badge": "النشر", + + // "publication.page.description": "Description", "publication.page.description": "الوصف", + + // "publication.page.edit": "Edit this item", "publication.page.edit": "تحرير هذه المادة", + + // "publication.page.journal-issn": "Journal ISSN", "publication.page.journal-issn": "ردمد الدورية", - "publication.page.journal-title": "عنوان الدوري", + + // "publication.page.journal-title": "Journal Title", + "publication.page.journal-title": "عنوان الدورية", + + // "publication.page.publisher": "Publisher", "publication.page.publisher": "الناشر", - "publication.page.titleprefix": "النشر: ", + + // "publication.page.titleprefix": "Publication: ", + "publication.page.titleprefix": "المنشور: ", + + // "publication.page.volume-title": "Volume Title", "publication.page.volume-title": "عنوان المجلد", + + // "publication.search.results.head": "Publication Search Results", "publication.search.results.head": "نتائج بحث المنشور", + + // "publication-relationships.search.results.head": "Publication Search Results", "publication-relationships.search.results.head": "نتائج بحث المنشور", - "publication.search.title": "بحثت في المنشور", + + // "publication.search.title": "Publication Search", + "publication.search.title": "بحث المنشور", + + // "media-viewer.next": "Next", "media-viewer.next": "التالي", - "media-viewer.previous": "السابقة", + + // "media-viewer.previous": "Previous", + "media-viewer.previous": "السابق", + + // "media-viewer.playlist": "Playlist", "media-viewer.playlist": "قائمة التشغيل", - "suggestion.loading": "تحميل ...", - "suggestion.title": "المطالبة بالنشر", - "suggestion.title.breadcrumbs": "المطالبة بالنشر", - "suggestion.targets.description": "أدناه يمكنك رؤية جميع الاقتراحات ", - "suggestion.targets": "الاقتراحات الحالية", - "suggestion.table.name": "اسم الباحث", - "suggestion.table.actions": "أجراءات", - "suggestion.button.review": "مراجعة {{ total }} اقتراحات)", - "suggestion.button.review.title": "مراجعة {{ total }} اقتراح (اقتراحات) ل ", - "suggestion.noTargets": "لم يتم العثور على هدف.", - "suggestion.target.error.service.retrieve": "حدث خطأ أثناء تحميل أهداف الاقتراح", - "suggestion.evidence.type": "يكتب", - "suggestion.evidence.score": "نتيجة", - "suggestion.evidence.notes": "ملحوظات", - "suggestion.approveAndImport": "الموافقة والاستيراد", - "suggestion.approveAndImport.success": "تم استيراد الاقتراح بنجاح. منظر.", - "suggestion.approveAndImport.bulk": "الموافقة والاستيراد المحدد", - "suggestion.approveAndImport.bulk.success": "{{ count }} تم استيراد الاقتراحات بنجاح ", - "suggestion.approveAndImport.bulk.error": "{{ count }} لم يتم استيراد الاقتراحات بسبب حدوث أخطاء غير متوقعة في الخادم", - "suggestion.ignoreSuggestion": "تجاهل الاقتراح", - "suggestion.ignoreSuggestion.success": "لقد تم تجاهل الاقتراح", - "suggestion.ignoreSuggestion.bulk": "تجاهل الاقتراح المحدد", - "suggestion.ignoreSuggestion.bulk.success": "{{ count }} لقد تم تجاهل الاقتراحات ", - "suggestion.ignoreSuggestion.bulk.error": "{{ count }} لم يتم تجاهل الاقتراحات بسبب أخطاء غير متوقعة في الخادم", - "suggestion.seeEvidence": "انظر الأدلة", - "suggestion.hideEvidence": "إخفاء الأدلة", - "suggestion.suggestionFor": "اقتراحات ل", - "suggestion.suggestionFor.breadcrumb": "اقتراحات ل {{ name }}", - "suggestion.source.openaire": "الرسم البياني أوبن إير", - "suggestion.from.source": "من ", - "suggestion.count.missing": "لم يتبق لديك أي مطالبات بالنشر", - "suggestion.totalScore": "مجموع النقاط", - "suggestion.type.openaire": "أوبن إير", + + // "suggestion.loading": "Loading ...", + // TODO New key - Add a translation + "suggestion.loading": "Loading ...", + + // "suggestion.title": "Publication Claim", + // TODO New key - Add a translation + "suggestion.title": "Publication Claim", + + // "suggestion.title.breadcrumbs": "Publication Claim", + // TODO New key - Add a translation + "suggestion.title.breadcrumbs": "Publication Claim", + + // "suggestion.targets.description": "Below you can see all the suggestions ", + // TODO New key - Add a translation + "suggestion.targets.description": "Below you can see all the suggestions ", + + // "suggestion.targets": "Current Suggestions", + // TODO New key - Add a translation + "suggestion.targets": "Current Suggestions", + + // "suggestion.table.name": "Researcher Name", + // TODO New key - Add a translation + "suggestion.table.name": "Researcher Name", + + // "suggestion.table.actions": "Actions", + // TODO New key - Add a translation + "suggestion.table.actions": "Actions", + + // "suggestion.button.review": "Review {{ total }} suggestion(s)", + // TODO New key - Add a translation + "suggestion.button.review": "Review {{ total }} suggestion(s)", + + // "suggestion.button.review.title": "Review {{ total }} suggestion(s) for ", + // TODO New key - Add a translation + "suggestion.button.review.title": "Review {{ total }} suggestion(s) for ", + + // "suggestion.noTargets": "No target found.", + // TODO New key - Add a translation + "suggestion.noTargets": "No target found.", + + // "suggestion.target.error.service.retrieve": "An error occurred while loading the Suggestion targets", + // TODO New key - Add a translation + "suggestion.target.error.service.retrieve": "An error occurred while loading the Suggestion targets", + + // "suggestion.evidence.type": "Type", + // TODO New key - Add a translation + "suggestion.evidence.type": "Type", + + // "suggestion.evidence.score": "Score", + // TODO New key - Add a translation + "suggestion.evidence.score": "Score", + + // "suggestion.evidence.notes": "Notes", + // TODO New key - Add a translation + "suggestion.evidence.notes": "Notes", + + // "suggestion.approveAndImport": "Approve & import", + // TODO New key - Add a translation + "suggestion.approveAndImport": "Approve & import", + + // "suggestion.approveAndImport.success": "The suggestion has been imported successfully. View.", + // TODO New key - Add a translation + "suggestion.approveAndImport.success": "The suggestion has been imported successfully. View.", + + // "suggestion.approveAndImport.bulk": "Approve & import Selected", + // TODO New key - Add a translation + "suggestion.approveAndImport.bulk": "Approve & import Selected", + + // "suggestion.approveAndImport.bulk.success": "{{ count }} suggestions have been imported successfully ", + // TODO New key - Add a translation + "suggestion.approveAndImport.bulk.success": "{{ count }} suggestions have been imported successfully ", + + // "suggestion.approveAndImport.bulk.error": "{{ count }} suggestions haven't been imported due to unexpected server errors", + // TODO New key - Add a translation + "suggestion.approveAndImport.bulk.error": "{{ count }} suggestions haven't been imported due to unexpected server errors", + + // "suggestion.ignoreSuggestion": "Ignore Suggestion", + // TODO New key - Add a translation + "suggestion.ignoreSuggestion": "Ignore Suggestion", + + // "suggestion.ignoreSuggestion.success": "The suggestion has been discarded", + // TODO New key - Add a translation + "suggestion.ignoreSuggestion.success": "The suggestion has been discarded", + + // "suggestion.ignoreSuggestion.bulk": "Ignore Suggestion Selected", + // TODO New key - Add a translation + "suggestion.ignoreSuggestion.bulk": "Ignore Suggestion Selected", + + // "suggestion.ignoreSuggestion.bulk.success": "{{ count }} suggestions have been discarded ", + // TODO New key - Add a translation + "suggestion.ignoreSuggestion.bulk.success": "{{ count }} suggestions have been discarded ", + + // "suggestion.ignoreSuggestion.bulk.error": "{{ count }} suggestions haven't been discarded due to unexpected server errors", + // TODO New key - Add a translation + "suggestion.ignoreSuggestion.bulk.error": "{{ count }} suggestions haven't been discarded due to unexpected server errors", + + // "suggestion.seeEvidence": "See evidence", + // TODO New key - Add a translation + "suggestion.seeEvidence": "See evidence", + + // "suggestion.hideEvidence": "Hide evidence", + // TODO New key - Add a translation + "suggestion.hideEvidence": "Hide evidence", + + // "suggestion.suggestionFor": "Suggestions for", + // TODO New key - Add a translation + "suggestion.suggestionFor": "Suggestions for", + + // "suggestion.suggestionFor.breadcrumb": "Suggestions for {{ name }}", + // TODO New key - Add a translation + "suggestion.suggestionFor.breadcrumb": "Suggestions for {{ name }}", + + // "suggestion.source.openaire": "OpenAIRE Graph", + // TODO New key - Add a translation + "suggestion.source.openaire": "OpenAIRE Graph", + + // "suggestion.from.source": "from the ", + // TODO New key - Add a translation + "suggestion.from.source": "from the ", + + // "suggestion.count.missing": "You have no publication claims left", + // TODO New key - Add a translation + "suggestion.count.missing": "You have no publication claims left", + + // "suggestion.totalScore": "Total Score", + // TODO New key - Add a translation + "suggestion.totalScore": "Total Score", + + // "suggestion.type.openaire": "OpenAIRE", + // TODO New key - Add a translation + "suggestion.type.openaire": "OpenAIRE", + + // "register-email.title": "New user registration", "register-email.title": "تسجيل مستخدم جديد", + + // "register-page.create-profile.header": "Create Profile", "register-page.create-profile.header": "إنشاء ملف شخصي", + + // "register-page.create-profile.identification.header": "Identify", "register-page.create-profile.identification.header": "تعريف", + + // "register-page.create-profile.identification.email": "Email Address", "register-page.create-profile.identification.email": "عنوان البريد الإلكتروني", + + // "register-page.create-profile.identification.first-name": "First Name *", "register-page.create-profile.identification.first-name": "الاسم الأول *", - "register-page.create-profile.identification.first-name.error": "يرجى الاتصال بالاسم الأول", + + // "register-page.create-profile.identification.first-name.error": "Please fill in a First Name", + "register-page.create-profile.identification.first-name.error": "يرجى إدخال الاسم الأول", + + // "register-page.create-profile.identification.last-name": "Last Name *", "register-page.create-profile.identification.last-name": "اسم العائلة *", - "register-page.create-profile.identification.last-name.error": "يرجى الاتصال باسم العائلة", + + // "register-page.create-profile.identification.last-name.error": "Please fill in a Last Name", + "register-page.create-profile.identification.last-name.error": "يرجى إدخال اسم العائلة", + + // "register-page.create-profile.identification.contact": "Contact Telephone", "register-page.create-profile.identification.contact": "الهاتف", + + // "register-page.create-profile.identification.language": "Language", "register-page.create-profile.identification.language": "اللغة", + + // "register-page.create-profile.security.header": "Security", "register-page.create-profile.security.header": "الحماية والأمان", - "register-page.create-profile.security.info": "يرجى الاتصال برقم المرور في الشريط أدناه، وتأكيدها عن طريق كتابها مرة أخرى في الشريط الثاني. ", + + // "register-page.create-profile.security.info": "Please enter a password in the box below, and confirm it by typing it again into the second box.", + "register-page.create-profile.security.info": "يرجى إدخال كلمة المرور في المربع أدناه، وتأكيدها عن طريق كتابتها مرة أخرى في المربع الثاني. يجب أن تتكون من ستة أحرف على الأقل.", + + // "register-page.create-profile.security.label.password": "Password *", "register-page.create-profile.security.label.password": "كلمة المرور *", - "register-page.create-profile.security.label.passwordrepeat": "خطة إعادة الكتابة للتأكيد *", - "register-page.create-profile.security.error.empty-password": "الرجاء الاتصال بكلمة المرور في النطاق أدناه.", - "register-page.create-profile.security.error.matching-passwords": "كلمتي الطلب التي قمت بتأكيدها غير متطابقتين.", + + // "register-page.create-profile.security.label.passwordrepeat": "Retype to confirm *", + "register-page.create-profile.security.label.passwordrepeat": "أعد الكتابة للتأكيد *", + + // "register-page.create-profile.security.error.empty-password": "Please enter a password in the box below.", + "register-page.create-profile.security.error.empty-password": "يرجى إدخال كلمة المرور في المربع أدناه.", + + // "register-page.create-profile.security.error.matching-passwords": "The passwords do not match.", + "register-page.create-profile.security.error.matching-passwords": "كلمتي المرور التي قمت بإدخالهما غير متطابقتين.", + + // "register-page.create-profile.submit": "Complete Registration", "register-page.create-profile.submit": "اكتمل التسجيل", + + // "register-page.create-profile.submit.error.content": "Something went wrong while registering a new user.", "register-page.create-profile.submit.error.content": "حدث خطأ ما أثناء تسجيل مستخدم جديد.", + + // "register-page.create-profile.submit.error.head": "Registration failed", "register-page.create-profile.submit.error.head": "فشل التسجيل", - "register-page.create-profile.submit.success.content": "تم التسجيل الفعال. ", + + // "register-page.create-profile.submit.success.content": "The registration was successful. You have been logged in as the created user.", + "register-page.create-profile.submit.success.content": "تم التسجيل بنجاح. لقد قمت بتسجيل الدخول كالمستخدم الذي تم إنشاؤه.", + + // "register-page.create-profile.submit.success.head": "Registration completed", "register-page.create-profile.submit.success.head": "اكتمل التسجيل", + + // "register-page.registration.header": "New user registration", "register-page.registration.header": "تسجيل مستخدم جديد", - "register-page.registration.info": "قام بتسجيل حساب للاشتراك في Vitten لتحديثات البريد الإلكتروني، المساهمة في منتجات جديدة إلى دي سبيس.", + + // "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + "register-page.registration.info": "قم بتسجيل حساب للاشتراك في حاويات لتحديثات البريد الإلكتروني، وتقديم مواد جديدة إلى دي سبيس.", + + // "register-page.registration.email": "Email Address *", "register-page.registration.email": "عنوان البريد الإلكتروني *", - "register-page.registration.email.error.required": "يرجى الاتصال بعنوان البريد الإلكتروني", - "register-page.registration.email.error.not-email-form": "يرجى الاتصال بعنوان بريد إلكتروني صالح.", - "register-page.registration.email.error.not-valid-domain": "استخدام البريد الإلكتروني بالنطاقات المخصصة: {{ domains }}", - "register-page.registration.email.hint": "تم التحقق من هذا العنوان نيكوله كاسم تسجيل الدخول الخاص بك.", + + // "register-page.registration.email.error.required": "Please fill in an email address", + "register-page.registration.email.error.required": "يرجى إدخال عنوان البريد الإلكتروني", + + // "register-page.registration.email.error.not-email-form": "Please fill in a valid email address.", + "register-page.registration.email.error.not-email-form": "يرجى إدخال عنوان بريد إلكتروني صالح.", + + // "register-page.registration.email.error.not-valid-domain": "Use email with allowed domains: {{ domains }}", + "register-page.registration.email.error.not-valid-domain": "استخدم البريد الإلكتروني بالنطاقات المسموح بها: {{ domains }}", + + // "register-page.registration.email.hint": "This address will be verified and used as your login name.", + "register-page.registration.email.hint": "سيتم التحقق من هذا العنوان واستخدامه كاسم تسجيل الدخول الخاص بك.", + + // "register-page.registration.submit": "Register", "register-page.registration.submit": "تسجيل", - "register-page.registration.success.head": "إرسال رسالة بريد إلكتروني مؤكدة", - "register-page.registration.success.content": "يتم إرسال رسالة بريد الإلكتروني إلى {{ email }} تحتوي على عنوان URL خاص ومتزايد من التعلميات.", - "register-page.registration.error.head": "حدث خطأ أثناء محاولة تسجيل البريد الإلكتروني", + + // "register-page.registration.success.head": "Verification email sent", + "register-page.registration.success.head": "تم إرسال رسالة تأكيد البريد الإلكتروني", + + // "register-page.registration.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + "register-page.registration.success.content": "تم إرسال رسالة بريد إلكتروني إلى {{ email }} تحتوي على عنوان URL خاص والمزيد من التعلميات.", + + // "register-page.registration.error.head": "Error when trying to register email", + "register-page.registration.error.head": "خطأ أثناء محاولة تسجيل البريد الإلكتروني", + + // "register-page.registration.error.content": "An error occured when registering the following email address: {{ email }}", "register-page.registration.error.content": "حدث خطأ أثناء تسجيل عنوان البريد الإلكتروني التالي: {{ email }}", + + // "register-page.registration.error.recaptcha": "Error when trying to authenticate with recaptcha", "register-page.registration.error.recaptcha": "حدث خطأ أثناء محاولة الاستيثاق باستخدام recaptcha", - "register-page.registration.google-recaptcha.must-accept-cookies": "للتسجيل، يجب عليك قبول ملفات تعريف الارتباط التسجيل و استعادة كلمة المرور (جوجل reCaptcha).", - "register-page.registration.error.maildomain": "عنوان البريد الإلكتروني غير موجود في قائمة النطاقات التي تناسب التسجيل. {{ domains }}", + + // "register-page.registration.google-recaptcha.must-accept-cookies": "In order to register you must accept the Registration and Password recovery (Google reCaptcha) cookies.", + "register-page.registration.google-recaptcha.must-accept-cookies": "للتسجيل، يجب عليك قبول ملفات تعريف ارتباط التسجيل واستعادة كلمة المرور (جوجل reCaptcha).", + + // "register-page.registration.error.maildomain": "This email address is not on the list of domains who can register. Allowed domains are {{ domains }}", + "register-page.registration.error.maildomain": "عنوان البريد الإلكتروني غير موجود في قائمة النطاقات التي يمكنها التسجيل. النطاقات المسموح بها هي {{ domains }}", + + // "register-page.registration.google-recaptcha.open-cookie-settings": "Open cookie settings", "register-page.registration.google-recaptcha.open-cookie-settings": "فتح إعدادات ملفات تعريف الارتباط", - "register-page.registration.google-recaptcha.notification.title": "جوجل ريكابتشا", + + // "register-page.registration.google-recaptcha.notification.title": "Google reCaptcha", + "register-page.registration.google-recaptcha.notification.title": "جوجل reCaptcha", + + // "register-page.registration.google-recaptcha.notification.message.error": "An error occurred during reCaptcha verification", "register-page.registration.google-recaptcha.notification.message.error": "حدث خطأ أثناء التحقق من reCaptcha", - "register-page.registration.google-recaptcha.notification.message.expired": "صلاحية التحقق. ", - "register-page.registration.info.maildomain": "يمكن تسجيل عقود لناوين البريد للنطاقات", - "relationships.add.error.relationship-type.content": "لا يمكن العثور على تطابق مناسب لنوع التوافق {{ type }} بين المادتين", - "relationships.add.error.server.content": "لقد ساعدت في خطأ", - "relationships.add.error.title": "غير قادر على الانضمام إلى إيران", + + // "register-page.registration.google-recaptcha.notification.message.expired": "Verification expired. Please verify again.", + "register-page.registration.google-recaptcha.notification.message.expired": "انتهت صلاحية التحقق. يرجى التحقق مرة أخرى.", + + // "register-page.registration.info.maildomain": "Accounts can be registered for mail addresses of the domains", + "register-page.registration.info.maildomain": "يمكن تسجيل الحسابات لعناوين البريد للنطاقات", + + // "relationships.add.error.relationship-type.content": "No suitable match could be found for relationship type {{ type }} between the two items", + "relationships.add.error.relationship-type.content": "لا يمكن العثور على تطابق مناسب لنوع العلاقة {{ type }} بين المادتين", + + // "relationships.add.error.server.content": "The server returned an error", + "relationships.add.error.server.content": "لقد أعاد الخادم خطأ", + + // "relationships.add.error.title": "Unable to add relationship", + "relationships.add.error.title": "غير قادر على إضافة العلاقة", + + // "relationships.isAuthorOf": "Authors", "relationships.isAuthorOf": "المؤلفين", - "relationships.isAuthorOf.Person": "المؤلفين (الأشخاص)", + + // "relationships.isAuthorOf.Person": "Authors (persons)", + "relationships.isAuthorOf.Person": "المؤلفين (أشخاص)", + + // "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", "relationships.isAuthorOf.OrgUnit": "المؤلفين (وحدات مؤسسية)", - "relationships.isIssueOf": "سجل الدوري", - "relationships.isIssueOf.JournalIssue": "عدد الدوري", - "relationships.isJournalIssueOf": "عدد الدوري", + + // "relationships.isIssueOf": "Journal Issues", + "relationships.isIssueOf": "أعداد الدورية", + + // "relationships.isIssueOf.JournalIssue": "Journal Issue", + "relationships.isIssueOf.JournalIssue": "عدد الدورية", + + // "relationships.isJournalIssueOf": "Journal Issue", + "relationships.isJournalIssueOf": "عدد الدورية", + + // "relationships.isJournalOf": "Journals", "relationships.isJournalOf": "الدوريات", - "relationships.isJournalVolumeOf": "سلسلة الدورية", + + // "relationships.isJournalVolumeOf": "Journal Volume", + "relationships.isJournalVolumeOf": "مجلد الدورية", + + // "relationships.isOrgUnitOf": "Organizational Units", "relationships.isOrgUnitOf": "وحدات مؤسسية", + + // "relationships.isPersonOf": "Authors", "relationships.isPersonOf": "المؤلفين", - "relationships.isProjectOf": "مشاريع البحث", + + // "relationships.isProjectOf": "Research Projects", + "relationships.isProjectOf": "مشروعات البحث", + + // "relationships.isPublicationOf": "Publications", "relationships.isPublicationOf": "منشورات", + + // "relationships.isPublicationOfJournalIssue": "Articles", "relationships.isPublicationOfJournalIssue": "مقالات", - "relationships.isSingleJournalOf": "الدوري", - "relationships.isSingleVolumeOf": "سلسلة الدورية", - "relationships.isVolumeOf": "سلسلة الدوريات", - "relationships.isVolumeOf.JournalVolume": "سلسلة الدورية", - "relationships.isContributorOf": "خذ", + + // "relationships.isSingleJournalOf": "Journal", + "relationships.isSingleJournalOf": "الدورية", + + // "relationships.isSingleVolumeOf": "Journal Volume", + "relationships.isSingleVolumeOf": "مجلد الدورية", + + // "relationships.isVolumeOf": "Journal Volumes", + "relationships.isVolumeOf": "مجلدات الدورية", + + // "relationships.isVolumeOf.JournalVolume": "Journal Volume", + "relationships.isVolumeOf.JournalVolume": "مجلد الدورية", + + // "relationships.isContributorOf": "Contributors", + "relationships.isContributorOf": "المساهمين", + + // "relationships.isContributorOf.OrgUnit": "Contributor (Organizational Unit)", "relationships.isContributorOf.OrgUnit": "المساهم (وحدة مؤسسية)", + + // "relationships.isContributorOf.Person": "Contributor", "relationships.isContributorOf.Person": "المساهم", + + // "relationships.isFundingAgencyOf.OrgUnit": "Funder", "relationships.isFundingAgencyOf.OrgUnit": "الممول", - "repository.image.logo": "مستودع الشعار", + + // "repository.image.logo": "Repository logo", + "repository.image.logo": "شعار المستودع", + + // "repository.title": "DSpace Repository", "repository.title": "مستودع دي سبيس", + + // "repository.title.prefix": "DSpace Repository :: ", "repository.title.prefix": "مستودع دي سبيس :: ", + + // "resource-policies.add.button": "Add", "resource-policies.add.button": "إضافة", - "resource-policies.add.for.": "إضافة جديدة", - "resource-policies.add.for.bitstream": "إضافة لمزيد من التدفق بت جديدة", - "resource-policies.add.for.bundle": "إضافة حزمة جديدة", - "resource-policies.add.for.item": "إضافة مادة جديدة", - "resource-policies.add.for.community": "اضافة الى مجتمع جديد", - "resource-policies.add.for.collection": "إضافة ابي كوبين جديدة", - "resource-policies.create.page.heading": "إنشاء أشياء جديدة لـ ", - "resource-policies.create.page.failure.content": "حدث خطأ أثناء إنشاء الموارد.", - "resource-policies.create.page.success.content": "فعال", - "resource-policies.create.page.title": "إنشاء أشياء جديدة", - "resource-policies.delete.btn": "حذف", - "resource-policies.delete.btn.title": "حذف الموارد المحددة", - "resource-policies.delete.failure.content": "حدث خطأ أثناء حذف سياسات المورد الهامة.", - "resource-policies.delete.success.content": "عملية", - "resource-policies.edit.page.heading": "تحرير بولي المورد ", - "resource-policies.edit.page.failure.content": "حدث خطأ أثناء تحرير المورد.", + + // "resource-policies.add.for.": "Add a new policy", + "resource-policies.add.for.": "إضافة سياسة جديدة", + + // "resource-policies.add.for.bitstream": "Add a new Bitstream policy", + "resource-policies.add.for.bitstream": "إضافة سياسة تدفق بت جديدة", + + // "resource-policies.add.for.bundle": "Add a new Bundle policy", + "resource-policies.add.for.bundle": "إضافة سياسة حزمة جديدة", + + // "resource-policies.add.for.item": "Add a new Item policy", + "resource-policies.add.for.item": "إضافة سياسة مادة جديدة", + + // "resource-policies.add.for.community": "Add a new Community policy", + "resource-policies.add.for.community": "إضافة سياسة مجتمع جديدة", + + // "resource-policies.add.for.collection": "Add a new Collection policy", + "resource-policies.add.for.collection": "إضافة سياسة حاوية جديدة", + + // "resource-policies.create.page.heading": "Create new resource policy for ", + "resource-policies.create.page.heading": "إنشاء سياسة موارد جديدة لـ ", + + // "resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.", + "resource-policies.create.page.failure.content": "حدث خطأ أثناء إنشاء سياسة الموارد.", + + // "resource-policies.create.page.success.content": "Operation successful", + "resource-policies.create.page.success.content": "تمت العملية بنجاح", + + // "resource-policies.create.page.title": "Create new resource policy", + "resource-policies.create.page.title": "إنشاء سياسة موارد جديدة", + + // "resource-policies.delete.btn": "Delete selected", + "resource-policies.delete.btn": "حذف المحدد", + + // "resource-policies.delete.btn.title": "Delete selected resource policies", + "resource-policies.delete.btn.title": "حذف سياسات الموارد المحددة", + + // "resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.", + "resource-policies.delete.failure.content": "حدث خطأ أثناء حذف سياسات المورد المحددة.", + + // "resource-policies.delete.success.content": "Operation successful", + "resource-policies.delete.success.content": "عملية ناجحة", + + // "resource-policies.edit.page.heading": "Edit resource policy ", + "resource-policies.edit.page.heading": "تحرير سياسة المورد ", + + // "resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.", + "resource-policies.edit.page.failure.content": "حدث خطأ أثناء تحرير سياسة المورد.", + + // "resource-policies.edit.page.target-failure.content": "An error occurred while editing the target (ePerson or group) of the resource policy.", "resource-policies.edit.page.target-failure.content": "حدث خطأ أثناء تحرير الهدف (الشخص الإلكتروني أو المجموعة) لسياسة الموارد.", - "resource-policies.edit.page.other-failure.content": "حدث خطأ أثناء تحرير الموارد. ", - "resource-policies.edit.page.success.content": "عملية", - "resource-policies.edit.page.title": "تحرير بولي المورد", + + // "resource-policies.edit.page.other-failure.content": "An error occurred while editing the resource policy. The target (ePerson or group) has been successfully updated.", + "resource-policies.edit.page.other-failure.content": "حدث خطأ أثناء تحرير سياسة الموارد. تم تحديث الهدف (الشخص الإلكتروني أو المجموعة) بنجاح.", + + // "resource-policies.edit.page.success.content": "Operation successful", + "resource-policies.edit.page.success.content": "عملية ناجحة", + + // "resource-policies.edit.page.title": "Edit resource policy", + "resource-policies.edit.page.title": "تحرير سياسة المورد", + + // "resource-policies.form.action-type.label": "Select the action type", "resource-policies.form.action-type.label": "تحديد نوع الإجراء", - "resource-policies.form.action-type.required": "يجب عليك تحديد إجراء إجراء المورد.", - "resource-policies.form.eperson-group-list.label": "الشخص الإلكتروني أو المجموعة التي يستفيد منها من هذه الامتيازات", + + // "resource-policies.form.action-type.required": "You must select the resource policy action.", + "resource-policies.form.action-type.required": "يجب عليك تحديد إجراء سياسة المورد.", + + // "resource-policies.form.eperson-group-list.label": "The eperson or group that will be granted the permission", + "resource-policies.form.eperson-group-list.label": "الشخص الإلكتروني أو المجموعة التي سيتم منحها هذه الصلاحية", + + // "resource-policies.form.eperson-group-list.select.btn": "Select", "resource-policies.form.eperson-group-list.select.btn": "تحديد", + + // "resource-policies.form.eperson-group-list.tab.eperson": "Search for a ePerson", "resource-policies.form.eperson-group-list.tab.eperson": "بحث عن شخص إلكتروني", - "resource-policies.form.eperson-group-list.tab.group": "بحثت عن مجموعة", - "resource-policies.form.eperson-group-list.table.headers.action": "صنع", + + // "resource-policies.form.eperson-group-list.tab.group": "Search for a group", + "resource-policies.form.eperson-group-list.tab.group": "بحث عن مجموعة", + + // "resource-policies.form.eperson-group-list.table.headers.action": "Action", + "resource-policies.form.eperson-group-list.table.headers.action": "إجراء", + + // "resource-policies.form.eperson-group-list.table.headers.id": "ID", "resource-policies.form.eperson-group-list.table.headers.id": "المعرف", + + // "resource-policies.form.eperson-group-list.table.headers.name": "Name", "resource-policies.form.eperson-group-list.table.headers.name": "الاسم", + + // "resource-policies.form.eperson-group-list.modal.header": "Cannot change type", "resource-policies.form.eperson-group-list.modal.header": "لا يمكن تغيير النوع", - "resource-policies.form.eperson-group-list.modal.text1.toGroup": "لا يمكن استبدال الشخص الحياتي.", - "resource-policies.form.eperson-group-list.modal.text1.toEPerson": "لا يمكن استبدال مجموعة الإلكترونيات الشخصية.", - "resource-policies.form.eperson-group-list.modal.text2": "قم بحذف طلبات الموارد الحالية ونقلها بالنوع المطلوب.", - "resource-policies.form.eperson-group-list.modal.close": "حسنًا", + + // "resource-policies.form.eperson-group-list.modal.text1.toGroup": "It is not possible to replace an ePerson with a group.", + "resource-policies.form.eperson-group-list.modal.text1.toGroup": "لا يمكن استبدال الشخص الإلكتروني بمجموعة.", + + // "resource-policies.form.eperson-group-list.modal.text1.toEPerson": "It is not possible to replace a group with an ePerson.", + "resource-policies.form.eperson-group-list.modal.text1.toEPerson": "لا يمكن استبدال مجموعة بشخص إلكتروني.", + + // "resource-policies.form.eperson-group-list.modal.text2": "Delete the current resource policy and create a new one with the desired type.", + "resource-policies.form.eperson-group-list.modal.text2": "قم بحذف سياسة الموارد الحالية وإنشاء سياسة جديدة بالنوع المطلوب.", + + // "resource-policies.form.eperson-group-list.modal.close": "Ok", + "resource-policies.form.eperson-group-list.modal.close": "موافق", + + // "resource-policies.form.date.end.label": "End Date", "resource-policies.form.date.end.label": "تاريخ الانتهاء", - "resource-policies.form.date.start.label": "تاريخ الميلاد", + + // "resource-policies.form.date.start.label": "Start Date", + "resource-policies.form.date.start.label": "تاريخ البدء", + + // "resource-policies.form.description.label": "Description", "resource-policies.form.description.label": "الوصف", + + // "resource-policies.form.name.label": "Name", "resource-policies.form.name.label": "الاسم", + + // "resource-policies.form.policy-type.label": "Select the policy type", "resource-policies.form.policy-type.label": "حدد نوع السياسة", - "resource-policies.form.policy-type.required": "يجب عليك تحديد نوع أبو الموارد.", - "resource-policies.table.headers.action": "صنع", + + // "resource-policies.form.policy-type.required": "You must select the resource policy type.", + "resource-policies.form.policy-type.required": "يجب عليك تحديد نوع سياسة الموارد.", + + // "resource-policies.table.headers.action": "Action", + "resource-policies.table.headers.action": "إجراء", + + // "resource-policies.table.headers.date.end": "End Date", "resource-policies.table.headers.date.end": "تاريخ الانتهاء", - "resource-policies.table.headers.date.start": "تاريخ الميلاد", + + // "resource-policies.table.headers.date.start": "Start Date", + "resource-policies.table.headers.date.start": "تاريخ البدء", + + // "resource-policies.table.headers.edit": "Edit", "resource-policies.table.headers.edit": "تحرير", + + // "resource-policies.table.headers.edit.group": "Edit group", "resource-policies.table.headers.edit.group": "تحرير المجموعة", + + // "resource-policies.table.headers.edit.policy": "Edit policy", "resource-policies.table.headers.edit.policy": "تحرير السياسة", + + // "resource-policies.table.headers.eperson": "EPerson", "resource-policies.table.headers.eperson": "شخص إلكتروني", + + // "resource-policies.table.headers.group": "Group", "resource-policies.table.headers.group": "المجموعة", + + // "resource-policies.table.headers.select-all": "Select all", "resource-policies.table.headers.select-all": "تحديد الكل", + + // "resource-policies.table.headers.deselect-all": "Deselect all", "resource-policies.table.headers.deselect-all": "إلغاء تحديد الكل", + + // "resource-policies.table.headers.select": "Select", "resource-policies.table.headers.select": "تحديد", - "resource-policies.table.headers.deselect": "قم بإلغاء التحديد", + + // "resource-policies.table.headers.deselect": "Deselect", + "resource-policies.table.headers.deselect": "إلغاء تحديد", + + // "resource-policies.table.headers.id": "ID", "resource-policies.table.headers.id": "المعرف", + + // "resource-policies.table.headers.name": "Name", "resource-policies.table.headers.name": "الاسم", + + // "resource-policies.table.headers.policyType": "type", "resource-policies.table.headers.policyType": "النوع", - "resource-policies.table.headers.title.for.bitstream": "سياسة تدفق البت", + + // "resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream", + "resource-policies.table.headers.title.for.bitstream": "سياسات تدفق البت", + + // "resource-policies.table.headers.title.for.bundle": "Policies for Bundle", "resource-policies.table.headers.title.for.bundle": "سياسات الحزمة", - "resource-policies.table.headers.title.for.item": "هذه المادة", - "resource-policies.table.headers.title.for.community": "سياسة المجتمع", - "resource-policies.table.headers.title.for.collection": "تمام", + + // "resource-policies.table.headers.title.for.item": "Policies for Item", + "resource-policies.table.headers.title.for.item": "سياسات المادة", + + // "resource-policies.table.headers.title.for.community": "Policies for Community", + "resource-policies.table.headers.title.for.community": "سياسات المجتمع", + + // "resource-policies.table.headers.title.for.collection": "Policies for Collection", + "resource-policies.table.headers.title.for.collection": "سياسات الحاوية", + + // "root.skip-to-content": "Skip to main content", "root.skip-to-content": "انتقل إلى المحتوى الرئيسي", + + // "search.description": "", "search.description": "", + + // "search.switch-configuration.title": "Show", "search.switch-configuration.title": "عرض", + + // "search.title": "Search", "search.title": "بحث", + + // "search.breadcrumbs": "Search", "search.breadcrumbs": "بحث", - "search.search-form.placeholder": "بحث المستودع...", - "search.filters.remove": "إزالة المنقح من النوع {{ type }} د {{ value }}", + + // "search.search-form.placeholder": "Search the repository ...", + "search.search-form.placeholder": "بحث المستودع ...", + + // "search.filters.remove": "Remove filter of type {{ type }} with value {{ value }}", + "search.filters.remove": "إزالة المنقح من النوع {{ type }} بقيمة {{ value }}", + + // "search.filters.applied.f.author": "Author", "search.filters.applied.f.author": "المؤلف", + + // "search.filters.applied.f.dateIssued.max": "End date", "search.filters.applied.f.dateIssued.max": "تاريخ الانتهاء", - "search.filters.applied.f.dateIssued.min": "تاريخ الميلاد", - "search.filters.applied.f.dateSubmitted": "التاريخ", - "search.filters.applied.f.discoverable": "غير للاكتشاف", + + // "search.filters.applied.f.dateIssued.min": "Start date", + "search.filters.applied.f.dateIssued.min": "تاريخ البدء", + + // "search.filters.applied.f.dateSubmitted": "Date submitted", + "search.filters.applied.f.dateSubmitted": "تاريخ التقديم", + + // "search.filters.applied.f.discoverable": "Non-discoverable", + "search.filters.applied.f.discoverable": "غير قابل للاكتشاف", + + // "search.filters.applied.f.entityType": "Item Type", "search.filters.applied.f.entityType": "نوع المادة", + + // "search.filters.applied.f.has_content_in_original_bundle": "Has files", "search.filters.applied.f.has_content_in_original_bundle": "بها ملفات", + + // "search.filters.applied.f.itemtype": "Type", "search.filters.applied.f.itemtype": "النوع", + + // "search.filters.applied.f.namedresourcetype": "Status", "search.filters.applied.f.namedresourcetype": "الحالة", - "search.filters.applied.f.subject": "بدلا", - "search.filters.applied.f.submitter": "شير", + + // "search.filters.applied.f.subject": "Subject", + "search.filters.applied.f.subject": "الموضع", + + // "search.filters.applied.f.submitter": "Submitter", + "search.filters.applied.f.submitter": "المقدم", + + // "search.filters.applied.f.jobTitle": "Job Title", "search.filters.applied.f.jobTitle": "المسمى الوظيفي", + + // "search.filters.applied.f.birthDate.max": "End birth date", "search.filters.applied.f.birthDate.max": "نهاية تاريخ الميلاد", + + // "search.filters.applied.f.birthDate.min": "Start birth date", "search.filters.applied.f.birthDate.min": "بداية تاريخ الميلاد", - "search.filters.applied.f.supervisedBy": "تحت النار", + + // "search.filters.applied.f.supervisedBy": "Supervised by", + "search.filters.applied.f.supervisedBy": "تحت إشراف", + + // "search.filters.applied.f.withdrawn": "Withdrawn", "search.filters.applied.f.withdrawn": "مسحوب", + + // "search.filters.filter.author.head": "Author", "search.filters.filter.author.head": "المؤلف", + + // "search.filters.filter.author.placeholder": "Author name", "search.filters.filter.author.placeholder": "اسم المؤلف", - "search.filters.filter.author.label": "بحثت باسم المؤلف", - "search.filters.filter.birthDate.head": "تاريخ", - "search.filters.filter.birthDate.placeholder": "تاريخ", - "search.filters.filter.birthDate.label": "تمت مناقشة تاريخ الميلاد", + + // "search.filters.filter.author.label": "Search author name", + "search.filters.filter.author.label": "بحث اسم المؤلف", + + // "search.filters.filter.birthDate.head": "Birth Date", + "search.filters.filter.birthDate.head": "تاريخ الميلاد", + + // "search.filters.filter.birthDate.placeholder": "Birth Date", + "search.filters.filter.birthDate.placeholder": "تاريخ الميلاد", + + // "search.filters.filter.birthDate.label": "Search birth date", + "search.filters.filter.birthDate.label": "بحث تاريخ الميلاد", + + // "search.filters.filter.collapse": "Collapse filter", "search.filters.filter.collapse": "طي المنقح", + + // "search.filters.filter.creativeDatePublished.head": "Date Published", "search.filters.filter.creativeDatePublished.head": "تاريخ النشر", + + // "search.filters.filter.creativeDatePublished.placeholder": "Date Published", "search.filters.filter.creativeDatePublished.placeholder": "تاريخ النشر", + + // "search.filters.filter.creativeDatePublished.label": "Search date published", "search.filters.filter.creativeDatePublished.label": "بحث تاريخ النشر", + + // "search.filters.filter.creativeWorkEditor.head": "Editor", "search.filters.filter.creativeWorkEditor.head": "المحرر", + + // "search.filters.filter.creativeWorkEditor.placeholder": "Editor", "search.filters.filter.creativeWorkEditor.placeholder": "المحرر", - "search.filters.filter.creativeWorkEditor.label": "المحرر المحرر", + + // "search.filters.filter.creativeWorkEditor.label": "Search editor", + "search.filters.filter.creativeWorkEditor.label": "بحث المحرر", + + // "search.filters.filter.creativeWorkKeywords.head": "Subject", "search.filters.filter.creativeWorkKeywords.head": "الموضوع", + + // "search.filters.filter.creativeWorkKeywords.placeholder": "Subject", "search.filters.filter.creativeWorkKeywords.placeholder": "الموضوع", - "search.filters.filter.creativeWorkKeywords.label": "موضوع البحث", + + // "search.filters.filter.creativeWorkKeywords.label": "Search subject", + "search.filters.filter.creativeWorkKeywords.label": "بحث الموضوع", + + // "search.filters.filter.creativeWorkPublisher.head": "Publisher", "search.filters.filter.creativeWorkPublisher.head": "الناشر", + + // "search.filters.filter.creativeWorkPublisher.placeholder": "Publisher", "search.filters.filter.creativeWorkPublisher.placeholder": "الناشر", + + // "search.filters.filter.creativeWorkPublisher.label": "Search publisher", "search.filters.filter.creativeWorkPublisher.label": "بحث الناشر", + + // "search.filters.filter.dateIssued.head": "Date", "search.filters.filter.dateIssued.head": "التاريخ", + + // "search.filters.filter.dateIssued.max.placeholder": "Maximum Date", "search.filters.filter.dateIssued.max.placeholder": "الحد الأقصى للتاريخ", - "search.filters.filter.dateIssued.max.label": "تنتهي", - "search.filters.filter.dateIssued.min.placeholder": "الحد للتاريخ", - "search.filters.filter.dateIssued.min.label": "المبتدئ", - "search.filters.filter.dateSubmitted.head": "التاريخ", - "search.filters.filter.dateSubmitted.placeholder": "التاريخ", - "search.filters.filter.dateSubmitted.label": "تاريخ العرض", - "search.filters.filter.discoverable.head": "غير للاكتشاف", + + // "search.filters.filter.dateIssued.max.label": "End", + "search.filters.filter.dateIssued.max.label": "انتهاء", + + // "search.filters.filter.dateIssued.min.placeholder": "Minimum Date", + "search.filters.filter.dateIssued.min.placeholder": "الحد الأدنى للتاريخ", + + // "search.filters.filter.dateIssued.min.label": "Start", + "search.filters.filter.dateIssued.min.label": "البدء", + + // "search.filters.filter.dateSubmitted.head": "Date submitted", + "search.filters.filter.dateSubmitted.head": "تاريخ التقديم", + + // "search.filters.filter.dateSubmitted.placeholder": "Date submitted", + "search.filters.filter.dateSubmitted.placeholder": "تاريخ التقديم", + + // "search.filters.filter.dateSubmitted.label": "Search date submitted", + "search.filters.filter.dateSubmitted.label": "بحث تاريخ التقديم", + + // "search.filters.filter.discoverable.head": "Non-discoverable", + "search.filters.filter.discoverable.head": "غير قابل للاكتشاف", + + // "search.filters.filter.withdrawn.head": "Withdrawn", "search.filters.filter.withdrawn.head": "مسحوب", + + // "search.filters.filter.entityType.head": "Item Type", "search.filters.filter.entityType.head": "نوع المادة", + + // "search.filters.filter.entityType.placeholder": "Item Type", "search.filters.filter.entityType.placeholder": "نوع المادة", - "search.filters.filter.entityType.label": "تمت مناقشة نوع المادة", - "search.filters.filter.expand": "الأوقات المنقحة", + + // "search.filters.filter.entityType.label": "Search item type", + "search.filters.filter.entityType.label": "بحث نوع المادة", + + // "search.filters.filter.expand": "Expand filter", + "search.filters.filter.expand": "توسيع المنقح", + + // "search.filters.filter.has_content_in_original_bundle.head": "Has files", "search.filters.filter.has_content_in_original_bundle.head": "بها ملفات", + + // "search.filters.filter.itemtype.head": "Type", "search.filters.filter.itemtype.head": "النوع", + + // "search.filters.filter.itemtype.placeholder": "Type", "search.filters.filter.itemtype.placeholder": "النوع", + + // "search.filters.filter.itemtype.label": "Search type", "search.filters.filter.itemtype.label": "بحث النوع", + + // "search.filters.filter.jobTitle.head": "Job Title", "search.filters.filter.jobTitle.head": "المسمى الوظيفي", + + // "search.filters.filter.jobTitle.placeholder": "Job Title", "search.filters.filter.jobTitle.placeholder": "المسمى الوظيفي", - "search.filters.filter.jobTitle.label": "بحث في المسمى الوظيفي", + + // "search.filters.filter.jobTitle.label": "Search job title", + "search.filters.filter.jobTitle.label": "بحث المسمى الوظيفي", + + // "search.filters.filter.knowsLanguage.head": "Known language", "search.filters.filter.knowsLanguage.head": "لغة معروفة", + + // "search.filters.filter.knowsLanguage.placeholder": "Known language", "search.filters.filter.knowsLanguage.placeholder": "لغة معروفة", - "search.filters.filter.knowsLanguage.label": "اتصل بـ اسم معروف", + + // "search.filters.filter.knowsLanguage.label": "Search known language", + "search.filters.filter.knowsLanguage.label": "بحث لغة معروفة", + + // "search.filters.filter.namedresourcetype.head": "Status", "search.filters.filter.namedresourcetype.head": "الحالة", + + // "search.filters.filter.namedresourcetype.placeholder": "Status", "search.filters.filter.namedresourcetype.placeholder": "الحالة", - "search.filters.filter.namedresourcetype.label": "الحالة المدروسة", - "search.filters.filter.objectpeople.head": "الأشخاص", - "search.filters.filter.objectpeople.placeholder": "الأشخاص", - "search.filters.filter.objectpeople.label": "بحث الناس", + + // "search.filters.filter.namedresourcetype.label": "Search status", + "search.filters.filter.namedresourcetype.label": "بحث الحالة", + + // "search.filters.filter.objectpeople.head": "People", + "search.filters.filter.objectpeople.head": "أشخاص", + + // "search.filters.filter.objectpeople.placeholder": "People", + "search.filters.filter.objectpeople.placeholder": "أشخاص", + + // "search.filters.filter.objectpeople.label": "Search people", + "search.filters.filter.objectpeople.label": "بحث الأشخاص", + + // "search.filters.filter.organizationAddressCountry.head": "Country", "search.filters.filter.organizationAddressCountry.head": "البلد", + + // "search.filters.filter.organizationAddressCountry.placeholder": "Country", "search.filters.filter.organizationAddressCountry.placeholder": "البلد", + + // "search.filters.filter.organizationAddressCountry.label": "Search country", "search.filters.filter.organizationAddressCountry.label": "بحث البلد", + + // "search.filters.filter.organizationAddressLocality.head": "City", "search.filters.filter.organizationAddressLocality.head": "المدينة", + + // "search.filters.filter.organizationAddressLocality.placeholder": "City", "search.filters.filter.organizationAddressLocality.placeholder": "المدينة", - "search.filters.filter.organizationAddressLocality.label": "بحثت المدينة", + + // "search.filters.filter.organizationAddressLocality.label": "Search city", + "search.filters.filter.organizationAddressLocality.label": "بحث المدينة", + + // "search.filters.filter.organizationFoundingDate.head": "Date Founded", "search.filters.filter.organizationFoundingDate.head": "تاريخ التأسيس", + + // "search.filters.filter.organizationFoundingDate.placeholder": "Date Founded", "search.filters.filter.organizationFoundingDate.placeholder": "تاريخ التأسيس", - "search.filters.filter.organizationFoundingDate.label": "بحثت في تاريخها", + + // "search.filters.filter.organizationFoundingDate.label": "Search date founded", + "search.filters.filter.organizationFoundingDate.label": "بحث تاريخ التأسيس", + + // "search.filters.filter.scope.head": "Scope", "search.filters.filter.scope.head": "النطاق", + + // "search.filters.filter.scope.placeholder": "Scope filter", "search.filters.filter.scope.placeholder": "منقح النطاق", + + // "search.filters.filter.scope.label": "Search scope filter", "search.filters.filter.scope.label": "منقح نطاق البحث", - "search.filters.filter.show-less": "طيء", + + // "search.filters.filter.show-less": "Collapse", + "search.filters.filter.show-less": "طي", + + // "search.filters.filter.show-more": "Show more", "search.filters.filter.show-more": "عرض المزيد", + + // "search.filters.filter.subject.head": "Subject", "search.filters.filter.subject.head": "الموضوع", + + // "search.filters.filter.subject.placeholder": "Subject", "search.filters.filter.subject.placeholder": "الموضوع", - "search.filters.filter.subject.label": "موضوع البحث", - "search.filters.filter.submitter.head": "شير", - "search.filters.filter.submitter.placeholder": "شير", + + // "search.filters.filter.subject.label": "Search subject", + "search.filters.filter.subject.label": "بحث الموضوع", + + // "search.filters.filter.submitter.head": "Submitter", + "search.filters.filter.submitter.head": "المقدم", + + // "search.filters.filter.submitter.placeholder": "Submitter", + "search.filters.filter.submitter.placeholder": "المقدم", + + // "search.filters.filter.submitter.label": "Search submitter", "search.filters.filter.submitter.label": "مقدم البحث", + + // "search.filters.filter.show-tree": "Browse {{ name }} tree", "search.filters.filter.show-tree": "استعراض شجرة {{ name }}", - "search.filters.filter.funding.head": "تمويل", - "search.filters.filter.funding.placeholder": "تمويل", - "search.filters.filter.supervisedBy.head": "تحت النار", - "search.filters.filter.supervisedBy.placeholder": "تحت النار", - "search.filters.filter.supervisedBy.label": "ابحث تحت البحث", - "search.filters.entityType.JournalIssue": "عدد الدوري", - "search.filters.entityType.JournalVolume": "سلسلة الدورية", + + // "search.filters.filter.funding.head": "Funding", + "search.filters.filter.funding.head": "التمويل", + + // "search.filters.filter.funding.placeholder": "Funding", + "search.filters.filter.funding.placeholder": "التمويل", + + // "search.filters.filter.supervisedBy.head": "Supervised By", + "search.filters.filter.supervisedBy.head": "تحت إشراف", + + // "search.filters.filter.supervisedBy.placeholder": "Supervised By", + "search.filters.filter.supervisedBy.placeholder": "تحت إشراف", + + // "search.filters.filter.supervisedBy.label": "Search Supervised By", + "search.filters.filter.supervisedBy.label": "البحث تحت إشراف", + + // "search.filters.entityType.JournalIssue": "Journal Issue", + "search.filters.entityType.JournalIssue": "عدد الدورية", + + // "search.filters.entityType.JournalVolume": "Journal Volume", + "search.filters.entityType.JournalVolume": "مجلد الدورية", + + // "search.filters.entityType.OrgUnit": "Organizational Unit", "search.filters.entityType.OrgUnit": "وحدة مؤسسية", - "search.filters.entityType.Person": "شخص", - "search.filters.entityType.Project": "مشروع", - "search.filters.entityType.Publication": "النشر", + + // "search.filters.entityType.Person": "Person", + // TODO New key - Add a translation + "search.filters.entityType.Person": "Person", + + // "search.filters.entityType.Project": "Project", + // TODO New key - Add a translation + "search.filters.entityType.Project": "Project", + + // "search.filters.entityType.Publication": "Publication", + // TODO New key - Add a translation + "search.filters.entityType.Publication": "Publication", + + // "search.filters.has_content_in_original_bundle.true": "Yes", "search.filters.has_content_in_original_bundle.true": "نعم", + + // "search.filters.has_content_in_original_bundle.false": "No", "search.filters.has_content_in_original_bundle.false": "لا", + + // "search.filters.discoverable.true": "No", "search.filters.discoverable.true": "لا", + + // "search.filters.discoverable.false": "Yes", "search.filters.discoverable.false": "نعم", + + // "search.filters.namedresourcetype.Archived": "Archived", "search.filters.namedresourcetype.Archived": "مؤرشف", + + // "search.filters.namedresourcetype.Validation": "Validation", "search.filters.namedresourcetype.Validation": "التحقق من الصحة", + + // "search.filters.namedresourcetype.Waiting for Controller": "Waiting for reviewer", "search.filters.namedresourcetype.Waiting for Controller": "في انتظار المراجع", + + // "search.filters.namedresourcetype.Workflow": "Workflow", "search.filters.namedresourcetype.Workflow": "سير العمل", + + // "search.filters.namedresourcetype.Workspace": "Workspace", "search.filters.namedresourcetype.Workspace": "مساحة العمل", + + // "search.filters.withdrawn.true": "Yes", "search.filters.withdrawn.true": "نعم", + + // "search.filters.withdrawn.false": "No", "search.filters.withdrawn.false": "لا", + + // "search.filters.head": "Filters", "search.filters.head": "المنقحات", - "search.filters.reset": "إعادة تعيين المقحات", + + // "search.filters.reset": "Reset filters", + "search.filters.reset": "إعادة تعيين المنقحات", + + // "search.filters.search.submit": "Submit", "search.filters.search.submit": "تقديم", + + // "search.form.search": "Search", "search.form.search": "بحث", + + // "search.form.search_dspace": "All repository", "search.form.search_dspace": "كل المستودع", + + // "search.form.scope.all": "All of DSpace", "search.form.scope.all": "كل دي سبيس", + + // "search.results.head": "Search Results", "search.results.head": "نتائج البحث", - "search.results.no-results": "لم أسافر لبحثك عن أي نتائج. ", - "search.results.no-results-link": "راسي نص حوله", - "search.results.empty": "لم أسافر لبحثك عن أي نتائج.", + + // "search.results.no-results": "Your search returned no results. Having trouble finding what you're looking for? Try putting", + "search.results.no-results": "لم يسفر بحثك عن أي نتائج. هل تجد صعوبة في العثور على ما تبحث عنه؟ جرب وضع", + + // "search.results.no-results-link": "quotes around it", + "search.results.no-results-link": "قوسي نص حوله", + + // "search.results.empty": "Your search returned no results.", + "search.results.empty": "لم يسفر بحثك عن أي نتائج.", + + // "search.results.view-result": "View", "search.results.view-result": "عرض", - "search.results.response.500": "حدث خطأ أثناء التخطيط، يرجى إعادة محاولة مرة أخرى لاحقاً", + + // "search.results.response.500": "An error occurred during query execution, please try again later", + "search.results.response.500": "حدث خطأ أثناء تنفيذ الاستعلام، يرجى إعادة المحاولة مرة أخرى لاحقاً", + + // "default.search.results.head": "Search Results", "default.search.results.head": "نتائج البحث", - "default-relationships.search.results.head": "نتائج البحث", + + // "default-relationships.search.results.head": "Search Results", + // TODO New key - Add a translation + "default-relationships.search.results.head": "Search Results", + + // "search.sidebar.close": "Back to results", "search.sidebar.close": "العودة إلى النتائج", + + // "search.sidebar.filters.title": "Filters", "search.sidebar.filters.title": "المنقحات", + + // "search.sidebar.open": "Search Tools", "search.sidebar.open": "أدوات البحث", + + // "search.sidebar.results": "results", "search.sidebar.results": "النتائج", + + // "search.sidebar.settings.rpp": "Results per page", "search.sidebar.settings.rpp": "النتائج لكل صفحة", - "search.sidebar.settings.sort-by": "فرز حسب الطلب", - "search.sidebar.settings.title": "عد", + + // "search.sidebar.settings.sort-by": "Sort By", + "search.sidebar.settings.sort-by": "فرز حسب", + + // "search.sidebar.settings.title": "Settings", + "search.sidebar.settings.title": "الإعدادات", + + // "search.view-switch.show-detail": "Show detail", "search.view-switch.show-detail": "عرض التفاصل", + + // "search.view-switch.show-grid": "Show as grid", "search.view-switch.show-grid": "عرض كشبكة", - "search.view-switch.show-list": "عرض القائمة", - "selectable-list-item-control.deselect": "قم بإلغاء تحديد المادة", - "selectable-list-item-control.select": "المادة المحددة", - "sorting.ASC": "تقييمياً", + + // "search.view-switch.show-list": "Show as list", + "search.view-switch.show-list": "عرض كقائمة", + + // "selectable-list-item-control.deselect": "Deselect item", + "selectable-list-item-control.deselect": "إلغاء تحديد المادة", + + // "selectable-list-item-control.select": "Select item", + "selectable-list-item-control.select": "تحديد المادة", + + // "sorting.ASC": "Ascending", + "sorting.ASC": "تصاعدياً", + + // "sorting.DESC": "Descending", "sorting.DESC": "تنازلياً", - "sorting.dc.title.ASC": "العنوان تقييمياً", + + // "sorting.dc.title.ASC": "Title Ascending", + "sorting.dc.title.ASC": "العنوان تصاعدياً", + + // "sorting.dc.title.DESC": "Title Descending", "sorting.dc.title.DESC": "العنوان تنازلياً", - "sorting.score.ASC": "أقل صلة", + + // "sorting.score.ASC": "Least Relevant", + "sorting.score.ASC": "الأقل صلة", + + // "sorting.score.DESC": "Most Relevant", "sorting.score.DESC": "الأكثر صلة", - "sorting.dc.date.issued.ASC": "تاريخ الإصدار التقييمي", + + // "sorting.dc.date.issued.ASC": "Date Issued Ascending", + "sorting.dc.date.issued.ASC": "تاريخ الإصدار تصاعدياً", + + // "sorting.dc.date.issued.DESC": "Date Issued Descending", "sorting.dc.date.issued.DESC": "تاريخ الإصدار تنازلياً", - "sorting.dc.date.accessioned.ASC": "تاريخ الإيداع تقييميًا", - "sorting.dc.date.accessioned.DESC": "تاريخ الإيداع التنازلي", - "sorting.lastModified.ASC": "آخر تعديل تقييمياً", + + // "sorting.dc.date.accessioned.ASC": "Accessioned Date Ascending", + "sorting.dc.date.accessioned.ASC": "تاريخ الإيداع تصاعدياً", + + // "sorting.dc.date.accessioned.DESC": "Accessioned Date Descending", + "sorting.dc.date.accessioned.DESC": "تاريخ الإيداع تنازلياً", + + // "sorting.lastModified.ASC": "Last modified Ascending", + "sorting.lastModified.ASC": "آخر تعديل تصاعدياً", + + // "sorting.lastModified.DESC": "Last modified Descending", "sorting.lastModified.DESC": "آخر تعديل تنازلياً", - "sorting.person.familyName.ASC": "اللقب تصاعدي", - "sorting.person.familyName.DESC": "اللقب تنازلي", - "sorting.person.givenName.ASC": "الاسم تصاعدي", - "sorting.person.givenName.DESC": "اسم تنازلي", - "sorting.person.birthDate.ASC": "تاريخ الميلاد تصاعدي", - "sorting.person.birthDate.DESC": "تاريخ الميلاد تنازلي", + + // "sorting.person.familyName.ASC": "Surname Ascending", + // TODO New key - Add a translation + "sorting.person.familyName.ASC": "Surname Ascending", + + // "sorting.person.familyName.DESC": "Surname Descending", + // TODO New key - Add a translation + "sorting.person.familyName.DESC": "Surname Descending", + + // "sorting.person.givenName.ASC": "Name Ascending", + // TODO New key - Add a translation + "sorting.person.givenName.ASC": "Name Ascending", + + // "sorting.person.givenName.DESC": "Name Descending", + // TODO New key - Add a translation + "sorting.person.givenName.DESC": "Name Descending", + + // "sorting.person.birthDate.ASC": "Birth Date Ascending", + // TODO New key - Add a translation + "sorting.person.birthDate.ASC": "Birth Date Ascending", + + // "sorting.person.birthDate.DESC": "Birth Date Descending", + // TODO New key - Add a translation + "sorting.person.birthDate.DESC": "Birth Date Descending", + + // "statistics.title": "Statistics", "statistics.title": "الاحصائيات", - "statistics.header": "إحصائيات لـ {{ scope }}", + + // "statistics.header": "Statistics for {{ scope }}", + "statistics.header": "احصائيات لـ {{ scope }}", + + // "statistics.breadcrumbs": "Statistics", "statistics.breadcrumbs": "الاحصائيات", - "statistics.page.no-data": "لا توفر أي بيانات", - "statistics.table.no-data": "لا توفر أي بيانات", - "statistics.table.title.TotalVisits": "زيارة إجمالية", + + // "statistics.page.no-data": "No data available", + "statistics.page.no-data": "لا تتوافر أي بيانات", + + // "statistics.table.no-data": "No data available", + "statistics.table.no-data": "لا تتوافر أي بيانات", + + // "statistics.table.title.TotalVisits": "Total visits", + "statistics.table.title.TotalVisits": "إجمالي الزيارات", + + // "statistics.table.title.TotalVisitsPerMonth": "Total visits per month", "statistics.table.title.TotalVisitsPerMonth": "إجمالي الزيارات لكل شهر", + + // "statistics.table.title.TotalDownloads": "File Visits", "statistics.table.title.TotalDownloads": "زيارات الملف", - "statistics.table.title.TopCountries": "أعلى المشاهدات على مستوى البلد", - "statistics.table.title.TopCities": "أعلى المشاهدات على مستوى المدينة", + + // "statistics.table.title.TopCountries": "Top country views", + "statistics.table.title.TopCountries": "أعلى مشاهدات على مستوى البلد", + + // "statistics.table.title.TopCities": "Top city views", + "statistics.table.title.TopCities": "أعلى مشاهدات على مستوى المدينة", + + // "statistics.table.header.views": "Views", "statistics.table.header.views": "المشاهدات", - "statistics.table.no-name": "(تعذر تحميل اسم سميث)", - "submission.edit.breadcrumbs": "تحرير.التقديم", - "submission.edit.title": "تحرير.التقديم", + + // "statistics.table.no-name": "(object name could not be loaded)", + "statistics.table.no-name": "(تعذر تحميل اسم الكائن)", + + // "submission.edit.breadcrumbs": "Edit Submission", + "submission.edit.breadcrumbs": "تحرير التقديم", + + // "submission.edit.title": "Edit Submission", + "submission.edit.title": "تحرير التقديم", + + // "submission.general.cancel": "Cancel", "submission.general.cancel": "إلغاء", - "submission.general.cannot_submit": "ليس لديك القدرة على تقديم الجديد.", + + // "submission.general.cannot_submit": "You don't have permission to make a new submission.", + "submission.general.cannot_submit": "ليس لديك صلاحية القيام بتقديم جديد.", + + // "submission.general.deposit": "Deposit", "submission.general.deposit": "إيداع", + + // "submission.general.discard.confirm.cancel": "Cancel", "submission.general.discard.confirm.cancel": "إلغاء", - "submission.general.discard.confirm.info": "لا يمكن السماء عن هذه الطريقة. ", - "submission.general.discard.confirm.submit": "نعم، بالتأكيد", - "submission.general.discard.confirm.title": "تجاهل", - "submission.general.discard.submit": "لا", - "submission.general.back.submit": "خلف", + + // "submission.general.discard.confirm.info": "This operation can't be undone. Are you sure?", + "submission.general.discard.confirm.info": "لا يمكن التراجع عن هذه العملية. هل أنت متأكد؟", + + // "submission.general.discard.confirm.submit": "Yes, I'm sure", + "submission.general.discard.confirm.submit": "نعم، متأكد", + + // "submission.general.discard.confirm.title": "Discard submission", + "submission.general.discard.confirm.title": "تجاهل التقديم", + + // "submission.general.discard.submit": "Discard", + "submission.general.discard.submit": "تجاهل", + + // "submission.general.back.submit": "Back", + // TODO New key - Add a translation + "submission.general.back.submit": "Back", + + // "submission.general.info.saved": "Saved", "submission.general.info.saved": "محفوظ", - "submission.general.info.pending-changes": "أخبار غير محفوظة", + + // "submission.general.info.pending-changes": "Unsaved changes", + "submission.general.info.pending-changes": "تغييرات غير محفوظة", + + // "submission.general.save": "Save", "submission.general.save": "حفظ", - "submission.general.save-later": "لوقت لاحق", - "submission.import-external.page.title": "استيراد ميتا من المصدر الخارجي", - "submission.import-external.title": "استيراد ميتا من المصدر الخارجي", - "submission.import-external.title.Journal": "استيراد دورية من المصدر الخارجي", - "submission.import-external.title.JournalIssue": "استيراد عدد دورية من المصدر الخارجي", - "submission.import-external.title.JournalVolume": "استيراد دورية من المصدر الخارجي", - "submission.import-external.title.OrgUnit": "استيراد ناشر من المصدر الخارجي", + + // "submission.general.save-later": "Save for later", + "submission.general.save-later": "حفظ لوقت لاحق", + + // "submission.import-external.page.title": "Import metadata from an external source", + "submission.import-external.page.title": "استيراد ميتاداتا من مصدر خارجي", + + // "submission.import-external.title": "Import metadata from an external source", + "submission.import-external.title": "استيراد ميتاداتا من مصدر خارجي", + + // "submission.import-external.title.Journal": "Import a journal from an external source", + "submission.import-external.title.Journal": "استيراد دورية من مصدر خارجي", + + // "submission.import-external.title.JournalIssue": "Import a journal issue from an external source", + "submission.import-external.title.JournalIssue": "استيراد عدد دورية من مصدر خارجيe", + + // "submission.import-external.title.JournalVolume": "Import a journal volume from an external source", + "submission.import-external.title.JournalVolume": "استيراد مجلد دورية من مصدر خارجي", + + // "submission.import-external.title.OrgUnit": "Import a publisher from an external source", + "submission.import-external.title.OrgUnit": "استيراد ناشر من مصدر خارجي", + + // "submission.import-external.title.Person": "Import a person from an external source", "submission.import-external.title.Person": "استيراد شخص من مصدر خارجي", + + // "submission.import-external.title.Project": "Import a project from an external source", "submission.import-external.title.Project": "استيراد مشروع من مصدر خارجي", - "submission.import-external.title.Publication": "استيراد منشور من المصدر الخارجي", - "submission.import-external.title.none": "استيراد ميتا من المصدر الخارجي", - "submission.import-external.page.hint": "قم دائمًا بالاستعلام عن بعد لاستيراد البيانات إلى دي سبيس.", + + // "submission.import-external.title.Publication": "Import a publication from an external source", + "submission.import-external.title.Publication": "استيراد منشور من مصدر خارجي", + + // "submission.import-external.title.none": "Import metadata from an external source", + "submission.import-external.title.none": "استيراد ميتاداتا من مصدر خارجي", + + // "submission.import-external.page.hint": "Enter a query above to find items from the web to import in to DSpace.", + "submission.import-external.page.hint": "قم بإدخال استعلام أعلاه للعثور على مواد من الويب لاستيرادها إلى دي سبيس.", + + // "submission.import-external.back-to-my-dspace": "Back to MyDSpace", "submission.import-external.back-to-my-dspace": "العودة إلى ماي سبيس", + + // "submission.import-external.search.placeholder": "Search the external source", "submission.import-external.search.placeholder": "بحث المصدر الخارجي", + + // "submission.import-external.search.button": "Search", "submission.import-external.search.button": "بحث", + + // "submission.import-external.search.button.hint": "Write some words to search", "submission.import-external.search.button.hint": "اكتب بعض الكلمات للبحث", + + // "submission.import-external.search.source.hint": "Pick an external source", "submission.import-external.search.source.hint": "اختر مصدراً خارجياً", + + // "submission.import-external.source.arxiv": "arXiv", "submission.import-external.source.arxiv": "arXiv", + + // "submission.import-external.source.ads": "NASA/ADS", "submission.import-external.source.ads": "ناسا/ADS", + + // "submission.import-external.source.cinii": "CiNii", "submission.import-external.source.cinii": "CiNii", + + // "submission.import-external.source.crossref": "CrossRef", "submission.import-external.source.crossref": "كروس ريف", + + // "submission.import-external.source.datacite": "DataCite", "submission.import-external.source.datacite": "داتاسايت", + + // "submission.import-external.source.doi": "DOI", + // TODO New key - Add a translation "submission.import-external.source.doi": "DOI", - "submission.import-external.source.scielo": "سيلو", + + // "submission.import-external.source.scielo": "SciELO", + "submission.import-external.source.scielo": "SciELO", + + // "submission.import-external.source.scopus": "Scopus", "submission.import-external.source.scopus": "سكوبس", + + // "submission.import-external.source.vufind": "VuFind", "submission.import-external.source.vufind": "فيوفايند", + + // "submission.import-external.source.wos": "Web Of Science", "submission.import-external.source.wos": "شبكة العلوم", + + // "submission.import-external.source.orcidWorks": "ORCID", "submission.import-external.source.orcidWorks": "أوركيد", - "submission.import-external.source.epo": "مكتب براءات الاصدار الأوروبي (EPO)", + + // "submission.import-external.source.epo": "European Patent Office (EPO)", + "submission.import-external.source.epo": "مكتب براءات الاختراع الأوروبي (EPO)", + + // "submission.import-external.source.loading": "Loading ...", "submission.import-external.source.loading": "جاري التحميل ...", + + // "submission.import-external.source.sherpaJournal": "SHERPA Journals", "submission.import-external.source.sherpaJournal": "دوريات شيربا", + + // "submission.import-external.source.sherpaJournalIssn": "SHERPA Journals by ISSN", "submission.import-external.source.sherpaJournalIssn": "دوريات شيربا بواسطة الردمد", - "submission.import-external.source.sherpaPublisher": "نشري شيربا", - "submission.import-external.source.openAIREFunding": "تمويل برمجة تطبيقات OpenAIRE", + + // "submission.import-external.source.sherpaPublisher": "SHERPA Publishers", + "submission.import-external.source.sherpaPublisher": "ناشري شيربا", + + // "submission.import-external.source.openAIREFunding": "Funding OpenAIRE API", + "submission.import-external.source.openAIREFunding": "تمويل واجهة برمجة تطبيقات OpenAIRE", + + // "submission.import-external.source.orcid": "ORCID", "submission.import-external.source.orcid": "أوركيد", - "submission.import-external.source.pubmed": "نشر", - "submission.import-external.source.pubmedeu": "أوروبا المنشورة", - "submission.import-external.source.lcname": "اسماء مكتبة الكونجرس", - "submission.import-external.source.ror": "سجل المنظمات البحثية (ROR)", - "submission.import-external.preview.title": "عرض المادة", - "submission.import-external.preview.title.Publication": "قم بمراجعة المنشور", - "submission.import-external.preview.title.none": "عرض المادة", - "submission.import-external.preview.title.Journal": "مراجعة الدورية", - "submission.import-external.preview.title.OrgUnit": "نظرة عامة على الوحدة الوطنية", - "submission.import-external.preview.title.Person": "نظرة على الشخص", - "submission.import-external.preview.title.Project": "نظرة على المشروع", - "submission.import-external.preview.subtitle": "تم استيراد الميتاداتا أدناه من المصدر الخارجي. ", - "submission.import-external.preview.button.import": "البدء", + + // "submission.import-external.source.pubmed": "Pubmed", + "submission.import-external.source.pubmed": "Pubmed", + + // "submission.import-external.source.pubmedeu": "Pubmed Europe", + "submission.import-external.source.pubmedeu": "Pubmed Europe", + + // "submission.import-external.source.lcname": "Library of Congress Names", + "submission.import-external.source.lcname": "أسماء مكتبة الكونجرس", + + // "submission.import-external.source.ror": "Research Organization Registry (ROR)", + "submission.import-external.source.ror": "سجل المؤسسات البحثية (ROR)", + + // "submission.import-external.preview.title": "Item Preview", + "submission.import-external.preview.title": "معاينة المادة", + + // "submission.import-external.preview.title.Publication": "Publication Preview", + "submission.import-external.preview.title.Publication": "معاينة المنشور", + + // "submission.import-external.preview.title.none": "Item Preview", + "submission.import-external.preview.title.none": "معاينة المادة", + + // "submission.import-external.preview.title.Journal": "Journal Preview", + "submission.import-external.preview.title.Journal": "معاينة الدورية", + + // "submission.import-external.preview.title.OrgUnit": "Organizational Unit Preview", + "submission.import-external.preview.title.OrgUnit": "معاينة الوحدة المؤسسية", + + // "submission.import-external.preview.title.Person": "Person Preview", + "submission.import-external.preview.title.Person": "معاينة الشخص", + + // "submission.import-external.preview.title.Project": "Project Preview", + "submission.import-external.preview.title.Project": "معاينة المشروع", + + // "submission.import-external.preview.subtitle": "The metadata below was imported from an external source. It will be pre-filled when you start the submission.", + "submission.import-external.preview.subtitle": "تم استيراد الميتاداتا أدناه من مصدر خارجي. ستتم تعبئتها بشكل مسبق عند بدء التقديم.", + + // "submission.import-external.preview.button.import": "Start submission", + "submission.import-external.preview.button.import": "بدء التقديم", + + // "submission.import-external.preview.error.import.title": "Submission error", "submission.import-external.preview.error.import.title": "خطأ في التقديم", - "submission.import-external.preview.error.import.body": "حدث خطأ أثناء عملية استيراد المصدر الخارجي.", + + // "submission.import-external.preview.error.import.body": "An error occurs during the external source entry import process.", + "submission.import-external.preview.error.import.body": "حدث خطأ أثناء عملية استيراد مدخل المصدر الخارجي.", + + // "submission.sections.describe.relationship-lookup.close": "Close", "submission.sections.describe.relationship-lookup.close": "إغلاق", - "submission.sections.describe.relationship-lookup.external-source.added": "تمت إضافة المدخل المحلي الفعال إلى التحديد", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "استيراد الكاتب البعيد", + + // "submission.sections.describe.relationship-lookup.external-source.added": "Successfully added local entry to the selection", + "submission.sections.describe.relationship-lookup.external-source.added": "تمت إضافة المدخل المحلي بنجاح إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "Import remote author", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "استيراد مؤلف بعيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Import remote journal", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "استيراد دورية بعيدة", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "استيراد عدد دورية بعيدة", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "استيراد دورية بعيدة", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Import remote journal issue", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "استيراد عدد دورية بعيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "استيراد مجلد دورية بعيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.isProjectOfPublication": "Project", "submission.sections.describe.relationship-lookup.external-source.import-button-title.isProjectOfPublication": "المشروع", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.none": "Import remote item", "submission.sections.describe.relationship-lookup.external-source.import-button-title.none": "استيراد مادة بعيدة", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Event": "زراعة فعالة بعيدة", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Product": "استيراد المنتج البعيد", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Equipment": "استيراد المعدات البعيدة", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Event": "Import remote event", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Event": "استيراد فعالية بعيدة", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Product": "Import remote product", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Product": "استيراد منتج بعيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Equipment": "Import remote equipment", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Equipment": "استيراد معدات بعيدة", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.OrgUnit": "Import remote organizational unit", "submission.sections.describe.relationship-lookup.external-source.import-button-title.OrgUnit": "استيراد وحدة مؤسسية بعيدة", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Funding": "استيراد التمويل البعيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Funding": "Import remote fund", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Funding": "استيراد تمويل بعيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Person": "Import remote person", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Person": "استيراد شخص بعيد", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Patent": "استيراد اختراع طويل", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Patent": "Import remote patent", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Patent": "استيراد براءة اختراع بعيدة", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Project": "Import remote project", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Project": "استيراد مشروع بعيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication": "Import remote publication", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication": "استيراد منشور بعيد", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.added.new-entity": "أكمل إضافة كينونة جديدة!", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.added.new-entity": "New Entity Added!", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.added.new-entity": "تمت إضافة كينونة جديدة!", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.title": "Project", "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.title": "مشروع", - "submission.sections.describe.relationship-lookup.external-source.import-modal.head.openAIREFunding": "تمويل برمجة تطبيقات OpenAIRE", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "استيراد الكاتب البعيد", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "تمت إضافة المؤلف المحلي الفعال إلى التحديد", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "تم استيراد المصنع الخارجي بفعالية إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.openAIREFunding": "Funding OpenAIRE API", + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.openAIREFunding": "تمويل واجهة برمجة تطبيقات OpenAIRE", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "استيراد مؤلف بعيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Successfully added local author to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "تمت إضافة المؤلف المحلي بنجاح إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Successfully imported and added external author to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "تم استيراد وإضافة المؤلف الخارجي بنجاح إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority", "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "الاستناد", - "submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "أدخل كإستنباط محلي جديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "Import as a new local authority entry", + "submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "استيراد كإدخال استناد محلي جديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "Cancel", "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "إلغاء", - "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "اختر حاوية استيراد الإدخالات الجديدة الخاصة بها", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "Select a collection to import new entries to", + "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "حدد حاوية لاستيراد الإدخالات الجديدة إليها", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities", "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "الكينونات", - "submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "استيراد كيكونة محلية جديدة", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "Import as a new local entity", + "submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "استيراد ككينونة محلية جديدة", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "Importing from LC Name", "submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "استيراد من اسم مكتبة الكونجرس", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.orcid": "Importing from ORCID", "submission.sections.describe.relationship-lookup.external-source.import-modal.head.orcid": "استيراد من أوركيد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaJournal": "Importing from Sherpa Journal", "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaJournal": "استيراد من دورية شيربا", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaPublisher": "Importing from Sherpa Publisher", "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaPublisher": "استيراد من ناشر شيربا", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.pubmed": "Importing from PubMed", "submission.sections.describe.relationship-lookup.external-source.import-modal.head.pubmed": "استيراد من PubMed", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.arxiv": "Importing from arXiv", "submission.sections.describe.relationship-lookup.external-source.import-modal.head.arxiv": "استيراد من arXiv", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.ror": "Import from ROR", "submission.sections.describe.relationship-lookup.external-source.import-modal.head.ror": "استيراد من ROR", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "Import", "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "استيراد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "Import Remote Journal", "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "استيراد دورية بعيدة", - "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "أكمل إضافة الدورية الفعالة إلى التحديد", - "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "تم الانتهاء من حذف دورية خارجية إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "Successfully added local journal to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "تمت إضافة الدورية المحلية بنجاح إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "Successfully imported and added external journal to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "تم بنجاح استيراد وإضافة دورية خارجية إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.title": "Import Remote Journal Issue", "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.title": "استيراد عدد دورية بعيدة", - "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "تمت إضافة المزيد من الدوريات الفعالة إلى التحديد", - "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "تم استيراد عدد الدوريات الخارجية وإضافتها الفعالة إلى التحديد", - "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "استيراد دورة طويلة", - "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "أكمل إضافة الدورية الفعالة إلى التحديد", - "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "تم استيراد سلسلة الدوري الخارجية وإضافتها الفعالة إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "Successfully added local journal issue to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "تمت إضافة عدد الدورية المحلية بنجاح إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "Successfully imported and added external journal issue to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "تم استيراد عدد الدورية الخارجية وإضافته بنجاح إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "Import Remote Journal Volume", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "استيراد مجلد دورية بعيدة", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "Successfully added local journal volume to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "تمت إضافة مجلد الدورية المحلية بنجاح إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "Successfully imported and added external journal volume to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "تم استيراد مجلد الدورية الخارجية وإضافته بنجاح إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Select a local match:", "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "تحديد تطابق محلي:", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isOrgUnitOfProject.title": "Import Remote Organization", "submission.sections.describe.relationship-lookup.external-source.import-modal.isOrgUnitOfProject.title": "استيراد مؤسسة بعيدة", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isOrgUnitOfProject.added.local-entity": "تمت إضافة المؤسسة المحلية إلى التحديد الفعال", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isOrgUnitOfProject.added.new-entity": "تم التخلص من المصنع الخارجي إلى التحديد", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isOrgUnitOfProject.added.local-entity": "Successfully added local organization to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isOrgUnitOfProject.added.local-entity": "تمت إضافة المؤسسة المحلية إلى التحديد بنجاح", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isOrgUnitOfProject.added.new-entity": "Successfully imported and added external organization to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isOrgUnitOfProject.added.new-entity": "تم بنجاح استيراد وإضافة مؤسسة خارجية إلى التحديد", + + // "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all", "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "إلغاء تحديد الكل", + + // "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page", "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "إلغاء تحديد الصفحة", + + // "submission.sections.describe.relationship-lookup.search-tab.loading": "Loading...", "submission.sections.describe.relationship-lookup.search-tab.loading": "جاري التحميل...", + + // "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Search query", "submission.sections.describe.relationship-lookup.search-tab.placeholder": "استعلام البحث", + + // "submission.sections.describe.relationship-lookup.search-tab.search": "Go", "submission.sections.describe.relationship-lookup.search-tab.search": "اذهب", - "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "بحثت...", + + // "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "Search...", + "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "بحث...", + + // "submission.sections.describe.relationship-lookup.search-tab.select-all": "Select all", "submission.sections.describe.relationship-lookup.search-tab.select-all": "تحديد الكل", + + // "submission.sections.describe.relationship-lookup.search-tab.select-page": "Select page", "submission.sections.describe.relationship-lookup.search-tab.select-page": "تحديد الصفحة", + + // "submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items", "submission.sections.describe.relationship-lookup.selected": "{{ size }} مادة محددة", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "المؤلفين ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "المؤلفين المحليين ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "الدوريات المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Local Projects ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "المشاريع المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Local Publications ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "المنشورات المحلية ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "المؤلفين ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "الوحدات الوطنية المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "المؤلفين المحليين ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "الوحدات المؤسسية المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Local Data Packages ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "حزم البيانات المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Local Data Files ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "ملفات البيانات المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Local Journals ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "الدوريات المحلية ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "سجل الدوريات المحلية ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "سجل الدوريات المحلية ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "خطوط الدوريات المحلية ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "خطوط الدوريات المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Local Journal Issues ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "أعداد الدوريات المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Local Journal Issues ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "أعداد الدوريات المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Local Journal Volumes ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "مجلدات الدوريات المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Local Journal Volumes ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "مجلدات الدوريات المحلية ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "Sherpa Journals ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "دوريات شيربا ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaPublisher": "Sherpa Publishers ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaPublisher": "ناشري شيربا ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcid": "ORCID ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcid": "أوركيد ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "LC Names ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "أسماء مكتبة الكونجرس ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "مجلات ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "أرخايف ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.ror": "معدل العائد ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "PubMed ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "PubMed ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.ror": "ROR ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.ror": "ROR ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcidWorks": "ORCID ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcidWorks": "أوركيد ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.crossref": "كروسريف ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.scopus": "سكوبس ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.crossref": "CrossRef ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.crossref": "CrossRef ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.scopus": "Scopus ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.scopus": "Scopus ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.openaireFunding": "Funding OpenAIRE ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.openaireFunding": "تمويل OpenAIRE ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournalIssn": "Sherpa Journals by ISSN ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournalIssn": "دوريات شيربا حسب ISSN ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "ابحث عن وكالات ممولة", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "البحث عن التمويل", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "البحث عن الوحدات الوطنية", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.openAIREFunding": "تمويل برمجة تطبيقات OpenAIRE", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Search for Funding Agencies", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "البحث عن وكالات ممولة", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Search for Funding", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "البحث عن تمويل", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Search for Organizational Units", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "البحث عن الوحدات المؤسسية", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.openAIREFunding": "Funding OpenAIRE API", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.openAIREFunding": "تمويل واجهة برمجة تطبيقات OpenAIRE", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isProjectOfPublication": "Projects", "submission.sections.describe.relationship-lookup.search-tab.tab-title.isProjectOfPublication": "المشاريع", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfProject": "مول المشروع", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfProject": "Funder of the Project", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfProject": "ممول المشروع", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isPublicationOfAuthor": "Publication of the Author", "submission.sections.describe.relationship-lookup.search-tab.tab-title.isPublicationOfAuthor": "منشورات المؤلف", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isOrgUnitOfProject": "الوحدة التنظيمية", - "submission.sections.describe.relationship-lookup.selection-tab.title.openAIREFunding": "تمويل برمجة تطبيقات OpenAIRE", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isOrgUnitOfProject": "OrgUnit of the Project", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isOrgUnitOfProject": "الوحدة المؤسسية للمشروع", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.openAIREFunding": "Funding OpenAIRE API", + "submission.sections.describe.relationship-lookup.selection-tab.title.openAIREFunding": "تمويل واجهة برمجة تطبيقات OpenAIRE", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isProjectOfPublication": "Project", "submission.sections.describe.relationship-lookup.selection-tab.title.isProjectOfPublication": "المشروع", + + // "submission.sections.describe.relationship-lookup.title.isProjectOfPublication": "Projects", "submission.sections.describe.relationship-lookup.title.isProjectOfPublication": "المشاريع", - "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfProject": "مول المشروع", - "submission.sections.describe.relationship-lookup.selection-tab.search-form.placeholder": "بحثت...", - "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "التحديد الفعلي ({{ count }})", - "submission.sections.describe.relationship-lookup.title.Journal": "الدوري", - "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "سجل الدوري", - "submission.sections.describe.relationship-lookup.title.JournalIssue": "سجل الدوري", - "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "سلسلة الدوريات", - "submission.sections.describe.relationship-lookup.title.JournalVolume": "سلسلة الدوريات", + + // "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfProject": "Funder of the Project", + "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfProject": "ممول المشروع", + + // "submission.sections.describe.relationship-lookup.selection-tab.search-form.placeholder": "Search...", + "submission.sections.describe.relationship-lookup.selection-tab.search-form.placeholder": "بحث...", + + // "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Current Selection ({{ count }})", + "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "التحديد الحالي ({{ count }})", + + // "submission.sections.describe.relationship-lookup.title.Journal": "Journal", + "submission.sections.describe.relationship-lookup.title.Journal": "الدورية", + + // "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Journal Issues", + "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "أعداد الدورية", + + // "submission.sections.describe.relationship-lookup.title.JournalIssue": "Journal Issues", + "submission.sections.describe.relationship-lookup.title.JournalIssue": "أعداد الدورية", + + // "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Journal Volumes", + "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "مجلدات الدورية", + + // "submission.sections.describe.relationship-lookup.title.JournalVolume": "Journal Volumes", + "submission.sections.describe.relationship-lookup.title.JournalVolume": "مجلدات الدورية", + + // "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "Journals", "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "الدوريات", + + // "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Authors", "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "المؤلفين", + + // "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Funding Agency", "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "الوكالة الممولة", - "submission.sections.describe.relationship-lookup.title.Project": "المشاريع", - "submission.sections.describe.relationship-lookup.title.Publication": "منشورات", + + // "submission.sections.describe.relationship-lookup.title.Project": "Projects", + "submission.sections.describe.relationship-lookup.title.Project": "المشروعات", + + // "submission.sections.describe.relationship-lookup.title.Publication": "Publications", + "submission.sections.describe.relationship-lookup.title.Publication": "المنشورات", + + // "submission.sections.describe.relationship-lookup.title.Person": "Authors", "submission.sections.describe.relationship-lookup.title.Person": "المؤلفين", - "submission.sections.describe.relationship-lookup.title.OrgUnit": "الوحدات الوطنية", + + // "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organizational Units", + "submission.sections.describe.relationship-lookup.title.OrgUnit": "الوحدات المؤسسية", + + // "submission.sections.describe.relationship-lookup.title.DataPackage": "Data Packages", "submission.sections.describe.relationship-lookup.title.DataPackage": "حزم البيانات", - "submission.sections.describe.relationship-lookup.title.DataFile": "ملفات بيانات البيانات", + + // "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", + "submission.sections.describe.relationship-lookup.title.DataFile": "ملفات البيانات", + + // "submission.sections.describe.relationship-lookup.title.Funding Agency": "Funding Agency", "submission.sections.describe.relationship-lookup.title.Funding Agency": "الوكالة الممولة", + + // "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "تمويل", - "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "الوحدة المحلية الأصلية", + + // "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", + "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "الوحدة المؤسسية الأصلية", + + // "submission.sections.describe.relationship-lookup.title.isPublicationOfAuthor": "Publication", "submission.sections.describe.relationship-lookup.title.isPublicationOfAuthor": "النشر", + + // "submission.sections.describe.relationship-lookup.title.isOrgUnitOfProject": "OrgUnit", "submission.sections.describe.relationship-lookup.title.isOrgUnitOfProject": "وحدة مؤسسية", + + // "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Toggle dropdown", "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "قائمة التبديل المنسدلة", - "submission.sections.describe.relationship-lookup.selection-tab.settings": "عد", - "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "تحديدك بالكامل.", - "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "المؤلفين", + + // "submission.sections.describe.relationship-lookup.selection-tab.settings": "Settings", + "submission.sections.describe.relationship-lookup.selection-tab.settings": "الإعدادات", + + // "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Your selection is currently empty.", + "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "تحديدك فارغ حالياً.", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Selected Authors", + "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "المؤلفين المحددين", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Selected Journals", "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "الدوريات المحددة", - "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "دليل البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Selected Journal Volume", + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "مجلد الدورية المحدد", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Selected Projects", "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "المشاريع المحددة", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "Selected Publications", "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "المنشورات المحددة", - "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "المؤلفين", - "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "الوحدات الوطنية المحددة", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Selected Authors", + "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "المؤلفين المحددين", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Selected Organizational Units", + "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "الوحدات المؤسسية المحددة", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Selected Data Packages", "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "حزم البيانات المحددة", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "ملفات البيانات المحددة", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Selected Journals", "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "الدوريات المحددة", - "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "العثور على نتيجة", - "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "دليل البحث", - "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "الوكالة الممولة", - "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "التمويل للبحث", - "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "العثور على نتيجة", - "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "الوحدة الوطنية المحددة", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Selected Issue", + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "العدد المحدد", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Selected Journal Volume", + "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "مجلد الدورية المحدد", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "Selected Funding Agency", + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "الوكالة الممولة المحددة", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Selected Funding", + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "التمويل المحدد", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Selected Issue", + "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "العدد المحدد", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "Selected Organizational Unit", + "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "الوحدة المؤسسية المحددة", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.crossref": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.crossref": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.epo": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.epo": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.scopus": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.scopus": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.scielo": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.scielo": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.wos": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.wos": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.ror": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title.ror": "نتائج البحث", + + // "submission.sections.describe.relationship-lookup.selection-tab.title": "Search Results", "submission.sections.describe.relationship-lookup.selection-tab.title": "نتائج البحث", - "submission.sections.describe.relationship-lookup.name-variant.notification.content": "هل ترغب في حفظ \"{{ value }}\" كمتغير اسم هذا الشخص حتى بدأت بالفعل في إعادة استخدامه بنجاح بنجاح؟ إذا لم تقم بذلك، فلا يزال بإمكانك استخدام هذا التقديم.", - "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "حفظ اسم جديد", - "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "استخدم فقط هذا التقديم", - "submission.sections.ccLicense.type": "نوع الحكم", - "submission.sections.ccLicense.select": "قم بتحديد نوع الأمر…", - "submission.sections.ccLicense.change": "قم بتغيير نوع النظام…", - "submission.sections.ccLicense.none": "لا تتوفر أي تراخيص", - "submission.sections.ccLicense.option.select": "قم باختيار الخيار…", - "submission.sections.ccLicense.link": "لقد قمت بإلغاء الأمر التالي:", - "submission.sections.ccLicense.confirmation": "زيادة على ذلك", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.content": "Would you like to save \"{{ value }}\" as a name variant for this person so you and others can reuse it for future submissions? If you don't you can still use it for this submission.", + "submission.sections.describe.relationship-lookup.name-variant.notification.content": "هل ترغب في حفظe \"{{ value }}\" كمتغير اسم لهذا الشخص حتى تتمكن أنت والآخرون من إعادة استخدامه لعمليات التقديم المستقبلية؟ إذا لم تقم بذلك، فلا يزال بإمكانك استخدامه لهذا التقديم.", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant", + "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "حفظ متغير اسم جديد", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "Use only for this submission", + "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "استخدم فقط لهذا التقديم", + + // "submission.sections.ccLicense.type": "License Type", + "submission.sections.ccLicense.type": "نوع الترخيص", + + // "submission.sections.ccLicense.select": "Select a license type…", + "submission.sections.ccLicense.select": "قم بتحديد نوع الترخيص…", + + // "submission.sections.ccLicense.change": "Change your license type…", + "submission.sections.ccLicense.change": "قم بتغيير نوع الترخيص…", + + // "submission.sections.ccLicense.none": "No licenses available", + "submission.sections.ccLicense.none": "لا تتوافر أي تراخيص", + + // "submission.sections.ccLicense.option.select": "Select an option…", + "submission.sections.ccLicense.option.select": "قم بتحديد خيار…", + + // "submission.sections.ccLicense.link": "You’ve selected the following license:", + "submission.sections.ccLicense.link": "لقد قمت بتحديد الترخيص التالي:", + + // "submission.sections.ccLicense.confirmation": "I grant the license above", + "submission.sections.ccLicense.confirmation": "أمنحك الترخيص أعلاه", + + // "submission.sections.general.add-more": "Add more", "submission.sections.general.add-more": "إضافة المزيد", - "submission.sections.general.cannot_deposit": "لا يمكن تجاوز الإيداع بسبب وجود أخطاء في النموذج.
يرجى تعبئة جميع الأغراض المطلوبة لجميع الإيداع.", + + // "submission.sections.general.cannot_deposit": "Deposit cannot be completed due to errors in the form.
Please fill out all required fields to complete the deposit.", + "submission.sections.general.cannot_deposit": "لا يمكن إتمام الإيداع بسبب وجود أخطاء في النموذج.
يرجى ملء جميع الحقول المطلوبة لإتمام الإيداع.", + + // "submission.sections.general.collection": "Collection", "submission.sections.general.collection": "حاوية", - "submission.sections.general.deposit_error_notice": "تجربة تقديم المادة أثناء تقديم المادة، يرجى إعادة محاولة مرة أخرى لاحقاً.", - "submission.sections.general.deposit_success_notice": "تم تقديم التقديم الفعال.", - "submission.sections.general.discard_error_notice": "لا تتجاهل المشكلة، يرجى إعادة محاولة مرة أخرى لاحقًا.", - "submission.sections.general.discard_success_notice": "تم التقليل من التأثير.", - "submission.sections.general.metadata-extracted": "تم الانتهاء من ميتاداتا جديدة وإضافتها إلى القسم {{sectionId}}.", - "submission.sections.general.metadata-extracted-new-section": "أكمل إضافة قسم {{sectionId}} الجديد في التقديم.", - "submission.sections.general.no-collection": "لم يتم العثور على الوثيقة", + + // "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", + "submission.sections.general.deposit_error_notice": "حدثت مشكلة أثناء تقديم المادة، يرجى إعادة المحاولة مرة أخرى لاحقاً.", + + // "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", + "submission.sections.general.deposit_success_notice": "تم إيداع التقديم بنجاح.", + + // "submission.sections.general.discard_error_notice": "There was an issue when discarding the item, please try again later.", + "submission.sections.general.discard_error_notice": "حدثت مشكلة أثناء تجاهل المادة، يرجى إعادة المحاولة مرة أخرى لاحقاً.", + + // "submission.sections.general.discard_success_notice": "Submission discarded successfully.", + "submission.sections.general.discard_success_notice": "تم تجاهل التقديم بنجاح.", + + // "submission.sections.general.metadata-extracted": "New metadata have been extracted and added to the {{sectionId}} section.", + "submission.sections.general.metadata-extracted": "تم استخلاص ميتاداتا جديدة وإضافتها إلى قسم {{sectionId}}.", + + // "submission.sections.general.metadata-extracted-new-section": "New {{sectionId}} section has been added to submission.", + "submission.sections.general.metadata-extracted-new-section": "تمت إضافة قسم {{sectionId}} جديد إلى التقديم.", + + // "submission.sections.general.no-collection": "No collection found", + "submission.sections.general.no-collection": "لم يتم العثور على حاويات", + + // "submission.sections.general.no-entity": "No entity types found", "submission.sections.general.no-entity": "لم يتم العثور على أنواع كينونات", - "submission.sections.general.no-sections": "لا تتوفر أي خيارات", - "submission.sections.general.save_error_notice": "حدثت مشكلة أثناء حفظ المادة، يرجى إعادة محاولة مرة أخرى لاحقًا.", - "submission.sections.general.save_success_notice": "تم دعم الفعال.", - "submission.sections.general.search-collection": "ابحث عن الحاوية", + + // "submission.sections.general.no-sections": "No options available", + "submission.sections.general.no-sections": "لا تتوافر أي خيارات", + + // "submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.", + "submission.sections.general.save_error_notice": "حدثت مشكلة أثناء حفظ المادة، يرجى إعادة المحاولة مرة أخرى لاحقاً.", + + // "submission.sections.general.save_success_notice": "Submission saved successfully.", + "submission.sections.general.save_success_notice": "تم حفظ التقديم بنجاح.", + + // "submission.sections.general.search-collection": "Search for a collection", + "submission.sections.general.search-collection": "البحث عن حاوية", + + // "submission.sections.general.sections_not_valid": "There are incomplete sections.", "submission.sections.general.sections_not_valid": "هناك أقسام غير مكتملة.", - "submission.sections.identifiers.info": "سيتم إنشاء المعرفات التالية الجديدة بك:", - "submission.sections.identifiers.no_handle": "ولم يتم استخدام أي يد لهذه المادة.", - "submission.sections.identifiers.no_doi": "ولم يتم البحث عن أي معرفات كائنية رقمية لهذه المادة.", - "submission.sections.identifiers.handle_label": "مقبض: ", - "submission.sections.identifiers.doi_label": "المعرفة الرقمية: ", + + // "submission.sections.identifiers.info": "The following identifiers will be created for your item:", + "submission.sections.identifiers.info": "سيتم إنشاء المعرفات التالية للمادة الخاصة بك:", + + // "submission.sections.identifiers.no_handle": "No handles have been minted for this item.", + "submission.sections.identifiers.no_handle": "لم يتم سك أي هاندل لهذه المادة.", + + // "submission.sections.identifiers.no_doi": "No DOIs have been minted for this item.", + "submission.sections.identifiers.no_doi": "لم يتم سك أي معرفات كائنات رقمية لهذه المادة.", + + // "submission.sections.identifiers.handle_label": "Handle: ", + "submission.sections.identifiers.handle_label": "هاندل: ", + + // "submission.sections.identifiers.doi_label": "DOI: ", + "submission.sections.identifiers.doi_label": "معرف الكائن الرقمي: ", + + // "submission.sections.identifiers.otherIdentifiers_label": "Other identifiers: ", "submission.sections.identifiers.otherIdentifiers_label": "معرفات أخرى: ", - "submission.sections.submit.progressbar.accessCondition": "شروط الوصول إلى أبعد", + + // "submission.sections.submit.progressbar.accessCondition": "Item access conditions", + "submission.sections.submit.progressbar.accessCondition": "شروط الوصول للمادة", + + // "submission.sections.submit.progressbar.CClicense": "Creative commons license", "submission.sections.submit.progressbar.CClicense": "الإبداعية العامة", - "submission.sections.submit.progressbar.describe.recycle": "إعادة تدوير رياضي", + + // "submission.sections.submit.progressbar.describe.recycle": "Recycle", + "submission.sections.submit.progressbar.describe.recycle": "إعادة تدوير", + + // "submission.sections.submit.progressbar.describe.stepcustom": "Describe", "submission.sections.submit.progressbar.describe.stepcustom": "وصف", + + // "submission.sections.submit.progressbar.describe.stepone": "Describe", "submission.sections.submit.progressbar.describe.stepone": "وصف", + + // "submission.sections.submit.progressbar.describe.steptwo": "Describe", "submission.sections.submit.progressbar.describe.steptwo": "وصف", - "submission.sections.submit.progressbar.duplicates": "التكرارات المحتملة", + + // "submission.sections.submit.progressbar.duplicates": "Potential duplicates", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.duplicates": "Potential duplicates", + + // "submission.sections.submit.progressbar.identifiers": "Identifiers", "submission.sections.submit.progressbar.identifiers": "المعرفات", - "submission.sections.submit.progressbar.license": "ترخيص الإيداع", - "submission.sections.submit.progressbar.sherpapolicy": "سياسة شيربا", + + // "submission.sections.submit.progressbar.license": "Deposit license", + "submission.sections.submit.progressbar.license": "رخصة الإيداع", + + // "submission.sections.submit.progressbar.sherpapolicy": "Sherpa policies", + "submission.sections.submit.progressbar.sherpapolicy": "سياسات شيربا", + + // "submission.sections.submit.progressbar.upload": "Upload files", "submission.sections.submit.progressbar.upload": "تحميل الملفات", - "submission.sections.submit.progressbar.sherpaPolicies": "معلومات عن الوصول الحر للناشر", - "submission.sections.sherpa-policy.title-empty": "لا اختيار معلومات حول الناشر. ", + + // "submission.sections.submit.progressbar.sherpaPolicies": "Publisher open access policy information", + "submission.sections.submit.progressbar.sherpaPolicies": "معلومات سياسة الوصول الحر للناشر", + + // "submission.sections.sherpa-policy.title-empty": "No publisher policy information available. If your work has an associated ISSN, please enter it above to see any related publisher open access policies.", + "submission.sections.sherpa-policy.title-empty": "لا تتوفر معلومات حول سياسة الناشر. إذا كان لعملك رقم ISSN مرتبط، يرجى إدخاله أعلاه للاطلاع على أي سياسة وصول حر للناشرين ذوي الصلة.", + + // "submission.sections.status.errors.title": "Errors", "submission.sections.status.errors.title": "أخطاء", + + // "submission.sections.status.valid.title": "Valid", "submission.sections.status.valid.title": "صالح", + + // "submission.sections.status.warnings.title": "Warnings", "submission.sections.status.warnings.title": "تحذيرات", - "submission.sections.status.errors.aria": "بسبب الأخطاء", + + // "submission.sections.status.errors.aria": "has errors", + "submission.sections.status.errors.aria": "به أخطاء", + + // "submission.sections.status.valid.aria": "is valid", "submission.sections.status.valid.aria": "صالح", + + // "submission.sections.status.warnings.aria": "has warnings", "submission.sections.status.warnings.aria": "ذو تحذيرات", - "submission.sections.status.info.title": "معلومات اضافية", - "submission.sections.status.info.aria": "معلومات اضافية", + + // "submission.sections.status.info.title": "Additional Information", + "submission.sections.status.info.title": "معلومات إضافية", + + // "submission.sections.status.info.aria": "Additional Information", + "submission.sections.status.info.aria": "معلومات إضافية", + + // "submission.sections.toggle.open": "Open section", "submission.sections.toggle.open": "فتح القسم", + + // "submission.sections.toggle.close": "Close section", "submission.sections.toggle.close": "إغلاق القسم", - "submission.sections.toggle.aria.open": "قسم النهائي {{sectionHeader}}", + + // "submission.sections.toggle.aria.open": "Expand {{sectionHeader}} section", + "submission.sections.toggle.aria.open": "توسيع قسم {{sectionHeader}}", + + // "submission.sections.toggle.aria.close": "Collapse {{sectionHeader}} section", "submission.sections.toggle.aria.close": "طي قسم {{sectionHeader}}", - "submission.sections.upload.primary.make": "يصنع {{fileName}} تيار البت الأساسي", - "submission.sections.upload.primary.remove": "يزيل {{fileName}} باعتباره دفق البت الأساسي", + + // "submission.sections.upload.primary.make": "Make {{fileName}} the primary bitstream", + // TODO New key - Add a translation + "submission.sections.upload.primary.make": "Make {{fileName}} the primary bitstream", + + // "submission.sections.upload.primary.remove": "Remove {{fileName}} as the primary bitstream", + // TODO New key - Add a translation + "submission.sections.upload.primary.remove": "Remove {{fileName}} as the primary bitstream", + + // "submission.sections.upload.delete.confirm.cancel": "Cancel", "submission.sections.upload.delete.confirm.cancel": "إلغاء", - "submission.sections.upload.delete.confirm.info": "لا يمكن السماء عن هذه الطريقة. ", - "submission.sections.upload.delete.confirm.submit": "نعم، بالتأكيد", + + // "submission.sections.upload.delete.confirm.info": "This operation can't be undone. Are you sure?", + "submission.sections.upload.delete.confirm.info": "لا يمكن التراجع عن هذه العملية. هل أنت متأكد؟", + + // "submission.sections.upload.delete.confirm.submit": "Yes, I'm sure", + "submission.sections.upload.delete.confirm.submit": "نعم، متأكد", + + // "submission.sections.upload.delete.confirm.title": "Delete bitstream", "submission.sections.upload.delete.confirm.title": "حذف تدفق البت", + + // "submission.sections.upload.delete.submit": "Delete", "submission.sections.upload.delete.submit": "حذف", + + // "submission.sections.upload.download.title": "Download bitstream", "submission.sections.upload.download.title": "تحميل تدفق البت", - "submission.sections.upload.drop-message": "قم بإسقاط الملفات لإختفاءها بالمادة", + + // "submission.sections.upload.drop-message": "Drop files to attach them to the item", + "submission.sections.upload.drop-message": "قم بإسقاط الملفات لإرفاقها بالمادة", + + // "submission.sections.upload.edit.title": "Edit bitstream", "submission.sections.upload.edit.title": "تحرير دفق البت", + + // "submission.sections.upload.form.access-condition-label": "Access condition type", "submission.sections.upload.form.access-condition-label": "نوع شرط الوصول", - "submission.sections.upload.form.access-condition-hint": "حدد شرط الوصول إليه على تدفق المادة بمجرد إيداعها", + + // "submission.sections.upload.form.access-condition-hint": "Select an access condition to apply on the bitstream once the item is deposited", + "submission.sections.upload.form.access-condition-hint": "حدد شرط الوصول لتطبيقه على تدفقات البت بمجرد إيداع المادة", + + // "submission.sections.upload.form.date-required": "Date is required.", "submission.sections.upload.form.date-required": "التاريخ مطلوب.", - "submission.sections.upload.form.date-required-from": "تاريخ منح الوصول قبل مطلوب.", + + // "submission.sections.upload.form.date-required-from": "Grant access from date is required.", + "submission.sections.upload.form.date-required-from": "تاريخ منح الوصول منذ مطلوب.", + + // "submission.sections.upload.form.date-required-until": "Grant access until date is required.", "submission.sections.upload.form.date-required-until": "تاريخ منح الوصول حتى مطلوب.", - "submission.sections.upload.form.from-label": "أمنح من الوصول", - "submission.sections.upload.form.from-hint": "حدد التاريخ الذي يتم فيه تطبيق شرط الوصول ذي الصلة منذ البداية", + + // "submission.sections.upload.form.from-label": "Grant access from", + "submission.sections.upload.form.from-label": "منح الوصول من", + + // "submission.sections.upload.form.from-hint": "Select the date from which the related access condition is applied", + "submission.sections.upload.form.from-hint": "حدد التاريخ الذي يتم تطبيق شرط الوصول ذي الصلة منذ بلوغه", + + // "submission.sections.upload.form.from-placeholder": "From", "submission.sections.upload.form.from-placeholder": "من", + + // "submission.sections.upload.form.group-label": "Group", "submission.sections.upload.form.group-label": "المجموعة", + + // "submission.sections.upload.form.group-required": "Group is required.", "submission.sections.upload.form.group-required": "المجموعة مطلوبة.", - "submission.sections.upload.form.until-label": "أمنح حتى الوصول", - "submission.sections.upload.form.until-hint": "حدد التاريخ الذي يتم فيه تطبيق شرط الوصول ذي الصلة حتى المضي قدمًا", + + // "submission.sections.upload.form.until-label": "Grant access until", + "submission.sections.upload.form.until-label": "منح الوصول حتى", + + // "submission.sections.upload.form.until-hint": "Select the date until which the related access condition is applied", + "submission.sections.upload.form.until-hint": "حدد التاريخ الذي يتم تطبيق شرط الوصول ذي الصلة حتى بلوغه", + + // "submission.sections.upload.form.until-placeholder": "Until", "submission.sections.upload.form.until-placeholder": "حتى", - "submission.sections.upload.header.policy.default.nolist": "ستكون الإجراءات المرفوعة في الكائنات الحية {{collectionName}} لا يمكن الوصول إلى المجموعات التالية:", - "submission.sections.upload.header.policy.default.withlist": "يرجى ملاحظة أن الملفات المرفوعة في الحاوية {{collectionName}} ستكون قادرة على الوصول، بالإضافة إلى ما يقرر بوضوح للملف المفرد، مع المجموعات التالية:", - "submission.sections.upload.info": "مساهمة هنا في كل القضايا الموجودة في المادة حاليا. تحميل الملفات الإضافية عن طريق سحبها وتسجيلها في أي مكان في الصفحة", + + // "submission.sections.upload.header.policy.default.nolist": "Uploaded files in the {{collectionName}} collection will be accessible according to the following group(s):", + "submission.sections.upload.header.policy.default.nolist": "ستكون الملفات المرفوعة في الحاوية {{collectionName}} قابلة للوصول وفقًا للمجموعات التالية:", + + // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", + "submission.sections.upload.header.policy.default.withlist": "يرجى ملاحظة أن الملفات المرفوعة في حاوية {{collectionName}} ستكون قابلة للوصول، بالإضافة إلى ما تقرر بوضوح للملف المفرد، مع المجموعات التالية:", + + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", + "submission.sections.upload.info": "ستجد هنا كل الملفات الموجودة في المادة حاليًا. يمكنك تحديث ميتاداتا الملف وشروط الوصول أو تحميل ملفات إضافية عن طريق سحبها وإسقاطها في أي مكان في الصفحة", + + // "submission.sections.upload.no-entry": "No", "submission.sections.upload.no-entry": "لا", + + // "submission.sections.upload.no-file-uploaded": "No file uploaded yet.", "submission.sections.upload.no-file-uploaded": "لم يتم تحميل أي ملف حتى الآن.", + + // "submission.sections.upload.save-metadata": "Save metadata", "submission.sections.upload.save-metadata": "حفظ الميتاداتا", + + // "submission.sections.upload.undo": "Cancel", "submission.sections.upload.undo": "إلغاء", + + // "submission.sections.upload.upload-failed": "Upload failed", "submission.sections.upload.upload-failed": "فشل التحميل", - "submission.sections.upload.upload-successful": "بدأ التحميل", - "submission.sections.accesses.form.discoverable-description": "عند التحديد، ستكون هذه المادة قابلة للاكتشاف في البحث/الاستعراض. ", + + // "submission.sections.upload.upload-successful": "Upload successful", + "submission.sections.upload.upload-successful": "نجح التحميل", + + // "submission.sections.accesses.form.discoverable-description": "When checked, this item will be discoverable in search/browse. When unchecked, the item will only be available via a direct link and will never appear in search/browse.", + "submission.sections.accesses.form.discoverable-description": "عند التحديد، ستكون هذه المادة قابلة للاكتشاف في البحث/الاستعراض. عند إلغاء التحديد، ستكون المادة متاحة فقط عبر رابط مباشر ولن تظهر أبدًا في البحث/الاستعراض.", + + // "submission.sections.accesses.form.discoverable-label": "Discoverable", "submission.sections.accesses.form.discoverable-label": "قابل للاكتشاف", + + // "submission.sections.accesses.form.access-condition-label": "Access condition type", "submission.sections.accesses.form.access-condition-label": "نوع شرط الوصول", - "submission.sections.accesses.form.access-condition-hint": "حدد شرط الوصول إلى المادة بمجرد إيداعها", + + // "submission.sections.accesses.form.access-condition-hint": "Select an access condition to apply on the item once it is deposited", + "submission.sections.accesses.form.access-condition-hint": "حدد شرط الوصول لتطبيقه على المادة بمجرد إيداعها", + + // "submission.sections.accesses.form.date-required": "Date is required.", "submission.sections.accesses.form.date-required": "التاريخ مطلوب.", - "submission.sections.accesses.form.date-required-from": "تاريخ منح الوصول قبل مطلوب.", + + // "submission.sections.accesses.form.date-required-from": "Grant access from date is required.", + "submission.sections.accesses.form.date-required-from": "تاريخ منح الوصول منذ مطلوب.", + + // "submission.sections.accesses.form.date-required-until": "Grant access until date is required.", "submission.sections.accesses.form.date-required-until": "تاريخ منح الوصول حتى مطلوب.", - "submission.sections.accesses.form.from-label": "منح قبل الوصول", + + // "submission.sections.accesses.form.from-label": "Grant access from", + "submission.sections.accesses.form.from-label": "منح الوصول منذ", + + // "submission.sections.accesses.form.from-hint": "Select the date from which the related access condition is applied", "submission.sections.accesses.form.from-hint": "حدد التاريخ الذي يتم فيه تطبيق شرط الوصول ذي الصلة", + + // "submission.sections.accesses.form.from-placeholder": "From", "submission.sections.accesses.form.from-placeholder": "من", + + // "submission.sections.accesses.form.group-label": "Group", "submission.sections.accesses.form.group-label": "المجموعة", + + // "submission.sections.accesses.form.group-required": "Group is required.", "submission.sections.accesses.form.group-required": "المجموعة مطلوبة.", - "submission.sections.accesses.form.until-label": "أمنح حتى الوصول", - "submission.sections.accesses.form.until-hint": "حدد التاريخ الذي يتم فيه تطبيق شرط الوصول ذي الصلة حتى المضي قدمًا", + + // "submission.sections.accesses.form.until-label": "Grant access until", + "submission.sections.accesses.form.until-label": "منح الوصول حتى", + + // "submission.sections.accesses.form.until-hint": "Select the date until which the related access condition is applied", + "submission.sections.accesses.form.until-hint": "حدد التاريخ الذي يتم تطبيق شرط الوصول ذي الصلة حتى بلوغه", + + // "submission.sections.accesses.form.until-placeholder": "Until", "submission.sections.accesses.form.until-placeholder": "حتى", - "submission.sections.duplicates.none": "لم يتم اكتشاف أي تكرارات.", - "submission.sections.duplicates.detected": "تم الكشف عن التكرارات المحتملة. ", - "submission.sections.duplicates.in-workspace": "هذا العنصر موجود في مساحة العمل", - "submission.sections.duplicates.in-workflow": "هذا العنصر في سير العمل", - "submission.sections.license.granted-label": "وأرجح ذلك", - "submission.sections.license.required": "يجب عليك معارضة", - "submission.sections.license.notgranted": "يجب عليك معارضة", + + // "submission.sections.duplicates.none": "No duplicates were detected.", + // TODO New key - Add a translation + "submission.sections.duplicates.none": "No duplicates were detected.", + + // "submission.sections.duplicates.detected": "Potential duplicates were detected. Please review the list below.", + // TODO New key - Add a translation + "submission.sections.duplicates.detected": "Potential duplicates were detected. Please review the list below.", + + // "submission.sections.duplicates.in-workspace": "This item is in workspace", + // TODO New key - Add a translation + "submission.sections.duplicates.in-workspace": "This item is in workspace", + + // "submission.sections.duplicates.in-workflow": "This item is in workflow", + // TODO New key - Add a translation + "submission.sections.duplicates.in-workflow": "This item is in workflow", + + // "submission.sections.license.granted-label": "I confirm the license above", + "submission.sections.license.granted-label": "أؤكد الترخيص أعلاه", + + // "submission.sections.license.required": "You must accept the license", + "submission.sections.license.required": "يجب عليك قبول الترخيص", + + // "submission.sections.license.notgranted": "You must accept the license", + "submission.sections.license.notgranted": "يجب عليك قبول الترخيص", + + // "submission.sections.sherpa.publication.information": "Publication information", "submission.sections.sherpa.publication.information": "معلومات الناشر", - "submission.sections.sherpa.publication.information.title": "عنوان العنوان", + + // "submission.sections.sherpa.publication.information.title": "Title", + "submission.sections.sherpa.publication.information.title": "العنوان", + + // "submission.sections.sherpa.publication.information.issns": "ISSNs", "submission.sections.sherpa.publication.information.issns": "أرقام ردمد", + + // "submission.sections.sherpa.publication.information.url": "URL", "submission.sections.sherpa.publication.information.url": "عنوان URL", + + // "submission.sections.sherpa.publication.information.publishers": "Publisher", "submission.sections.sherpa.publication.information.publishers": "الناشر", - "submission.sections.sherpa.publication.information.romeoPub": "حانة روميو", - "submission.sections.sherpa.publication.information.zetoPub": "حانة زيتو", - "submission.sections.sherpa.publisher.policy": "للناشر", - "submission.sections.sherpa.publisher.policy.description": "تم العثور على المعلومات أدناه عبر شيربا روميو. ", - "submission.sections.sherpa.publisher.policy.openaccess": "مسارات الوصول الحر التي تتيح لها هذه الدورية المدرجة أدناه حسب إصدار المقال. ", - "submission.sections.sherpa.publisher.policy.more.information": "لمزيد من المعلومات، يرجى الاطلاع على الروابط التالية:", - "submission.sections.sherpa.publisher.policy.version": "النسخة", + + // "submission.sections.sherpa.publication.information.romeoPub": "Romeo Pub", + "submission.sections.sherpa.publication.information.romeoPub": "Romeo Pub", + + // "submission.sections.sherpa.publication.information.zetoPub": "Zeto Pub", + "submission.sections.sherpa.publication.information.zetoPub": "Zeto Pub", + + // "submission.sections.sherpa.publisher.policy": "Publisher Policy", + "submission.sections.sherpa.publisher.policy": "سياسة الناشر", + + // "submission.sections.sherpa.publisher.policy.description": "The below information was found via Sherpa Romeo. Based on the policies of your publisher, it provides advice regarding whether an embargo may be necessary and/or which files you are allowed to upload. If you have questions, please contact your site administrator via the feedback form in the footer.", + "submission.sections.sherpa.publisher.policy.description": "تم العثور على المعلومات أدناه عبر شيربا روميو. وبناءً على سياسات الناشر الخاص بك، فإنه يقدم النصائح بشأن ما إذا كان الحظر ضروريًا أو الملفات المسموح لك بتحميلها. إذا كانت لديك أسئلة، يرجى الاتصال بمسؤول موقعك عبر نموذج التعليقات الموجود في التذييل.", + + // "submission.sections.sherpa.publisher.policy.openaccess": "Open Access pathways permitted by this journal's policy are listed below by article version. Click on a pathway for a more detailed view", + "submission.sections.sherpa.publisher.policy.openaccess": "مسارات الوصول الحر التي تسمح بها سياسة هذه الدورية مدرجة أدناه حسب إصدار المقال. انقر على المسار للحصول على عرض أكثر تفصيلاً", + + // "submission.sections.sherpa.publisher.policy.more.information": "For more information, please see the following links:", + "submission.sections.sherpa.publisher.policy.more.information": "للمزيد من المعلومات، يرجى الاطلاع على الروابط التالية:", + + // "submission.sections.sherpa.publisher.policy.version": "Version", + "submission.sections.sherpa.publisher.policy.version": "الإصدارة", + + // "submission.sections.sherpa.publisher.policy.embargo": "Embargo", "submission.sections.sherpa.publisher.policy.embargo": "حظر", + + // "submission.sections.sherpa.publisher.policy.noembargo": "No Embargo", "submission.sections.sherpa.publisher.policy.noembargo": "بلا حظر", + + // "submission.sections.sherpa.publisher.policy.nolocation": "None", "submission.sections.sherpa.publisher.policy.nolocation": "لا شيء", - "submission.sections.sherpa.publisher.policy.license": "com", + + // "submission.sections.sherpa.publisher.policy.license": "License", + "submission.sections.sherpa.publisher.policy.license": "الترخيص", + + // "submission.sections.sherpa.publisher.policy.prerequisites": "Prerequisites", "submission.sections.sherpa.publisher.policy.prerequisites": "المتطلبات الأساسية", + + // "submission.sections.sherpa.publisher.policy.location": "Location", "submission.sections.sherpa.publisher.policy.location": "الموقع", + + // "submission.sections.sherpa.publisher.policy.conditions": "Conditions", "submission.sections.sherpa.publisher.policy.conditions": "الشروط", + + // "submission.sections.sherpa.publisher.policy.refresh": "Refresh", "submission.sections.sherpa.publisher.policy.refresh": "تحديث", - "submission.sections.sherpa.record.information": "تسجيل المعلومات", + + // "submission.sections.sherpa.record.information": "Record Information", + "submission.sections.sherpa.record.information": "معلومات التسجيلة", + + // "submission.sections.sherpa.record.information.id": "ID", "submission.sections.sherpa.record.information.id": "المعرّف", + + // "submission.sections.sherpa.record.information.date.created": "Date Created", "submission.sections.sherpa.record.information.date.created": "تاريخ الإنشاء", + + // "submission.sections.sherpa.record.information.date.modified": "Last Modified", "submission.sections.sherpa.record.information.date.modified": "آخر تعديل", + + // "submission.sections.sherpa.record.information.uri": "URI", "submission.sections.sherpa.record.information.uri": "URI", - "submission.sections.sherpa.error.message": "حدث خطأ أثناء حذف معلومات شيربا", + + // "submission.sections.sherpa.error.message": "There was an error retrieving sherpa informations", + "submission.sections.sherpa.error.message": "حدث خطأ أثناء استرداد معلومات شيربا", + + // "submission.submit.breadcrumbs": "New submission", "submission.submit.breadcrumbs": "تقديم جديد", + + // "submission.submit.title": "New submission", "submission.submit.title": "تقديم جديد", + + // "submission.workflow.generic.delete": "Delete", "submission.workflow.generic.delete": "حذف", - "submission.workflow.generic.delete-help": "حدد هذا الخيار لتجاهل هذه المادة. ", + + // "submission.workflow.generic.delete-help": "Select this option to discard this item. You will then be asked to confirm it.", + "submission.workflow.generic.delete-help": "حدد هذا الخيار لتجاهل هذه المادة. سيُطلب منك بعد ذلك تأكيد ذلك.", + + // "submission.workflow.generic.edit": "Edit", "submission.workflow.generic.edit": "تحرير", - "submission.workflow.generic.edit-help": "حدد هذا الخيار لتكوين المادة.", + + // "submission.workflow.generic.edit-help": "Select this option to change the item's metadata.", + "submission.workflow.generic.edit-help": "حدد هذا الخيار لتغيير ميتاداتا المادة.", + + // "submission.workflow.generic.view": "View", "submission.workflow.generic.view": "عرض", + + // "submission.workflow.generic.view-help": "Select this option to view the item's metadata.", "submission.workflow.generic.view-help": "حدد هذا الخيار لعرض ميتاداتا المادة.", + + // "submission.workflow.generic.submit_select_reviewer": "Select Reviewer", "submission.workflow.generic.submit_select_reviewer": "حدد المراجع", + + // "submission.workflow.generic.submit_select_reviewer-help": "", "submission.workflow.generic.submit_select_reviewer-help": "", + + // "submission.workflow.generic.submit_score": "Rate", "submission.workflow.generic.submit_score": "تقييم", + + // "submission.workflow.generic.submit_score-help": "", "submission.workflow.generic.submit_score-help": "", - "submission.workflow.tasks.claimed.approve": "أوافق", - "submission.workflow.tasks.claimed.approve_help": "إذا قمت بمراجعة المادة الداخلية للاستهلاك الغذائي، اختر \"قبول\".", + + // "submission.workflow.tasks.claimed.approve": "Approve", + "submission.workflow.tasks.claimed.approve": "قبول", + + // "submission.workflow.tasks.claimed.approve_help": "If you have reviewed the item and it is suitable for inclusion in the collection, select \"Approve\".", + "submission.workflow.tasks.claimed.approve_help": "إذا قمت بمراجعة المادة وكانت ملائمة للإدراج في الحاوية، اختر \"قبول\".", + + // "submission.workflow.tasks.claimed.edit": "Edit", "submission.workflow.tasks.claimed.edit": "تحرير", - "submission.workflow.tasks.claimed.edit_help": "سيقوم هذا الخيار بتغيير المادة.", - "submission.workflow.tasks.claimed.decline": "الرفض", + + // "submission.workflow.tasks.claimed.edit_help": "Select this option to change the item's metadata.", + "submission.workflow.tasks.claimed.edit_help": "قم بتحديد هذا الخيار لتغيير ميتاداتا المادة.", + + // "submission.workflow.tasks.claimed.decline": "Decline", + "submission.workflow.tasks.claimed.decline": "رفض", + + // "submission.workflow.tasks.claimed.decline_help": "", "submission.workflow.tasks.claimed.decline_help": "", - "submission.workflow.tasks.claimed.reject.reason.info": "يرجي التسجيل سبب الرفض في القسم أدناه، وقم بتوضيح ما إذا كان بإمكانه تصحيح المشكلة لتقديم الطلب.", + + // "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", + "submission.workflow.tasks.claimed.reject.reason.info": "يرجي إدخال سبب رفض التقديم في المربع أدناه، وقم بتوضيح ما إذا كان بإمكان المقدم تصحيح المشكلة وإعادة التقديم.", + + // "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", "submission.workflow.tasks.claimed.reject.reason.placeholder": "قم بوصف سبب الرفض", - "submission.workflow.tasks.claimed.reject.reason.submit": "الموافقة على المادة", - "submission.workflow.tasks.claimed.reject.reason.title": "هذا", - "submission.workflow.tasks.claimed.reject.submit": "الرفض", - "submission.workflow.tasks.claimed.reject_help": "إذا قمت بمراجعة المادة وجدتها غير وجزء للإدراج في الصغار، اختر \"رفض\". ", + + // "submission.workflow.tasks.claimed.reject.reason.submit": "Reject item", + "submission.workflow.tasks.claimed.reject.reason.submit": "رفض المادة", + + // "submission.workflow.tasks.claimed.reject.reason.title": "Reason", + "submission.workflow.tasks.claimed.reject.reason.title": "السبب", + + // "submission.workflow.tasks.claimed.reject.submit": "Reject", + "submission.workflow.tasks.claimed.reject.submit": "رفض", + + // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", + "submission.workflow.tasks.claimed.reject_help": "إذا قمت بمراجعة المادة ووجدتها غير ملائمة للإدراج في الحاوية، اختر \"رفض\". سيُطلب منك إدخال رسالة لتوضيح سبب عدم ملاءمة المادة، وما إذا كان يجب على المقدم إجراء بعض التغييرات وإعادة التقديم.", + + // "submission.workflow.tasks.claimed.return": "Return to pool", "submission.workflow.tasks.claimed.return": "إعادة إلى الصحن", - "submission.workflow.tasks.claimed.return_help": "إعادة مهمة إلى السخن لكي يقوم مستخدم آخر المهرج.", - "submission.workflow.tasks.generic.error": "حدث خطأ أثناء...", - "submission.workflow.tasks.generic.processing": "جاريب...", - "submission.workflow.tasks.generic.submitter": "شير", - "submission.workflow.tasks.generic.success": "فعال", + + // "submission.workflow.tasks.claimed.return_help": "Return the task to the pool so that another user may perform the task.", + "submission.workflow.tasks.claimed.return_help": "إعادة المهمة إلى الصحن لكي يقوم مستخدم آخر بأداء المهمة.", + + // "submission.workflow.tasks.generic.error": "Error occurred during operation...", + "submission.workflow.tasks.generic.error": "حدث خطأ أثناء العملية...", + + // "submission.workflow.tasks.generic.processing": "Processing...", + "submission.workflow.tasks.generic.processing": "جاري المعالجة...", + + // "submission.workflow.tasks.generic.submitter": "Submitter", + "submission.workflow.tasks.generic.submitter": "المقدم", + + // "submission.workflow.tasks.generic.success": "Operation successful", + "submission.workflow.tasks.generic.success": "تمت العملية بنجاح", + + // "submission.workflow.tasks.pool.claim": "Claim", "submission.workflow.tasks.pool.claim": "مطالبة", - "submission.workflow.tasks.pool.claim_help": "قم بهذه المهمة لأجلك.", - "submission.workflow.tasks.pool.hide-detail": "حفظ التفاصيل", + + // "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", + "submission.workflow.tasks.pool.claim_help": "قم بتعيين هذه المهمة لنفسك.", + + // "submission.workflow.tasks.pool.hide-detail": "Hide detail", + "submission.workflow.tasks.pool.hide-detail": "إخفاء التفاصيل", + + // "submission.workflow.tasks.pool.show-detail": "Show detail", "submission.workflow.tasks.pool.show-detail": "عرض التفاصيل", - "submission.workflow.tasks.duplicates": "تم الكشف عن التكرارات المحتملة لهذا العنصر. ", + + // "submission.workflow.tasks.duplicates": "potential duplicates were detected for this item. Claim and edit this item to see details.", + // TODO New key - Add a translation + "submission.workflow.tasks.duplicates": "potential duplicates were detected for this item. Claim and edit this item to see details.", + + // "submission.workspace.generic.view": "View", "submission.workspace.generic.view": "عرض", + + // "submission.workspace.generic.view-help": "Select this option to view the item's metadata.", "submission.workspace.generic.view-help": "حدد هذا الخيار لعرض ميتاداتا المادة.", - "submitter.empty": "غير محتمل", + + // "submitter.empty": "N/A", + "submitter.empty": "غير قابل للتطبيق", + + // "subscriptions.title": "Subscriptions", "subscriptions.title": "الاشتراكات", - "subscriptions.item": "الاشتراكات للمواد", + + // "subscriptions.item": "Subscriptions for items", + "subscriptions.item": "اشتراكات للمواد", + + // "subscriptions.collection": "Subscriptions for collections", "subscriptions.collection": "اشتراكات للحاويات", - "subscriptions.community": "الاشتراكات المتاحة", + + // "subscriptions.community": "Subscriptions for communities", + "subscriptions.community": "اشتراكات للمجتمعات", + + // "subscriptions.subscription_type": "Subscription type", "subscriptions.subscription_type": "نوع الاشتراك", + + // "subscriptions.frequency": "Subscription frequency", "subscriptions.frequency": "تواتر الاشتراك", + + // "subscriptions.frequency.D": "Daily", "subscriptions.frequency.D": "يومي", + + // "subscriptions.frequency.M": "Monthly", "subscriptions.frequency.M": "شهري", + + // "subscriptions.frequency.W": "Weekly", "subscriptions.frequency.W": "أسبوعي", + + // "subscriptions.tooltip": "Subscribe", "subscriptions.tooltip": "اشتراك", + + // "subscriptions.modal.title": "Subscriptions", "subscriptions.modal.title": "الاشتراكات", + + // "subscriptions.modal.type-frequency": "Type and frequency", "subscriptions.modal.type-frequency": "النوع والتواتر", + + // "subscriptions.modal.close": "Close", "subscriptions.modal.close": "إغلاق", - "subscriptions.modal.delete-info": "إزالة هذا الاشتراك، يرجى زيارة صفحة \"الاشتراكات\" أدنى ملف تعريف المستخدم الخاص بك", - "subscriptions.modal.new-subscription-form.type.content": "ال", + + // "subscriptions.modal.delete-info": "To remove this subscription, please visit the \"Subscriptions\" page under your user profile", + "subscriptions.modal.delete-info": "لإزالة هذا الاشتراك، يرجى زيارة صفحة \"الاشتراكات\" أدنى ملف تعريف المستخدم الخاص بك", + + // "subscriptions.modal.new-subscription-form.type.content": "Content", + "subscriptions.modal.new-subscription-form.type.content": "المحتوى", + + // "subscriptions.modal.new-subscription-form.frequency.D": "Daily", "subscriptions.modal.new-subscription-form.frequency.D": "يومي", + + // "subscriptions.modal.new-subscription-form.frequency.W": "Weekly", "subscriptions.modal.new-subscription-form.frequency.W": "أسبوعي", + + // "subscriptions.modal.new-subscription-form.frequency.M": "Monthly", "subscriptions.modal.new-subscription-form.frequency.M": "شهري", + + // "subscriptions.modal.new-subscription-form.submit": "Submit", "subscriptions.modal.new-subscription-form.submit": "تقديم", - "subscriptions.modal.new-subscription-form.processing": "جاريب...", - "subscriptions.modal.create.success": "تم الاشتراك في {{type}} فعالية.", - "subscriptions.modal.delete.success": "تم حذف الاشتراك الفعال", - "subscriptions.modal.update.success": "تم تحديث الاشتراك في {{type}} فعالية", + + // "subscriptions.modal.new-subscription-form.processing": "Processing...", + "subscriptions.modal.new-subscription-form.processing": "جاري المعالجة...", + + // "subscriptions.modal.create.success": "Subscribed to {{ type }} successfully.", + "subscriptions.modal.create.success": "تم الاشتراك في {{type}} بنجاح.", + + // "subscriptions.modal.delete.success": "Subscription deleted successfully", + "subscriptions.modal.delete.success": "تم حذف الاشتراك بنجاح", + + // "subscriptions.modal.update.success": "Subscription to {{ type }} updated successfully", + "subscriptions.modal.update.success": "تم تحديث الاشتراك في {{type}} بنجاح", + + // "subscriptions.modal.create.error": "An error occurs during the subscription creation", "subscriptions.modal.create.error": "حدث خطأ أثناء إنشاء الاشتراك", + + // "subscriptions.modal.delete.error": "An error occurs during the subscription delete", "subscriptions.modal.delete.error": "حدث خطأ أثناء حذف الاشتراك", + + // "subscriptions.modal.update.error": "An error occurs during the subscription update", "subscriptions.modal.update.error": "حدث خطأ أثناء تحديث الاشتراك", + + // "subscriptions.table.dso": "Subject", "subscriptions.table.dso": "الموضوع", + + // "subscriptions.table.subscription_type": "Subscription Type", "subscriptions.table.subscription_type": "نوع الاشتراك", + + // "subscriptions.table.subscription_frequency": "Subscription Frequency", "subscriptions.table.subscription_frequency": "تواتر الاشتراك", - "subscriptions.table.action": "صنع", + + // "subscriptions.table.action": "Action", + "subscriptions.table.action": "إجراء", + + // "subscriptions.table.edit": "Edit", "subscriptions.table.edit": "تحرير", + + // "subscriptions.table.delete": "Delete", "subscriptions.table.delete": "حذف", + + // "subscriptions.table.not-available": "Not available", "subscriptions.table.not-available": "غير متاح", - "subscriptions.table.not-available-message": "تم حذف مادة الاشتراك، أو ليس لديك صلاحية حاليا لمشاهدتها", - "subscriptions.table.empty.message": "ليس لديك أي اشتراك في هذا الوقت. ", + + // "subscriptions.table.not-available-message": "The subscribed item has been deleted, or you don't currently have the permission to view it", + "subscriptions.table.not-available-message": "تم حذف مادة الاشتراك، أو ليس لديك صلاحية حالياً لمشاهدتها", + + // "subscriptions.table.empty.message": "You do not have any subscriptions at this time. To subscribe to email updates for a Community or Collection, use the subscription button on the object's page.", + "subscriptions.table.empty.message": "ليس لديك أي اشتراكات في هذا الوقت. للاشتراك في تحديثات البريد الإلكتروني لمجتمع أو حاوية، استخدم زر الاشتراك الموجود في صفحة الكائن.", + + // "thumbnail.default.alt": "Thumbnail Image", "thumbnail.default.alt": "صورة مصغرة", - "thumbnail.default.placeholder": "لا اختيار صورة مصغرة", + + // "thumbnail.default.placeholder": "No Thumbnail Available", + "thumbnail.default.placeholder": "لا تتوفر صورة مصغرة", + + // "thumbnail.project.alt": "Project Logo", "thumbnail.project.alt": "شعار المشروع", - "thumbnail.project.placeholder": "صورة كمساهمة في المساهمة", - "thumbnail.orgunit.alt": "الشعار الوطني الوطني", - "thumbnail.orgunit.placeholder": "صورة الكارب النائي للوحدة الوطنية", + + // "thumbnail.project.placeholder": "Project Placeholder Image", + "thumbnail.project.placeholder": "صورة العنصر النائب للمشروع", + + // "thumbnail.orgunit.alt": "OrgUnit Logo", + "thumbnail.orgunit.alt": "شعار الوحدة المؤسسية", + + // "thumbnail.orgunit.placeholder": "OrgUnit Placeholder Image", + "thumbnail.orgunit.placeholder": "صورة العنصر النائي للوحدة المؤسسية", + + // "thumbnail.person.alt": "Profile Picture", "thumbnail.person.alt": "صورة الملف الشخصي", - "thumbnail.person.placeholder": "عدم توفر صورة للملف الشخصي", + + // "thumbnail.person.placeholder": "No Profile Picture Available", + "thumbnail.person.placeholder": "لا تتوافر صورة للملف الشخصي", + + // "title": "DSpace", "title": "دي سبيس", + + // "vocabulary-treeview.header": "Hierarchical tree view", "vocabulary-treeview.header": "عرض الشجرة الهرمية", + + // "vocabulary-treeview.load-more": "Load more", "vocabulary-treeview.load-more": "تحميل المزيد", + + // "vocabulary-treeview.search.form.reset": "Reset", "vocabulary-treeview.search.form.reset": "إعادة تعيين", + + // "vocabulary-treeview.search.form.search": "Search", "vocabulary-treeview.search.form.search": "بحث", - "vocabulary-treeview.search.form.search-placeholder": "تسهيل البحث عن طريق كتابة الرواية الأولى", + + // "vocabulary-treeview.search.form.search-placeholder": "Filter results by typing the first few letters", + "vocabulary-treeview.search.form.search-placeholder": "تنقيح النتائج عن طريق كتابة الأحرف الأولى", + + // "vocabulary-treeview.search.no-result": "There were no items to show", "vocabulary-treeview.search.no-result": "لم تكن هناك مواد للعرض", - "vocabulary-treeview.tree.description.nsi": "فرس العلوم النرويجي", - "vocabulary-treeview.tree.description.srsc": "موضوع البحث", - "vocabulary-treeview.info": "قم بزيارة موضوع لإضافته كمنقح بحثه", + + // "vocabulary-treeview.tree.description.nsi": "The Norwegian Science Index", + "vocabulary-treeview.tree.description.nsi": "فهرس العلوم النرويجي", + + // "vocabulary-treeview.tree.description.srsc": "Research Subject Categories", + "vocabulary-treeview.tree.description.srsc": "فئات موضوع البحث", + + // "vocabulary-treeview.info": "Select a subject to add as search filter", + "vocabulary-treeview.info": "قم بتحديد موضوع لإضافته كمنقح بحث", + + // "uploader.browse": "browse", "uploader.browse": "استعراض", - "uploader.drag-message": "قم بسحب وتسجيل ملفاتك هنا", + + // "uploader.drag-message": "Drag & Drop your files here", + "uploader.drag-message": "قم بسحب وإسقاط ملفاتك هنا", + + // "uploader.delete.btn-title": "Delete", "uploader.delete.btn-title": "حذف", + + // "uploader.or": ", or ", "uploader.or": ", أو ", - "uploader.processing": "الملفات الجارية التي تم تحميلها... (أصبح من الآن ينتهك هذه الصفحة)", + + // "uploader.processing": "Processing uploaded file(s)... (it's now safe to close this page)", + "uploader.processing": "جاري معالجة الملفات التي تم تحميلها... (أصبح من الآمن الآن إغلاق هذه الصفحة)", + + // "uploader.queue-length": "Queue length", "uploader.queue-length": "طول الصف", - "virtual-metadata.delete-item.info": "قم باختيار الأنواع التي تريد حفظ الميتاداتا لاستخدامها كميتاداتا فعلية", - "virtual-metadata.delete-item.modal-head": "استخدامات مفيدة لهذه المصالح", - "virtual-metadata.delete-relationship.modal-head": "قم بشراء المواد التي تريد حفظ الميتاداتا لاستخدامها كميتاداتا فعلية", - "supervisedWorkspace.search.results.head": "منتج للإشراف", + + // "virtual-metadata.delete-item.info": "Select the types for which you want to save the virtual metadata as real metadata", + "virtual-metadata.delete-item.info": "قم بتحديد الأنواع التي تريد حفظ الميتاداتا الافتراضية لها كميتاداتا فعلية", + + // "virtual-metadata.delete-item.modal-head": "The virtual metadata of this relation", + "virtual-metadata.delete-item.modal-head": "الميتاداتا الافتراضية لهذه العلاقة", + + // "virtual-metadata.delete-relationship.modal-head": "Select the items for which you want to save the virtual metadata as real metadata", + "virtual-metadata.delete-relationship.modal-head": "قم بتحديد المواد التي تريد حفظ الميتاداتا الافتراضية لها كميتاداتا فعلية", + + // "supervisedWorkspace.search.results.head": "Supervised Items", + "supervisedWorkspace.search.results.head": "مواد خاضعة للإشراف", + + // "workspace.search.results.head": "Your submissions", "workspace.search.results.head": "تقديمات", + + // "workflowAdmin.search.results.head": "Administer Workflow", "workflowAdmin.search.results.head": "أدر سير العمل", + + // "workflow.search.results.head": "Workflow tasks", "workflow.search.results.head": "مهام سير العمل", + + // "supervision.search.results.head": "Workflow and Workspace tasks", "supervision.search.results.head": "مهام سير العمل ومساحة العمل", - "orgunit.search.results.head": "نتائج البحث الوطني", - "workflow-item.edit.breadcrumbs": "تحرير سير العمل", - "workflow-item.edit.title": "تحرير سير العمل", + + // "orgunit.search.results.head": "Organizational Unit Search Results", + "orgunit.search.results.head": "نتائج بحث الوحدات المؤسسية", + + // "workflow-item.edit.breadcrumbs": "Edit workflowitem", + "workflow-item.edit.breadcrumbs": "تحرير مادة سير العمل", + + // "workflow-item.edit.title": "Edit workflowitem", + "workflow-item.edit.title": "تحرير مادة سير العمل", + + // "workflow-item.delete.notification.success.title": "Deleted", "workflow-item.delete.notification.success.title": "تم الحذف", - "workflow-item.delete.notification.success.content": "تم حذف المادة سير العمل هذه فعالة", + + // "workflow-item.delete.notification.success.content": "This workflow item was successfully deleted", + "workflow-item.delete.notification.success.content": "تم حذف مادة سير العمل هذه بنجاح", + + // "workflow-item.delete.notification.error.title": "Something went wrong", "workflow-item.delete.notification.error.title": "لقد حدث خطأ ما", - "workflow-item.delete.notification.error.content": "عذر حذف سير العمل", - "workflow-item.delete.title": "حذف سير العمل", - "workflow-item.delete.header": "حذف سير العمل", + + // "workflow-item.delete.notification.error.content": "The workflow item could not be deleted", + "workflow-item.delete.notification.error.content": "تعذر حذف مادة سير العمل", + + // "workflow-item.delete.title": "Delete workflow item", + "workflow-item.delete.title": "حذف مادة سير العمل", + + // "workflow-item.delete.header": "Delete workflow item", + "workflow-item.delete.header": "حذف مادة سير العمل", + + // "workflow-item.delete.button.cancel": "Cancel", "workflow-item.delete.button.cancel": "إلغاء", + + // "workflow-item.delete.button.confirm": "Delete", "workflow-item.delete.button.confirm": "حذف", - "workflow-item.send-back.notification.success.title": "إرسال إعادة إلى الأمام", - "workflow-item.send-back.notification.success.content": "أكمل إعادة صياغة سير العمل إلى هذه الإجراءات الفعالة", + + // "workflow-item.send-back.notification.success.title": "Sent back to submitter", + "workflow-item.send-back.notification.success.title": "إعادة إرسال إلى المقدم", + + // "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", + "workflow-item.send-back.notification.success.content": "تمت إعادة إرسال مادة سير العمل هذه إلى المقدم بنجاح", + + // "workflow-item.send-back.notification.error.title": "Something went wrong", "workflow-item.send-back.notification.error.title": "لقد حدث خطأ ما", - "workflow-item.send-back.notification.error.content": "تعذر إعادة إرسال المادة سير العمل إلى الأمام", - "workflow-item.send-back.title": "إرسال إعادة مادة سير العمل إلى شير", - "workflow-item.send-back.header": "إرسال إعادة مادة سير العمل إلى شير", + + // "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", + "workflow-item.send-back.notification.error.content": "تعذر إعادة إرسال مادة سير العمل إلى المقدم", + + // "workflow-item.send-back.title": "Send workflow item back to submitter", + "workflow-item.send-back.title": "إعادة إرسال مادة سير العمل إلى المقدم", + + // "workflow-item.send-back.header": "Send workflow item back to submitter", + "workflow-item.send-back.header": "إعادة إرسال مادة سير العمل إلى المقدم", + + // "workflow-item.send-back.button.cancel": "Cancel", "workflow-item.send-back.button.cancel": "إلغاء", - "workflow-item.send-back.button.confirm": "إعادة الإرسال", + + // "workflow-item.send-back.button.confirm": "Send back", + "workflow-item.send-back.button.confirm": "إعادة إرسال", + + // "workflow-item.view.breadcrumbs": "Workflow View", "workflow-item.view.breadcrumbs": "عرض سير العمل", + + // "workspace-item.view.breadcrumbs": "Workspace View", "workspace-item.view.breadcrumbs": "عرض مساحة العمل", + + // "workspace-item.view.title": "Workspace View", "workspace-item.view.title": "عرض مساحة العمل", + + // "workspace-item.delete.breadcrumbs": "Workspace Delete", "workspace-item.delete.breadcrumbs": "حذف مساحة العمل", - "workspace-item.delete.header": "حذف مساحة العمل", + + // "workspace-item.delete.header": "Delete workspace item", + "workspace-item.delete.header": "حذف مادة مساحة العمل", + + // "workspace-item.delete.button.confirm": "Delete", "workspace-item.delete.button.confirm": "حذف", + + // "workspace-item.delete.button.cancel": "Cancel", "workspace-item.delete.button.cancel": "إلغاء", + + // "workspace-item.delete.notification.success.title": "Deleted", "workspace-item.delete.notification.success.title": "تم الحذف", - "workspace-item.delete.title": "تم حذف المساحة الفعالة", + + // "workspace-item.delete.title": "This workspace item was successfully deleted", + "workspace-item.delete.title": "تم حذف مادة مساحة العمل بنجاح", + + // "workspace-item.delete.notification.error.title": "Something went wrong", "workspace-item.delete.notification.error.title": "هناك خطأ ما", - "workspace-item.delete.notification.error.content": "عذر حذف مساحة العمل", + + // "workspace-item.delete.notification.error.content": "The workspace item could not be deleted", + "workspace-item.delete.notification.error.content": "تعذر حذف مادة مساحة العمل", + + // "workflow-item.advanced.title": "Advanced workflow", "workflow-item.advanced.title": "سير العمل المتقدم", - "workflow-item.selectrevieweraction.notification.success.title": "المراجع للبحث", - "workflow-item.selectrevieweraction.notification.success.content": "تم اختيار المراجع الخاصة بما في ذلك سير العمل الفعال", + + // "workflow-item.selectrevieweraction.notification.success.title": "Selected reviewer", + "workflow-item.selectrevieweraction.notification.success.title": "المراجع المحدد", + + // "workflow-item.selectrevieweraction.notification.success.content": "The reviewer for this workflow item has been successfully selected", + "workflow-item.selectrevieweraction.notification.success.content": "تم اختيار المراجع الخاص بمادة سير العمل هذه بنجاح", + + // "workflow-item.selectrevieweraction.notification.error.title": "Something went wrong", "workflow-item.selectrevieweraction.notification.error.title": "هناك خطأ ما", - "workflow-item.selectrevieweraction.notification.error.content": "عذر تحديد المراجع لعنصر سير العمل هذا", - "workflow-item.selectrevieweraction.title": "تحديد الزائر", - "workflow-item.selectrevieweraction.header": "تحديد الزائر", + + // "workflow-item.selectrevieweraction.notification.error.content": "Couldn't select the reviewer for this workflow item", + "workflow-item.selectrevieweraction.notification.error.content": "تعذر تحديد المراجع لعنصر سير العمل هذا", + + // "workflow-item.selectrevieweraction.title": "Select Reviewer", + "workflow-item.selectrevieweraction.title": "تحديد مراجع", + + // "workflow-item.selectrevieweraction.header": "Select Reviewer", + "workflow-item.selectrevieweraction.header": "تحديد مراجع", + + // "workflow-item.selectrevieweraction.button.cancel": "Cancel", "workflow-item.selectrevieweraction.button.cancel": "إلغاء", - "workflow-item.selectrevieweraction.button.confirm": "بالتأكيد", + + // "workflow-item.selectrevieweraction.button.confirm": "Confirm", + "workflow-item.selectrevieweraction.button.confirm": "تأكيد", + + // "workflow-item.scorereviewaction.notification.success.title": "Rating review", "workflow-item.scorereviewaction.notification.success.title": "مراجعة التقييم", - "workflow-item.scorereviewaction.notification.success.content": "تم تقديم التقييم الخاص بعنصر سير العمل الفعال", + + // "workflow-item.scorereviewaction.notification.success.content": "The rating for this item workflow item has been successfully submitted", + "workflow-item.scorereviewaction.notification.success.content": "تم إرسال التقييم الخاص بعنصر سير عمل هذه المادة بنجاح", + + // "workflow-item.scorereviewaction.notification.error.title": "Something went wrong", "workflow-item.scorereviewaction.notification.error.title": "هناك خطأ ما", + + // "workflow-item.scorereviewaction.notification.error.content": "Couldn't rate this item", "workflow-item.scorereviewaction.notification.error.content": "تعذر تقييم هذه المادة", + + // "workflow-item.scorereviewaction.title": "Rate this item", "workflow-item.scorereviewaction.title": "قم بتقيم هذه المادة", + + // "workflow-item.scorereviewaction.header": "Rate this item", "workflow-item.scorereviewaction.header": "قم بتقييم هذه المادة", + + // "workflow-item.scorereviewaction.button.cancel": "Cancel", "workflow-item.scorereviewaction.button.cancel": "إلغاء", - "workflow-item.scorereviewaction.button.confirm": "بالتأكيد", - "idle-modal.header": "ستنتهي بعد قليل", - "idle-modal.info": "النهاية، انتهاء الجلسات المستخدمة بعد ذلك {{ timeToExpire }} دقيقة من عدم النشاط. ", + + // "workflow-item.scorereviewaction.button.confirm": "Confirm", + "workflow-item.scorereviewaction.button.confirm": "تأكيد", + + // "idle-modal.header": "Session will expire soon", + "idle-modal.header": "ستنتهي الجلسة بعد قليل", + + // "idle-modal.info": "For security reasons, user sessions expire after {{ timeToExpire }} minutes of inactivity. Your session will expire soon. Would you like to extend it or log out?", + "idle-modal.info": "لأسباب أمنية، تنتهي جلسات المستخدم بعد {{ timeToExpire }} دقيقة من عدم النشاط. ستنتهي جلستك بعد قليل. هل ترغب في تمديدها أم تسجيل الخروج؟", + + // "idle-modal.log-out": "Log out", "idle-modal.log-out": "خروج", + + // "idle-modal.extend-session": "Extend session", "idle-modal.extend-session": "تمديد الجلسة", - "researcher.profile.action.processing": "جاريب...", - "researcher.profile.associated": "الملف للباحثين الشخصيين", - "researcher.profile.change-visibility.fail": "حدث خطأ غير متوقع أثناء تغيير الملف الشخصي", + + // "researcher.profile.action.processing": "Processing...", + "researcher.profile.action.processing": "جاري المعالجة...", + + // "researcher.profile.associated": "Researcher profile associated", + "researcher.profile.associated": "الملف الشخصي للباحث المرتبط", + + // "researcher.profile.change-visibility.fail": "An unexpected error occurs while changing the profile visibility", + "researcher.profile.change-visibility.fail": "حدث خطأ غير متوقع أثناء تغيير رؤية الملف الشخصي", + + // "researcher.profile.create.new": "Create new", "researcher.profile.create.new": "إنشاء جديد", - "researcher.profile.create.success": "تم إنشاء الملف الشخصي للباحث الفعال", + + // "researcher.profile.create.success": "Researcher profile created successfully", + "researcher.profile.create.success": "تم إنشاء الملف الشخصي للباحث بنجاح", + + // "researcher.profile.create.fail": "An error occurs during the researcher profile creation", "researcher.profile.create.fail": "حدث خطأ أثناء إنشاء الملف الشخصي للباحث", + + // "researcher.profile.delete": "Delete", "researcher.profile.delete": "حذف", + + // "researcher.profile.expose": "Expose", "researcher.profile.expose": "عرض", + + // "researcher.profile.hide": "Hide", "researcher.profile.hide": "إخفاء", - "researcher.profile.not.associated": "الملف للباحث شخصي غير مرتبط بعد", + + // "researcher.profile.not.associated": "Researcher profile not yet associated", + "researcher.profile.not.associated": "الملف الشخصي للباحث غير مرتبط بعد", + + // "researcher.profile.view": "View", "researcher.profile.view": "عرض", + + // "researcher.profile.private.visibility": "PRIVATE", "researcher.profile.private.visibility": "خاص", + + // "researcher.profile.public.visibility": "PUBLIC", "researcher.profile.public.visibility": "عام", + + // "researcher.profile.status": "Status:", "researcher.profile.status": "الحالة:", - "researcherprofile.claim.not-authorized": "لا غير لك هذه المادة. ", - "researcherprofile.error.claim.body": "حدث خطأ أثناء استخدام الملف الشخصي، يرجى المحاولة مرة أخرى لاحقاً", + + // "researcherprofile.claim.not-authorized": "You are not authorized to claim this item. For more details contact the administrator(s).", + "researcherprofile.claim.not-authorized": "لا يحق لك المطالبة بهذه المادة. لمزيد من التفاصيل يرجى الاتصال بالمسؤول.", + + // "researcherprofile.error.claim.body": "An error occurred while claiming the profile, please try again later", + "researcherprofile.error.claim.body": "حدث خطأ أثناء المطالبة بالملف الشخصي، يرجى المحاولة مرة أخرى لاحقاً", + + // "researcherprofile.error.claim.title": "Error", "researcherprofile.error.claim.title": "خطأ", - "researcherprofile.success.claim.body": "أكمل بالملف الكامل الفعال", + + // "researcherprofile.success.claim.body": "Profile claimed with success", + "researcherprofile.success.claim.body": "تمت المطالبة بالملف الشخصي بنجاح", + + // "researcherprofile.success.claim.title": "Success", "researcherprofile.success.claim.title": "نجاح", + + // "person.page.orcid.create": "Create an ORCID ID", "person.page.orcid.create": "إنشاء معرف أوركيد", + + // "person.page.orcid.granted-authorizations": "Granted authorizations", "person.page.orcid.granted-authorizations": "التصاريح الممنوحة", + + // "person.page.orcid.grant-authorizations": "Grant authorizations", "person.page.orcid.grant-authorizations": "منح التصاريح", - "person.page.orcid.link": "الاتصال بمعرفة أوركيد", - "person.page.orcid.link.processing": "غاري الملف الشخصي بيوركيد...", - "person.page.orcid.link.error.message": "حدث ما حدث خطأ أثناء ربط الملف الشخصي بوركيد. ", - "person.page.orcid.orcid-not-linked-message": "معرف أوركيد لهذا الملف الشخصي ({{ orcid }}) لم يتم الاتصال به بعد بحسابك في سجل أوركيد أو صلاحية الاتصال.", - "person.page.orcid.unlink": "قطعة الاتصال بأوركيد", - "person.page.orcid.unlink.processing": "جاريب...", - "person.page.orcid.missing-authorizations": "لقد فقدت التصاريح", + + // "person.page.orcid.link": "Connect to ORCID ID", + "person.page.orcid.link": "الاتصال بمعرف أوركيد", + + // "person.page.orcid.link.processing": "Linking profile to ORCID...", + "person.page.orcid.link.processing": "جاري ربط الملف الشخصي بأوركيد...", + + // "person.page.orcid.link.error.message": "Something went wrong while connecting the profile with ORCID. If the problem persists, contact the administrator.", + "person.page.orcid.link.error.message": "حدث خطأ ما أثناء ربط الملف الشخصي بأوركيد. إذا استمرت المشكلة، يرجى الاتصال بالمسؤول.", + + // "person.page.orcid.orcid-not-linked-message": "The ORCID iD of this profile ({{ orcid }}) has not yet been connected to an account on the ORCID registry or the connection is expired.", + "person.page.orcid.orcid-not-linked-message": "معرف أوركيد لهذا الملف الشخصي ({{ orcid }}) لم يتم ربطه بعد بحساب في سجل أوركيد أو انتهت صلاحية الاتصال.", + + // "person.page.orcid.unlink": "Disconnect from ORCID", + "person.page.orcid.unlink": "قطع الاتصال بأوركيد", + + // "person.page.orcid.unlink.processing": "Processing...", + "person.page.orcid.unlink.processing": "جاري المعالجة...", + + // "person.page.orcid.missing-authorizations": "Missing authorizations", + "person.page.orcid.missing-authorizations": "تصاريح مفقودة", + + // "person.page.orcid.missing-authorizations-message": "The following authorizations are missing:", "person.page.orcid.missing-authorizations-message": "التصاريح التالية مفقودة:", - "person.page.orcid.no-missing-authorizations-message": "عظيم! ", - "person.page.orcid.no-orcid-message": "لا يوجد معرف أوركيد مرتبط حتى الآن. ", + + // "person.page.orcid.no-missing-authorizations-message": "Great! This box is empty, so you have granted all access rights to use all functions offers by your institution.", + "person.page.orcid.no-missing-authorizations-message": "عظيم! هذا المربع فارغ، لذا فقد قمت بمنح جميع حقوق الوصول لاستخدام جميع الوظائف التي تقدمها مؤسستك.", + + // "person.page.orcid.no-orcid-message": "No ORCID iD associated yet. By clicking on the button below it is possible to link this profile with an ORCID account.", + "person.page.orcid.no-orcid-message": "لا يوجد معرف أوركيد مرتبط حتى الآن. بالنقر على الزر أدناه من الممكن ربط هذا الملف الشخصي بحساب أوركيد.", + + // "person.page.orcid.profile-preferences": "Profile preferences", "person.page.orcid.profile-preferences": "تفضيلات الملف الشخصي", + + // "person.page.orcid.funding-preferences": "Funding preferences", "person.page.orcid.funding-preferences": "تفضيلات التمويل", - "person.page.orcid.publications-preferences": "مفضلات النشر", + + // "person.page.orcid.publications-preferences": "Publication preferences", + "person.page.orcid.publications-preferences": "تفضيلات النشر", + + // "person.page.orcid.remove-orcid-message": "If you need to remove your ORCID, please contact the repository administrator", "person.page.orcid.remove-orcid-message": "إذا كنت بحاجة إلى إزالة أوركيد الخاص بك، يرجى الاتصال بمسؤول المستودع", + + // "person.page.orcid.save.preference.changes": "Update settings", "person.page.orcid.save.preference.changes": "تحديث الإعدادات", + + // "person.page.orcid.sync-profile.affiliation": "Affiliation", "person.page.orcid.sync-profile.affiliation": "الانتسابات", - "person.page.orcid.sync-profile.biographical": "بيانات الشخصية", + + // "person.page.orcid.sync-profile.biographical": "Biographical data", + "person.page.orcid.sync-profile.biographical": "البيانات الشخصية", + + // "person.page.orcid.sync-profile.education": "Education", "person.page.orcid.sync-profile.education": "التعليم", + + // "person.page.orcid.sync-profile.identifiers": "Identifiers", "person.page.orcid.sync-profile.identifiers": "المعرفات", - "person.page.orcid.sync-fundings.all": "كل التمويل", + + // "person.page.orcid.sync-fundings.all": "All fundings", + "person.page.orcid.sync-fundings.all": "كل التمويلات", + + // "person.page.orcid.sync-fundings.mine": "My fundings", "person.page.orcid.sync-fundings.mine": "تمويلاتي", - "person.page.orcid.sync-fundings.my_selected": "التمويل المحدد", + + // "person.page.orcid.sync-fundings.my_selected": "Selected fundings", + "person.page.orcid.sync-fundings.my_selected": "التمويلات المحددة", + + // "person.page.orcid.sync-fundings.disabled": "Disabled", "person.page.orcid.sync-fundings.disabled": "معطلة", + + // "person.page.orcid.sync-publications.all": "All publications", "person.page.orcid.sync-publications.all": "كل المنشورات", + + // "person.page.orcid.sync-publications.mine": "My publications", "person.page.orcid.sync-publications.mine": "منشوراتي", + + // "person.page.orcid.sync-publications.my_selected": "Selected publications", "person.page.orcid.sync-publications.my_selected": "المنشورات المحددة", + + // "person.page.orcid.sync-publications.disabled": "Disabled", "person.page.orcid.sync-publications.disabled": "معطلة", - "person.page.orcid.sync-queue.discard": "لا ننسى ولا ننسى مع سجل أوركيد", - "person.page.orcid.sync-queue.discard.error": "فشلت في تجاهل تسجيل قائمة انتظار أوركيد", - "person.page.orcid.sync-queue.discard.success": "تم تجاهل تسجيل قائمة انتظار أوركيد الفعالة", - "person.page.orcid.sync-queue.empty-message": "سجل قائمة انتظار أوركيد الكاملة", + + // "person.page.orcid.sync-queue.discard": "Discard the change and do not synchronize with the ORCID registry", + "person.page.orcid.sync-queue.discard": "تجاهل التغيير ولا تقم بالمزامنة مع سجل أوركيد", + + // "person.page.orcid.sync-queue.discard.error": "The discarding of the ORCID queue record failed", + "person.page.orcid.sync-queue.discard.error": "فشل تجاهل تسجيلة قائمة انتظار أوركيد", + + // "person.page.orcid.sync-queue.discard.success": "The ORCID queue record have been discarded successfully", + "person.page.orcid.sync-queue.discard.success": "تم تجاهل تسجيلة قائمة انتظار أوركيد بنجاح", + + // "person.page.orcid.sync-queue.empty-message": "The ORCID queue registry is empty", + "person.page.orcid.sync-queue.empty-message": "سجل قائمة انتظار أوركيد فارغ", + + // "person.page.orcid.sync-queue.table.header.type": "Type", "person.page.orcid.sync-queue.table.header.type": "النوع", + + // "person.page.orcid.sync-queue.table.header.description": "Description", "person.page.orcid.sync-queue.table.header.description": "الوصف", - "person.page.orcid.sync-queue.table.header.action": "صنع", + + // "person.page.orcid.sync-queue.table.header.action": "Action", + "person.page.orcid.sync-queue.table.header.action": "إجراء", + + // "person.page.orcid.sync-queue.description.affiliation": "Affiliations", "person.page.orcid.sync-queue.description.affiliation": "الانتسابات", + + // "person.page.orcid.sync-queue.description.country": "Country", "person.page.orcid.sync-queue.description.country": "البلد", + + // "person.page.orcid.sync-queue.description.education": "Educations", "person.page.orcid.sync-queue.description.education": "التعليم", + + // "person.page.orcid.sync-queue.description.external_ids": "External ids", "person.page.orcid.sync-queue.description.external_ids": "معرفات خارجية", + + // "person.page.orcid.sync-queue.description.other_names": "Other names", "person.page.orcid.sync-queue.description.other_names": "أسماء أخرى", + + // "person.page.orcid.sync-queue.description.qualification": "Qualifications", "person.page.orcid.sync-queue.description.qualification": "المؤهلات", - "person.page.orcid.sync-queue.description.researcher_urls": "عناوين URL للباحثين", - "person.page.orcid.sync-queue.description.keywords": "الكلمات الرئيسية", - "person.page.orcid.sync-queue.tooltip.insert": "إضافة حجم جديد في سجل أوركيد", + + // "person.page.orcid.sync-queue.description.researcher_urls": "Researcher urls", + "person.page.orcid.sync-queue.description.researcher_urls": "عناوين URL للباحث", + + // "person.page.orcid.sync-queue.description.keywords": "Keywords", + "person.page.orcid.sync-queue.description.keywords": "كلمات رئيسية", + + // "person.page.orcid.sync-queue.tooltip.insert": "Add a new entry in the ORCID registry", + "person.page.orcid.sync-queue.tooltip.insert": "إضافة إدخال جديد في سجل أوركيد", + + // "person.page.orcid.sync-queue.tooltip.update": "Update this entry on the ORCID registry", "person.page.orcid.sync-queue.tooltip.update": "تحديث هذا الإدخال في سجل أوركيد", + + // "person.page.orcid.sync-queue.tooltip.delete": "Remove this entry from the ORCID registry", "person.page.orcid.sync-queue.tooltip.delete": "إزالة هذا الإدخال من سجل أوركيد", + + // "person.page.orcid.sync-queue.tooltip.publication": "Publication", "person.page.orcid.sync-queue.tooltip.publication": "النشر", + + // "person.page.orcid.sync-queue.tooltip.project": "Project", "person.page.orcid.sync-queue.tooltip.project": "المشروع", + + // "person.page.orcid.sync-queue.tooltip.affiliation": "Affiliation", "person.page.orcid.sync-queue.tooltip.affiliation": "الانتسابات", + + // "person.page.orcid.sync-queue.tooltip.education": "Education", "person.page.orcid.sync-queue.tooltip.education": "التعليم", + + // "person.page.orcid.sync-queue.tooltip.qualification": "Qualification", "person.page.orcid.sync-queue.tooltip.qualification": "المؤهل", + + // "person.page.orcid.sync-queue.tooltip.other_names": "Other name", "person.page.orcid.sync-queue.tooltip.other_names": "اسم آخر", + + // "person.page.orcid.sync-queue.tooltip.country": "Country", "person.page.orcid.sync-queue.tooltip.country": "البلد", + + // "person.page.orcid.sync-queue.tooltip.keywords": "Keyword", "person.page.orcid.sync-queue.tooltip.keywords": "كلمة رئيسية", + + // "person.page.orcid.sync-queue.tooltip.external_ids": "External identifier", "person.page.orcid.sync-queue.tooltip.external_ids": "معرف خارجي", + + // "person.page.orcid.sync-queue.tooltip.researcher_urls": "Researcher url", "person.page.orcid.sync-queue.tooltip.researcher_urls": "عنوان URL للباحث", - "person.page.orcid.sync-queue.send": "النت مع سجل أوركيد", - "person.page.orcid.sync-queue.send.unauthorized-error.title": "فشل تقديم أوركيد بسبب عيوب التراخيص.", - "person.page.orcid.sync-queue.send.unauthorized-error.content": "انقر هنا لمنح الصلاحيات المطلوبة مرة أخرى. ", + + // "person.page.orcid.sync-queue.send": "Synchronize with ORCID registry", + "person.page.orcid.sync-queue.send": "المزامنة مع سجل أوركيد", + + // "person.page.orcid.sync-queue.send.unauthorized-error.title": "The submission to ORCID failed for missing authorizations.", + "person.page.orcid.sync-queue.send.unauthorized-error.title": "فشل التقديم إلى أوركيد بسبب نقص تصاريح.", + + // "person.page.orcid.sync-queue.send.unauthorized-error.content": "Click here to grant again the required permissions. If the problem persists, contact the administrator", + "person.page.orcid.sync-queue.send.unauthorized-error.content": "انقر هنا لمنح الصلاحيات المطلوبة مرة أخرى. إذا استمرت المشكلة، يرجى الاتصال بالمسؤول", + + // "person.page.orcid.sync-queue.send.bad-request-error": "The submission to ORCID failed because the resource sent to ORCID registry is not valid", "person.page.orcid.sync-queue.send.bad-request-error": "فشل التقديم إلى أوركيد لأن المورد الذي تم إرساله إلى سجل أوركيد غير صالح", + + // "person.page.orcid.sync-queue.send.error": "The submission to ORCID failed", "person.page.orcid.sync-queue.send.error": "فشل التقديم إلى أوركيد", - "person.page.orcid.sync-queue.send.conflict-error": "فشل تقديم أوركيد لأن المورد موجود بالفعل في سجل أوركيد", - "person.page.orcid.sync-queue.send.not-found-warning": "لم يعد موردًا موجودًا في سجل أوركيد.", - "person.page.orcid.sync-queue.send.success": "تم التقديم إلى أوركيد الفعال", + + // "person.page.orcid.sync-queue.send.conflict-error": "The submission to ORCID failed because the resource is already present on the ORCID registry", + "person.page.orcid.sync-queue.send.conflict-error": "فشل التقديم إلى أوركيد لأن المورد موجود بالفعل في سجل أوركيد", + + // "person.page.orcid.sync-queue.send.not-found-warning": "The resource does not exists anymore on the ORCID registry.", + "person.page.orcid.sync-queue.send.not-found-warning": "لم يعد المورد موجودًا في سجل أوركيد.", + + // "person.page.orcid.sync-queue.send.success": "The submission to ORCID was completed successfully", + "person.page.orcid.sync-queue.send.success": "تم اكتمال التقديم إلى أوركيد بنجاح", + + // "person.page.orcid.sync-queue.send.validation-error": "The data that you want to synchronize with ORCID is not valid", "person.page.orcid.sync-queue.send.validation-error": "البيانات التي تريد مزامنتها مع أوركيد غير صالحة", - "person.page.orcid.sync-queue.send.validation-error.amount-currency.required": "العملة الورقية المطلوبة", - "person.page.orcid.sync-queue.send.validation-error.external-id.required": "يلزم المورد إرساله معرفًا جديدًا على الأقل", + + // "person.page.orcid.sync-queue.send.validation-error.amount-currency.required": "The amount's currency is required", + "person.page.orcid.sync-queue.send.validation-error.amount-currency.required": "عملة المبلغ مطلوبة", + + // "person.page.orcid.sync-queue.send.validation-error.external-id.required": "The resource to be sent requires at least one identifier", + "person.page.orcid.sync-queue.send.validation-error.external-id.required": "يتطلب المورد المراد إرساله معرفًا واحدًا على الأقل", + + // "person.page.orcid.sync-queue.send.validation-error.title.required": "The title is required", "person.page.orcid.sync-queue.send.validation-error.title.required": "العنوان مطلوب", + + // "person.page.orcid.sync-queue.send.validation-error.type.required": "The dc.type is required", "person.page.orcid.sync-queue.send.validation-error.type.required": "dc.type مطلوب", - "person.page.orcid.sync-queue.send.validation-error.start-date.required": "تاريخ البدلة مطلوب", + + // "person.page.orcid.sync-queue.send.validation-error.start-date.required": "The start date is required", + "person.page.orcid.sync-queue.send.validation-error.start-date.required": "تاريخ البد مطلوب", + + // "person.page.orcid.sync-queue.send.validation-error.funder.required": "The funder is required", "person.page.orcid.sync-queue.send.validation-error.funder.required": "الممول مطلوب", + + // "person.page.orcid.sync-queue.send.validation-error.country.invalid": "Invalid 2 digits ISO 3166 country", "person.page.orcid.sync-queue.send.validation-error.country.invalid": "كود البلد المكون من رقمين ISO 3166 غير صالح", - "person.page.orcid.sync-queue.send.validation-error.organization.required": "مؤسسة مطلوبة", + + // "person.page.orcid.sync-queue.send.validation-error.organization.required": "The organization is required", + "person.page.orcid.sync-queue.send.validation-error.organization.required": "المؤسسة مطلوبة", + + // "person.page.orcid.sync-queue.send.validation-error.organization.name-required": "The organization's name is required", "person.page.orcid.sync-queue.send.validation-error.organization.name-required": "اسم المؤسسة مطلوب", + + // "person.page.orcid.sync-queue.send.validation-error.publication.date-invalid": "The publication date must be one year after 1900", "person.page.orcid.sync-queue.send.validation-error.publication.date-invalid": "يجب أن يكون تاريخ النشر بعد سنة واحدة من عام 1900", - "person.page.orcid.sync-queue.send.validation-error.organization.address-required": "الطلبات التي تقوم المؤسسة بإرسالها عنواناً", - "person.page.orcid.sync-queue.send.validation-error.organization.city-required": "مطلوب عنوان المؤسسة المراد نقلها لمدينة", - "person.page.orcid.sync-queue.send.validation-error.organization.country-required": "يلزم عنوان المؤسسة المراد إرسالها رقمين صالحين وفقًا لمعايير ISO 3166", - "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.required": "مطلوب معرف لتوضيح المنظمة. ", - "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.value-required": "المتطلبات المعرفية للهيئة", - "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "المتطلبات المعرفية المؤسسة مصدراً", - "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "مصدر أحد المؤسسات المعرفية غير الصالحة. ", - "person.page.orcid.synchronization-mode": "وضع النوارس", + + // "person.page.orcid.sync-queue.send.validation-error.organization.address-required": "The organization to be sent requires an address", + "person.page.orcid.sync-queue.send.validation-error.organization.address-required": "تتطلب المؤسسة التي سيتم إرسالها عنواناً", + + // "person.page.orcid.sync-queue.send.validation-error.organization.city-required": "The address of the organization to be sent requires a city", + "person.page.orcid.sync-queue.send.validation-error.organization.city-required": "يتطلب عنوان المؤسسة المراد إرسالها مدينة", + + // "person.page.orcid.sync-queue.send.validation-error.organization.country-required": "The address of the organization to be sent requires a valid 2 digits ISO 3166 country", + "person.page.orcid.sync-queue.send.validation-error.organization.country-required": "يتطلب عنوان المؤسسة المراد إرسالها رقمين صالحين وفقًا لمعايير ISO 3166", + + // "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.required": "An identifier to disambiguate organizations is required. Supported ids are GRID, Ringgold, Legal Entity identifiers (LEIs) and Crossref Funder Registry identifiers", + "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.required": "مطلوب معرف لتوضيح المؤسسات. المعرفات المدعومة هي GRID وRinggold ومعرفات الكينونات القانونية (LEIs) ومعرفات سجل Crossref Funder", + + // "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.value-required": "The organization's identifiers requires a value", + "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.value-required": "تتطلب معرفات المؤسسة قيمة", + + // "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "The organization's identifiers requires a source", + "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "تتطلب معرفات المؤسسة مصدراً", + + // "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "The source of one of the organization identifiers is invalid. Supported sources are RINGGOLD, GRID, LEI and FUNDREF", + "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "مصدر أحد معرفات المؤسسة غير صالح. المصادر المدعومة هي RINGGOLD وGRID وLEI وFUNDREF", + + // "person.page.orcid.synchronization-mode": "Synchronization mode", + "person.page.orcid.synchronization-mode": "وضع المزامنة", + + // "person.page.orcid.synchronization-mode.batch": "Batch", "person.page.orcid.synchronization-mode.batch": "دفعة", - "person.page.orcid.synchronization-mode.label": "وضع النوارس", - "person.page.orcid.synchronization-mode-message": "يرجى تحديد الطريقة التي تريد أن تتم من خلالها تشغيل النت مع أوركيد. ", - "person.page.orcid.synchronization-mode-funding-message": "حدد ما إذا كنت ترغب في استكمال الدراسة في كينونات المشروع، ثم قم بإدراج المعلومات الخاصة بالتمويل الخاص بشركة أوركيد الخاصة بك.", - "person.page.orcid.synchronization-mode-publication-message": "حدد ما إذا كنت ترغب في ترك كينونات ترغب في قائمة أعمال تسجيل أوركيد الخاصة بك.", - "person.page.orcid.synchronization-mode-profile-message": "حدد ما إذا كنت تريد إرسال بياناتك الشخصية أو معرفاتك الشخصية إلى تسجيل أوركيد الخاص بك.", - "person.page.orcid.synchronization-settings-update.success": "تم تحديث إعدادات الروبوت الفعالة", - "person.page.orcid.synchronization-settings-update.error": "فشل تحديث إعدادات الناقلات", - "person.page.orcid.synchronization-mode.manual": "يدويا", + + // "person.page.orcid.synchronization-mode.label": "Synchronization mode", + "person.page.orcid.synchronization-mode.label": "وضع المزامنة", + + // "person.page.orcid.synchronization-mode-message": "Please select how you would like synchronization to ORCID to occur. The options include \"Manual\" (you must send your data to ORCID manually), or \"Batch\" (the system will send your data to ORCID via a scheduled script).", + "person.page.orcid.synchronization-mode-message": "يرجى تحديد الطريقة التي تريد أن تتم بها المزامنة مع أوركيد. تتضمن الخيارات \"يدوي\" (يجب عليك إرسال بياناتك إلى أوركيد يدوياً)، أو \"بالدفعة\" (سيقوم النظام بإرسال بياناتك إلى أوركيد عبر برنامج نصي مجدول).", + + // "person.page.orcid.synchronization-mode-funding-message": "Select whether to send your linked Project entities to your ORCID record's list of funding information.", + "person.page.orcid.synchronization-mode-funding-message": "حدد ما إذا كنت تريد إرسال كينونات المشروع المرتبطة إلى قائمة معلومات التمويل الخاصة بتسجيلة أوركيد الخاصة بك.", + + // "person.page.orcid.synchronization-mode-publication-message": "Select whether to send your linked Publication entities to your ORCID record's list of works.", + "person.page.orcid.synchronization-mode-publication-message": "حدد ما إذا كنت تريد إرسال كينونات النشر المرتبطة إلى قائمة أعمال تسجيلة أوركيد الخاصة بك.", + + // "person.page.orcid.synchronization-mode-profile-message": "Select whether to send your biographical data or personal identifiers to your ORCID record.", + "person.page.orcid.synchronization-mode-profile-message": "حدد ما إذا كنت تريد إرسال بياناتات الشخصية أو معرفاتك الشخصية إلى تسجيلة أوركيد الخاصة بك.", + + // "person.page.orcid.synchronization-settings-update.success": "The synchronization settings have been updated successfully", + "person.page.orcid.synchronization-settings-update.success": "تم تحديث إعدادات المزامنة بنجاح", + + // "person.page.orcid.synchronization-settings-update.error": "The update of the synchronization settings failed", + "person.page.orcid.synchronization-settings-update.error": "فشل تحديث إعدادات المزامنة", + + // "person.page.orcid.synchronization-mode.manual": "Manual", + "person.page.orcid.synchronization-mode.manual": "يدوي", + + // "person.page.orcid.scope.authenticate": "Get your ORCID iD", "person.page.orcid.scope.authenticate": "احصل على معرف أوركيد الخاص بك", + + // "person.page.orcid.scope.read-limited": "Read your information with visibility set to Trusted Parties", "person.page.orcid.scope.read-limited": "اقرأ معلوماتك مع ضبط مستوى الرؤية للأطراف الموثوقة", - "person.page.orcid.scope.activities-update": "إضافة/تحديث الدراسات الخاصة بك", + + // "person.page.orcid.scope.activities-update": "Add/update your research activities", + "person.page.orcid.scope.activities-update": "إضافة/تحديث الأنشطة البحثية الخاصة بك", + + // "person.page.orcid.scope.person-update": "Add/update other information about you", "person.page.orcid.scope.person-update": "إضافة/تحديث معلومات أخرى عنك", - "person.page.orcid.unlink.success": "تم قطع الاتصال بين الملف الشخصي وأوركيد فعال", - "person.page.orcid.unlink.error": "حدث خطأ أثناء قطع الاتصال بين الملف الشخصي وأوركيد. ", - "person.orcid.sync.setting": "إعدادات نوبات أوركيد", + + // "person.page.orcid.unlink.success": "The disconnection between the profile and the ORCID registry was successful", + "person.page.orcid.unlink.success": "تم قطع الاتصال بين الملف الشخصي وسجل أوركيد بنجاح", + + // "person.page.orcid.unlink.error": "An error occurred while disconnecting between the profile and the ORCID registry. Try again", + "person.page.orcid.unlink.error": "حدث خطأ أثناء قطع الاتصال بين الملف الشخصي وسجل أوركيد. يرجى إعادة المحاولة", + + // "person.orcid.sync.setting": "ORCID Synchronization settings", + "person.orcid.sync.setting": "إعدادات مزامنة أوركيد", + + // "person.orcid.registry.queue": "ORCID Registry Queue", "person.orcid.registry.queue": "قائمة انتظار سجل أوركيد", + + // "person.orcid.registry.auth": "ORCID Authorizations", "person.orcid.registry.auth": "تصاريح أوركيد", - "home.recent-submissions.head": "أحدث العروض", - "listable-notification-object.default-message": "تعذر على تجديد هذا", - "system-wide-alert-banner.retrieval.error": "حدث خطأ أثناء حذف التنبيه على النظام", + + // "home.recent-submissions.head": "Recent Submissions", + "home.recent-submissions.head": "أحدث التقديمات", + + // "listable-notification-object.default-message": "This object couldn't be retrieved", + "listable-notification-object.default-message": "تعذر استرداد هذا الكائن", + + // "system-wide-alert-banner.retrieval.error": "Something went wrong retrieving the system-wide alert banner", + "system-wide-alert-banner.retrieval.error": "حدث خطأ أثناء استرداد شعار التنبيه على مستوى النظام", + + // "system-wide-alert-banner.countdown.prefix": "In", "system-wide-alert-banner.countdown.prefix": "خلال", - "system-wide-alert-banner.countdown.days": "{{days}} يوما,", + + // "system-wide-alert-banner.countdown.days": "{{days}} day(s),", + "system-wide-alert-banner.countdown.days": "{{days}} يوماً,", + + // "system-wide-alert-banner.countdown.hours": "{{hours}} hour(s) and", "system-wide-alert-banner.countdown.hours": "{{hours}} ساعة و", + + // "system-wide-alert-banner.countdown.minutes": "{{minutes}} minute(s):", "system-wide-alert-banner.countdown.minutes": "{{minutes}} دقيقة:", + + // "menu.section.system-wide-alert": "System-wide Alert", "menu.section.system-wide-alert": "تنبيه على مستوى النظام", + + // "system-wide-alert.form.header": "System-wide Alert", "system-wide-alert.form.header": "تنبيه على مستوى النظام", - "system-wide-alert-form.retrieval.error": "حدث ما خطأ أثناء تحديث التنبيه على النظام", + + // "system-wide-alert-form.retrieval.error": "Something went wrong retrieving the system-wide alert", + "system-wide-alert-form.retrieval.error": "حدث خطأ ما أثناء استرداد التنبيه على مستوى النظام", + + // "system-wide-alert.form.cancel": "Cancel", "system-wide-alert.form.cancel": "إلغاء", + + // "system-wide-alert.form.save": "Save", "system-wide-alert.form.save": "حفظ", + + // "system-wide-alert.form.label.active": "ACTIVE", "system-wide-alert.form.label.active": "نشط", + + // "system-wide-alert.form.label.inactive": "INACTIVE", "system-wide-alert.form.label.inactive": "غير نشط", - "system-wide-alert.form.error.message": "يجب أن يحتوي على تنبيه على النظام على رسالة", + + // "system-wide-alert.form.error.message": "The system wide alert must have a message", + "system-wide-alert.form.error.message": "يجب أن يحتوي التنبيه على مستوى النظام على رسالة", + + // "system-wide-alert.form.label.message": "Alert message", "system-wide-alert.form.label.message": "رسالة تنبيه", - "system-wide-alert.form.label.countdownTo.enable": "تفعيل تقويم التاريخ", - "system-wide-alert.form.label.countdownTo.hint": "تلميح: قم بضبط توقيت تقويم التقويم. ", + + // "system-wide-alert.form.label.countdownTo.enable": "Enable a countdown timer", + "system-wide-alert.form.label.countdownTo.enable": "تفعيل مؤقت العد التنازلي", + + // "system-wide-alert.form.label.countdownTo.hint": "Hint: Set a countdown timer. When enabled, a date can be set in the future and the system-wide alert banner will perform a countdown to the set date. When this timer ends, it will disappear from the alert. The server will NOT be automatically stopped.", + "system-wide-alert.form.label.countdownTo.hint": "تلميح: قم بضبط مؤقت العد التنازلي. عند التفعيل، يمكن تعيين تاريخ في المستقبل وسيقوم شعار التنبيه على مستوى النظام بإجراء العد التنازلي للتاريخ المحدد. عندما ينتهي هذا المؤقت، سوف يختفي من التنبيه. لن يتم إيقاف الخادم تلقائياً.", + + // "system-wide-alert-form.select-date-by-calendar": "Select date using calendar", "system-wide-alert-form.select-date-by-calendar": "حدد التاريخ باستخدام التقويم", - "system-wide-alert.form.label.preview": "معاينة التنبيه على النظام", - "system-wide-alert.form.update.success": "تم تحديث التنبيه على النظام الفعال", - "system-wide-alert.form.update.error": "حدث خطأ ما أثناء تحديث التنبيه على النظام", - "system-wide-alert.form.create.success": "تم إنشاء تنبيه على النظام الفعال", - "system-wide-alert.form.create.error": "حدث خطأ ما أثناء إنشاء تنبيه على النظام", + + // "system-wide-alert.form.label.preview": "System-wide alert preview", + "system-wide-alert.form.label.preview": "معاينة التنبيه على مستوى النظام", + + // "system-wide-alert.form.update.success": "The system-wide alert was successfully updated", + "system-wide-alert.form.update.success": "تم تحديث التنبيه على مستوى النظام بنجاح", + + // "system-wide-alert.form.update.error": "Something went wrong when updating the system-wide alert", + "system-wide-alert.form.update.error": "حدث خطأ ما أثناء تحديث التنبيه على مستوى النظام", + + // "system-wide-alert.form.create.success": "The system-wide alert was successfully created", + "system-wide-alert.form.create.success": "تم إنشاء التنبيه على مستوى النظام بنجاح", + + // "system-wide-alert.form.create.error": "Something went wrong when creating the system-wide alert", + "system-wide-alert.form.create.error": "حدث خطأ ما أثناء إنشاء التنبيه على مستوى النظام", + + // "admin.system-wide-alert.breadcrumbs": "System-wide Alerts", "admin.system-wide-alert.breadcrumbs": "تنبيهات على مستوى النظام", + + // "admin.system-wide-alert.title": "System-wide Alerts", "admin.system-wide-alert.title": "تنبيهات على مستوى النظام", - "discover.filters.head": "يكتشف", - "item-access-control-title": "يتيح لك هذا النموذج عمل التغيرات في شروط الوصول إلى مادة ميتا أو تدفقات محددة خاصة بها.", - "collection-access-control-title": "يتيح لك هذا النموذج إجراء التغيرات في شروط الوصول لكل المواد المملوكة لهذه المجموعة. ", - "community-access-control-title": "يتيح لك هذا النموذج إجراء التغيرات في شروط الوصول لكل المواد المملوكة للمجموعة ضمن هذا المجتمع. ", - "access-control-item-header-toggle": "مادة ميتاداتا", - "access-control-item-toggle.enable": "تفعيل خيار عمل الخيارات على ميتاداتا المادة", - "access-control-item-toggle.disable": "السؤال الآن هو: القدرة على إحداث تغييرات على مادة ميتابادتا", + + // "discover.filters.head": "Discover", + // TODO New key - Add a translation + "discover.filters.head": "Discover", + + // "item-access-control-title": "This form allows you to perform changes to the access conditions of the item's metadata or its bitstreams.", + "item-access-control-title": "يتيح لك هذا النموذج إجراء تغييرات على شروط الوصول إلى ميتاداتا المادة أو تدفقات البت الخاصة بها.", + + // "collection-access-control-title": "This form allows you to perform changes to the access conditions of all the items owned by this collection. Changes may be performed to either all Item metadata or all content (bitstreams).", + "collection-access-control-title": "يتيح لك هذا النموذج إجراء تغييرات على شروط الوصول لكل المواد المملوكة لهذه المجموعة. قد يتم إجراء التغييرات إما على كل ميتاداتا المادة أو على المحتوى بأكمله (تدفقات البت).", + + // "community-access-control-title": "This form allows you to perform changes to the access conditions of all the items owned by any collection under this community. Changes may be performed to either all Item metadata or all content (bitstreams).", + "community-access-control-title": "يتيح لك هذا النموذج إجراء تغييرات على شروط الوصول لكل المواد المملوكة لأي مجموعة ضمن هذا المجتمع. قد يتم إجراء التغييرات إما على كل ميتاداتا المادة أو على المحتوى بأكمله (تدفقات البت).", + + // "access-control-item-header-toggle": "Item's Metadata", + "access-control-item-header-toggle": "ميتاداتا المادة", + + // "access-control-item-toggle.enable": "Enable option to perform changes on the item's metadata", + "access-control-item-toggle.enable": "تفعيل خيار إجراء تغييرات على ميتاداتا المادة", + + // "access-control-item-toggle.disable": "Disable option to perform changes on the item's metadata", + "access-control-item-toggle.disable": "تعطيل خيار إجراء تغييرات على ميتاداتا المادة", + + // "access-control-bitstream-header-toggle": "Bitstreams", "access-control-bitstream-header-toggle": "تدفقات البت", - "access-control-bitstream-toggle.enable": "تفعيل خيار خيارات على تدفقات البت", - "access-control-bitstream-toggle.disable": "مطلوب خيار إجراء تغييرات على تدفقات البت", - "access-control-mode": "وضع", + + // "access-control-bitstream-toggle.enable": "Enable option to perform changes on the bitstreams", + "access-control-bitstream-toggle.enable": "تفعيل خيار إجراء تغييرات على تدفقات البت", + + // "access-control-bitstream-toggle.disable": "Disable option to perform changes on the bitstreams", + "access-control-bitstream-toggle.disable": "تعطيل خيار إجراء تغييرات على تدفقات البت", + + // "access-control-mode": "Mode", + "access-control-mode": "Mode", + + // "access-control-access-conditions": "Access conditions", "access-control-access-conditions": "شروط الوصول", - "access-control-no-access-conditions-warning-message": "في الوقت الحالي، لم يتم تحديد أي شروط الوصول أدناه. ", + + // "access-control-no-access-conditions-warning-message": "Currently, no access conditions are specified below. If executed, this will replace the current access conditions with the default access conditions inherited from the owning collection.", + "access-control-no-access-conditions-warning-message": "في الوقت الراهن، لم يتم تحديد أي شروط وصول أدناه. عند التنفيذ، سيتم استبدال شروط الوصول الحالية بشروط الوصول الافتراضية الموروثة من المجموعة المالكة.", + + // "access-control-replace-all": "Replace access conditions", "access-control-replace-all": "استبدل شروط الوصول", + + // "access-control-add-to-existing": "Add to existing ones", "access-control-add-to-existing": "إضافة إلى الموجود", - "access-control-limit-to-specific": "قصر التغييرات على تدفقات بتجميلة", - "access-control-process-all-bitstreams": "تحديد كل التدفقات الواضحة في المادة", + + // "access-control-limit-to-specific": "Limit the changes to specific bitstreams", + "access-control-limit-to-specific": "قصر التغييرات على تدفقات بت معينة", + + // "access-control-process-all-bitstreams": "Update all the bitstreams in the item", + "access-control-process-all-bitstreams": "تحديد كل تدفقات البت في المادة", + + // "access-control-bitstreams-selected": "bitstreams selected", "access-control-bitstreams-selected": "تم تحديد تدفقات البت", + + // "access-control-bitstreams-select": "Select bitstreams", "access-control-bitstreams-select": "حدد تدفقات البت", + + // "access-control-cancel": "Cancel", "access-control-cancel": "إلغاء", + + // "access-control-execute": "Execute", "access-control-execute": "تنفيذ", + + // "access-control-add-more": "Add more", "access-control-add-more": "إضافة المزيد", + + // "access-control-remove": "Remove access condition", "access-control-remove": "إزالة شرط الوصول", + + // "access-control-select-bitstreams-modal.title": "Select bitstreams", "access-control-select-bitstreams-modal.title": "حدد تدفقات البت", - "access-control-select-bitstreams-modal.no-items": "لا يوجد شيء.", + + // "access-control-select-bitstreams-modal.no-items": "No items to show.", + "access-control-select-bitstreams-modal.no-items": "لا توجد مواد.", + + // "access-control-select-bitstreams-modal.close": "Close", "access-control-select-bitstreams-modal.close": "إلغاء", + + // "access-control-option-label": "Access condition type", "access-control-option-label": "نوع شرط الوصول", - "access-control-option-note": "اختر شرط وصول لتطبيقه على المواد المحددة.", - "access-control-option-start-date": "أمنح من الوصول", - "access-control-option-start-date-note": "قم بتسجيل التاريخ الذي يبدأ منه تطبيق شرط ذي الوصول ذي الصلة", - "access-control-option-end-date": "أمنح حتى الوصول", - "access-control-option-end-date-note": "يجب البدء بالتاريخ الذي سيتم تطبيق شرط الوصول ذي الصلة حتى أوله", + + // "access-control-option-note": "Choose an access condition to apply to selected objects.", + "access-control-option-note": "اختر شرط وصول لتطبيقه على الكائنات المحددة.", + + // "access-control-option-start-date": "Grant access from", + "access-control-option-start-date": "منح الوصول من", + + // "access-control-option-start-date-note": "Select the date from which the related access condition is applied", + "access-control-option-start-date-note": "قم بتحديد التاريخ الذي يبدأ منه تطبيق شرط الوصول ذي الصلة", + + // "access-control-option-end-date": "Grant access until", + "access-control-option-end-date": "منح الوصول حتى", + + // "access-control-option-end-date-note": "Select the date until which the related access condition is applied", + "access-control-option-end-date-note": "قم بتحديد التاريخ الذي سيتم تطبيق شرط الوصول ذي الصلة حتى بلوغه", + + // "vocabulary-treeview.search.form.add": "Add", "vocabulary-treeview.search.form.add": "إضافة", - "admin.notifications.publicationclaim.breadcrumbs": "لكي بالنشر", - "admin.notifications.publicationclaim.page.title": "لكي بالنشر", - "filter.search.operator.placeholder": "لها", - "search.filters.filter.entityType.text": "نوع الفرن", - "search.filters.operator.equals.text": "يساوي", - "search.filters.operator.notequals.text": "لا يساوي", - "search.filters.operator.notcontains.text": "لا يحتوي على", - "search.filters.operator.contains.text": "يحتوي على", - "search.filters.filter.title.text": "عنوان العنوان", - "search.filters.applied.f.title": "عنوان العنوان", - "search.filters.filter.author.text": "المؤلف", - "coar-notify-support.title": "COAR التمهيدي", - "coar-notify-support-title.content": "هنا، نحن ندعم بشكل كامل بروتوكول COAR Notify، المصمم لتعزيز الاتصال بين المستودعات. موقع إخطار COAR.", - "coar-notify-support.ldn-inbox.title": "صندوق LDN بريد", - "coar-notify-support.ldn-inbox.content": "من أجل راحتك، يمكن الوصول بسهولة إلى صندوق الوارد الخاص بـ LDN (إشعارات البيانات المرتبطة) على {ldnInboxUrl}. ", - "coar-notify-support.message-moderation.title": "الإشراف على الرسالة", - "coar-notify-support.message-moderation.content": "ولتوفير بيئة آمنة ومنتجة، يتم مراقبة جميع الرسائل. ", - "coar-notify-support.message-moderation.feedback-form": " دفتر نموذج.", - "service.overview.delete.header": "حذف الخدمة", - "ldn-registered-services.title": "الخدمات المميزة", - "ldn-registered-services.table.name": "الاسم", - "ldn-registered-services.table.description": "الوصف", - "ldn-registered-services.table.status": "الحالة", - "ldn-registered-services.table.action": "فعل", - "ldn-registered-services.new": "جديد", - "ldn-registered-services.new.breadcrumbs": "الخدمات المميزة", - "ldn-service.overview.table.enabled": "ممكن", - "ldn-service.overview.table.disabled": "ه", - "ldn-service.overview.table.clickToEnable": "انقر للتمكين", - "ldn-service.overview.table.clickToDisable": "انقر للتعطيل", - "ldn-edit-registered-service.title": "تحرير الخدمة", - "ldn-create-service.title": "إنشاء الخدمة", - "service.overview.create.modal": "إنشاء الخدمة", - "service.overview.create.body": "الرجاء التأكيد على إنشاء هذه الخدمة.", - "ldn-service-status": "الحالة", - "service.confirm.create": "إنشاء", - "service.refuse.create": "إلغاء", - "ldn-register-new-service.title": "تسجيل خدمة جديدة", - "ldn-new-service.form.label.submit": "حفظ", - "ldn-new-service.form.label.name": "اسم", - "ldn-new-service.form.label.description": "الوصف", - "ldn-new-service.form.label.url": "عنوان URL للخدمة", - "ldn-new-service.form.label.ip-range": "لخدمة نطاق IP", - "ldn-new-service.form.label.score": "مستوى الثقة", - "ldn-new-service.form.label.ldnUrl": "عنوان URL لصندوق بريد LDN", - "ldn-new-service.form.placeholder.name": "يرجى تقديم اسم الخدمة", - "ldn-new-service.form.placeholder.description": "يرجى تقديم وصف بخصوص خدمتك", - "ldn-new-service.form.placeholder.url": "يرجى إدخال عنوان URL للمستخدمين للتحقق من مزيد من المعلومات حول الخدمة", - "ldn-new-service.form.placeholder.lowerIp": "نطاق IPv4 الحد الأدنى", - "ldn-new-service.form.placeholder.upperIp": "نطاق IPv4 الحد الأعلى", - "ldn-new-service.form.placeholder.ldnUrl": "يرجى تحديد عنوان URL لصندوق LDN الوارد", - "ldn-new-service.form.placeholder.score": "الرجاء إدخال قيمة بين 0 و1. استخدم \".\" ", - "ldn-service.form.label.placeholder.default-select": "حدد نمطًا", - "ldn-service.form.pattern.ack-accept.label": "الاعتراف والقبول", - "ldn-service.form.pattern.ack-accept.description": "يستخدم هذا النمط للإقرار بالطلب (العرض) وقبوله. ", - "ldn-service.form.pattern.ack-accept.category": "شكر وتقدير", - "ldn-service.form.pattern.ack-reject.label": "الاعتراف والرفض", - "ldn-service.form.pattern.ack-reject.description": "يستخدم هذا النمط للإقرار بالطلب (العرض) ورفضه. ", - "ldn-service.form.pattern.ack-reject.category": "شكر وتقدير", - "ldn-service.form.pattern.ack-tentative-accept.label": "الإقرار والقبول مبدئيا", - "ldn-service.form.pattern.ack-tentative-accept.description": "يُستخدم هذا النمط للإقرار بالطلب (العرض) وقبوله مبدئيًا. ", - "ldn-service.form.pattern.ack-tentative-accept.category": "شكر وتقدير", - "ldn-service.form.pattern.ack-tentative-reject.label": "الاعتراف والرفض مبدئيا", - "ldn-service.form.pattern.ack-tentative-reject.description": "يُستخدم هذا النمط للإقرار بالطلب (العرض) ورفضه مبدئيًا. ", - "ldn-service.form.pattern.ack-tentative-reject.category": "شكر وتقدير", - "ldn-service.form.pattern.announce-endorsement.label": "إعلان المصادقة", - "ldn-service.form.pattern.announce-endorsement.description": "يُستخدم هذا النمط للإعلان عن وجود تأييد، مع الإشارة إلى المورد المعتمد.", - "ldn-service.form.pattern.announce-endorsement.category": "الإعلانات", - "ldn-service.form.pattern.announce-ingest.label": "أعلن عن استيعاب", - "ldn-service.form.pattern.announce-ingest.description": "يُستخدم هذا النمط للإعلان عن استيعاب أحد الموارد.", - "ldn-service.form.pattern.announce-ingest.category": "الإعلانات", - "ldn-service.form.pattern.announce-relationship.label": "أعلن عن العلاقة", - "ldn-service.form.pattern.announce-relationship.description": "يُستخدم هذا النمط للإعلان عن وجود علاقة بين مصدرين.", - "ldn-service.form.pattern.announce-relationship.category": "الإعلانات", - "ldn-service.form.pattern.announce-review.label": "الإعلان عن المراجعة", - "ldn-service.form.pattern.announce-review.description": "يُستخدم هذا النمط للإعلان عن وجود مراجعة، مع الإشارة إلى المورد الذي تمت مراجعته.", - "ldn-service.form.pattern.announce-review.category": "الإعلانات", - "ldn-service.form.pattern.announce-service-result.label": "الإعلان عن نتيجة الخدمة", - "ldn-service.form.pattern.announce-service-result.description": "يُستخدم هذا النمط للإعلان عن وجود \"نتيجة خدمة\"، مع الإشارة إلى المورد ذي الصلة.", - "ldn-service.form.pattern.announce-service-result.category": "الإعلانات", - "ldn-service.form.pattern.request-endorsement.label": "طلب المصادقة", - "ldn-service.form.pattern.request-endorsement.description": "يُستخدم هذا النمط لطلب المصادقة على مورد مملوك للنظام الأصلي.", - "ldn-service.form.pattern.request-endorsement.category": "الطلبات", - "ldn-service.form.pattern.request-ingest.label": "طلب استيعاب", - "ldn-service.form.pattern.request-ingest.description": "يُستخدم هذا النمط لمطالبة النظام المستهدف باستيعاب أحد الموارد.", - "ldn-service.form.pattern.request-ingest.category": "الطلبات", - "ldn-service.form.pattern.request-review.label": "طلب مراجعة", - "ldn-service.form.pattern.request-review.description": "يُستخدم هذا النمط لطلب مراجعة أحد الموارد المملوكة للنظام الأصلي.", - "ldn-service.form.pattern.request-review.category": "الطلبات", - "ldn-service.form.pattern.undo-offer.label": "التراجع عن العرض", - "ldn-service.form.pattern.undo-offer.description": "يُستخدم هذا النمط للتراجع عن (سحب) عرض تم تقديمه مسبقًا.", - "ldn-service.form.pattern.undo-offer.category": "الغاء التحميل", - "ldn-new-service.form.label.placeholder.selectedItemFilter": "لم يتم تحديد أي عنصر تصفية", - "ldn-new-service.form.label.ItemFilter": "عامل تصفية العنصر", - "ldn-new-service.form.label.automatic": "تلقائي", - "ldn-new-service.form.error.name": "مطلوب اسم", - "ldn-new-service.form.error.url": "عنوان URL مطلوب", - "ldn-new-service.form.error.ipRange": "الرجاء إدخال نطاق IP صالح", - "ldn-new-service.form.hint.ipRange": "الرجاء إدخال IPV4 صالح في كلا النطاقين (ملاحظة: بالنسبة لعنوان IP واحد، يرجى إدخال نفس القيمة في كلا الحقلين)", - "ldn-new-service.form.error.ldnurl": "عنوان URL لـ LDN مطلوب", - "ldn-new-service.form.error.patterns": "مطلوب نمط على الأقل", - "ldn-new-service.form.error.score": "الرجاء إدخال نتيجة صحيحة (بين 0 و1). ", - "ldn-new-service.form.label.inboundPattern": "النمط الوارد", - "ldn-new-service.form.label.addPattern": "+ أضف المزيد", - "ldn-new-service.form.label.removeItemFilter": "يزيل", - "ldn-register-new-service.breadcrumbs": "خدمة جديدة", - "service.overview.delete.body": "هل أنت متأكد أنك تريد حذف هذه الخدمة؟", - "service.overview.edit.body": "هل تؤكد التغييرات؟", - "service.overview.edit.modal": "تحرير الخدمة", - "service.detail.update": "يتأكد", - "service.detail.return": "يلغي", - "service.overview.reset-form.body": "هل أنت متأكد أنك تريد تجاهل التغييرات والمغادرة؟", - "service.overview.reset-form.modal": "تجاهل التغييرات", - "service.overview.reset-form.reset-confirm": "ينبذ", - "admin.registries.services-formats.modify.success.head": "تحرير ناجح", - "admin.registries.services-formats.modify.success.content": "تم تعديل الخدمة", - "admin.registries.services-formats.modify.failure.head": "فشل التحرير", - "admin.registries.services-formats.modify.failure.content": "لم يتم تحرير الخدمة", - "ldn-service-notification.created.success.title": "إنشاء ناجح", - "ldn-service-notification.created.success.body": "تم إنشاء الخدمة", - "ldn-service-notification.created.failure.title": "فشل الإنشاء", - "ldn-service-notification.created.failure.body": "لم يتم إنشاء الخدمة", - "ldn-service-notification.created.warning.title": "الرجاء تحديد نمط وارد واحد على الأقل", - "ldn-enable-service.notification.success.title": "تم تحديث الحالة بنجاح", - "ldn-enable-service.notification.success.content": "تم تحديث حالة الخدمة", - "ldn-service-delete.notification.success.title": "تم الحذف بنجاح", - "ldn-service-delete.notification.success.content": "تم حذف الخدمة", - "ldn-service-delete.notification.error.title": "فشل الحذف", - "ldn-service-delete.notification.error.content": "لم يتم حذف الخدمة", - "service.overview.reset-form.reset-return": "يلغي", - "service.overview.delete": "حذف الخدمة", - "ldn-edit-service.title": "تحرير الخدمة", - "ldn-edit-service.form.label.name": "اسم", - "ldn-edit-service.form.label.description": "وصف", - "ldn-edit-service.form.label.url": "عنوان URL للخدمة", - "ldn-edit-service.form.label.ldnUrl": "عنوان URL لصندوق بريد LDN", - "ldn-edit-service.form.label.inboundPattern": "النمط الوارد", - "ldn-edit-service.form.label.noInboundPatternSelected": "لا يوجد نمط وارد", - "ldn-edit-service.form.label.selectedItemFilter": "عامل تصفية العنصر المحدد", - "ldn-edit-service.form.label.selectItemFilter": "لا يوجد عامل تصفية للعناصر", - "ldn-edit-service.form.label.automatic": "تلقائي", - "ldn-edit-service.form.label.addInboundPattern": "+ أضف المزيد", - "ldn-edit-service.form.label.submit": "يحفظ", - "ldn-edit-service.breadcrumbs": "تحرير الخدمة", - "ldn-service.control-constaint-select-none": "لا تختر شيء", - "ldn-register-new-service.notification.error.title": "خطأ", - "ldn-register-new-service.notification.error.content": "حدث خطأ أثناء إنشاء هذه العملية", - "ldn-register-new-service.notification.success.title": "نجاح", - "ldn-register-new-service.notification.success.content": "تم إنشاء العملية بنجاح", - "submission.sections.notify.info": "الخدمة المحددة متوافقة مع العنصر وفقًا لحالته الحالية. {{ service.name }}: {{ service.description }}", - "item.page.endorsement": "تَأيِيد", - "item.page.review": "مراجعة", - "item.page.dataset": "مجموعة البيانات", - "menu.section.icon.ldn_services": "نظرة عامة على خدمات LDN", - "menu.section.services": "خدمات LDN", - "menu.section.services_new": "خدمة LDN", - "quality-assurance.topics.description-with-target": "أدناه يمكنك رؤية جميع المواضيع الواردة من الاشتراكات في {{source}} فيما يتعلق ب", - "quality-assurance.events.description": "هناك أدناه القائمة التي تحتوي على كافة الاقتراحات للموضوع للبحث.", - "quality-assurance.events.description-with-topic-and-target": "أسفل القائمة التي تحتوي على كافة الاقتراحات للموضوع المحدد {{topic}}، متعلق ب {{source}} و ", - "quality-assurance.event.table.event.message.serviceUrl": "عنوان الخدمة:", - "quality-assurance.event.table.event.message.link": "وصلة:", - "service.detail.delete.cancel": "يلغي", - "service.detail.delete.button": "حذف الخدمة", - "service.detail.delete.header": "حذف الخدمة", - "service.detail.delete.body": "هل أنت متأكد أنك تريد حذف الخدمة الحالية؟", - "service.detail.delete.confirm": "حذف الخدمة", - "service.detail.delete.success": "تم حذف الخدمة بنجاح.", - "service.detail.delete.error": "حدث خطأ ما عند حذف الخدمة", - "service.overview.table.id": "معرف الخدمات", - "service.overview.table.name": "اسم", - "service.overview.table.start": "وقت البدء (التوقيت العالمي المنسق)", - "service.overview.table.status": "حالة", - "service.overview.table.user": "مستخدم", - "service.overview.title": "نظرة عامة للخدمات", - "service.overview.breadcrumbs": "نظرة عامة للخدمات", - "service.overview.table.actions": "أجراءات", - "service.overview.table.description": "وصف", - "submission.sections.submit.progressbar.coarnotify": "إخطار COAR", - "submission.section.section-coar-notify.control.request-review.label": "يمكنك طلب مراجعة لإحدى الخدمات التالية", - "submission.section.section-coar-notify.control.request-endorsement.label": "يمكنك طلب المصادقة على إحدى المجلات المتراكبة التالية", - "submission.section.section-coar-notify.control.request-ingest.label": "يمكنك طلب استيعاب نسخة من طلبك إلى إحدى الخدمات التالية", - "submission.section.section-coar-notify.dropdown.no-data": "لا تتوافر بيانات", - "submission.section.section-coar-notify.dropdown.select-none": "لا تختر شيء", - "submission.section.section-coar-notify.small.notification": "اختر خدمة ل {{ pattern }} من هذا البند", - "submission.section.section-coar-notify.selection.description": "وصف الخدمة المختارة:", - "submission.section.section-coar-notify.selection.no-description": "لا تتوفر المزيد من المعلومات", - "submission.section.section-coar-notify.notification.error": "الخدمة المحددة غير مناسبة للعنصر الحالي. ", - "submission.section.section-coar-notify.info.no-pattern": "لم يتم العثور على أنماط قابلة للتكوين.", - "error.validation.coarnotify.invalidfilter": "عامل التصفية غير صالح، حاول تحديد خدمة أخرى أو لا شيء.", - "request-status-alert-box.accepted": "المطلوب {{ offerType }} ل {{ serviceName }} وقد تم توليه المسؤولية.", - "request-status-alert-box.rejected": "المطلوب {{ offerType }} ل {{ serviceName }} وقد رفض.", - "request-status-alert-box.requested": "المطلوب {{ offerType }} ل {{ serviceName }} معلق.", - "ldn-service-button-mark-inbound-deletion": "وضع علامة على النمط الوارد للحذف", - "ldn-service-button-unmark-inbound-deletion": "قم بإلغاء تحديد النمط الوارد للحذف", - "ldn-service-input-inbound-item-filter-dropdown": "حدد عامل تصفية العنصر للنمط الوارد", - "ldn-service-input-inbound-pattern-dropdown": "حدد النمط الوارد للخدمة", - "ldn-service-overview-select-delete": "اختر الخدمة للحذف", - "ldn-service-overview-select-edit": "تحرير خدمة LDN", - "ldn-service-overview-close-modal": "إغلاق مشروط", - "a-common-or_statement.label": "نوع العنصر هو مقالة يومية أو مجموعة بيانات", - "always_true_filter.label": "دائما صحيح او صادق", - "automatic_processing_collection_filter_16.label": "المعالجة التلقائية", - "dc-identifier-uri-contains-doi_condition.label": "يحتوي URI على DOI", - "doi-filter.label": "مرشح DOI", - "driver-document-type_condition.label": "نوع المستند يساوي السائق", - "has-at-least-one-bitstream_condition.label": "يحتوي على Bitstream واحد على الأقل", - "has-bitstream_filter.label": "لديه تيار البت", - "has-one-bitstream_condition.label": "لديه Bitstream واحد", - "is-archived_condition.label": "تمت أرشفته", - "is-withdrawn_condition.label": "تم سحبه", - "item-is-public_condition.label": "العنصر عام", - "journals_ingest_suggestion_collection_filter_18.label": "استيعاب المجلات", - "title-starts-with-pattern_condition.label": "يبدأ العنوان بالنمط", - "type-equals-dataset_condition.label": "النوع يساوي مجموعة البيانات", - "type-equals-journal-article_condition.label": "النوع يساوي مقالة يومية", - "search.filters.filter.subject.text": "موضوع", - "search.advanced.filters.head": "البحث المتقدم", - "filter.search.text.placeholder": "بحث في النص", - "advancesearch.form.submit": "يضيف", - "ldn.no-filter.label": "لا أحد", - "admin.notify.dashboard": "لوحة القيادة", - "menu.section.notify_dashboard": "لوحة القيادة", - "menu.section.coar_notify": "إخطار COAR", - "admin-notify-dashboard.title": "لوحة الإخطار", - "admin-notify-dashboard.description": "تراقب لوحة معلومات Notify الاستخدام العام لبروتوكول COAR Notify عبر المستودع. ", - "admin-notify-dashboard.metrics": "المقاييس", - "admin-notify-dashboard.received-ldn": "عدد LDN المستلم", - "admin-notify-dashboard.generated-ldn": "عدد LDN الذي تم إنشاؤه", - "admin-notify-dashboard.NOTIFY.incoming.accepted": "قبلت", - "admin-notify-dashboard.NOTIFY.incoming.accepted.description": "الإخطارات الواردة المقبولة", - "admin-notify-logs.NOTIFY.incoming.accepted": "يعرض حاليا: الإخطارات المقبولة", - "admin-notify-dashboard.NOTIFY.incoming.processed": "LDN المعالجة", - "admin-notify-dashboard.NOTIFY.incoming.processed.description": "معالجة الإخطارات الواردة", - "admin-notify-logs.NOTIFY.incoming.processed": "المعروض حاليا: LDN المعالج", - "admin-notify-logs.NOTIFY.incoming.failure": "المعروض حاليًا: الإشعارات الفاشلة", - "admin-notify-dashboard.NOTIFY.incoming.failure": "فشل", - "admin-notify-dashboard.NOTIFY.incoming.failure.description": "فشل الإخطارات الواردة", - "admin-notify-logs.NOTIFY.outgoing.failure": "المعروض حاليًا: الإشعارات الفاشلة", - "admin-notify-dashboard.NOTIFY.outgoing.failure": "فشل", - "admin-notify-dashboard.NOTIFY.outgoing.failure.description": "فشل الإخطارات الصادرة", - "admin-notify-logs.NOTIFY.incoming.untrusted": "المعروض حاليًا: إشعارات غير موثوقة", - "admin-notify-dashboard.NOTIFY.incoming.untrusted": "غير موثوق به", - "admin-notify-dashboard.NOTIFY.incoming.untrusted.description": "الإخطارات الواردة غير موثوق بها", - "admin-notify-logs.NOTIFY.incoming.delivered": "المعروض حاليًا: الإخطارات التي تم تسليمها", - "admin-notify-dashboard.NOTIFY.incoming.delivered.description": "تم تسليم الإشعارات الواردة بنجاح", - "admin-notify-dashboard.NOTIFY.outgoing.delivered": "تم التوصيل", - "admin-notify-logs.NOTIFY.outgoing.delivered": "المعروض حاليًا: الإخطارات التي تم تسليمها", - "admin-notify-dashboard.NOTIFY.outgoing.delivered.description": "تم تسليم الإخطارات الصادرة بنجاح", - "admin-notify-logs.NOTIFY.outgoing.queued": "المعروض حاليًا: الإشعارات في قائمة الانتظار", - "admin-notify-dashboard.NOTIFY.outgoing.queued.description": "الإخطارات في قائمة الانتظار حاليا", - "admin-notify-dashboard.NOTIFY.outgoing.queued": "في قائمة الانتظار", - "admin-notify-logs.NOTIFY.outgoing.queued_for_retry": "يتم العرض حاليًا: في قائمة الانتظار لإعادة محاولة الإشعارات", - "admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry": "في قائمة الانتظار لإعادة المحاولة", - "admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry.description": "الإخطارات في قائمة الانتظار حاليا لإعادة المحاولة", - "admin-notify-dashboard.NOTIFY.incoming.involvedItems": "العناصر المعنية", - "admin-notify-dashboard.NOTIFY.incoming.involvedItems.description": "العناصر المتعلقة بالإخطارات الواردة", - "admin-notify-dashboard.NOTIFY.outgoing.involvedItems": "العناصر المعنية", - "admin-notify-dashboard.NOTIFY.outgoing.involvedItems.description": "العناصر المتعلقة بالإخطارات الصادرة", - "admin.notify.dashboard.breadcrumbs": "لوحة القيادة", - "admin.notify.dashboard.inbound": "الرسائل الواردة", - "admin.notify.dashboard.inbound-logs": "السجلات/الواردة", - "admin.notify.dashboard.filter": "منقي: ", - "search.filters.applied.f.relateditem": "الأصناف المتعلقة", - "search.filters.applied.f.ldn_service": "خدمة LDN", - "search.filters.applied.f.notifyReview": "إخطار المراجعة", - "search.filters.applied.f.notifyEndorsement": "إخطار المصادقة", - "search.filters.applied.f.notifyRelation": "إخطار العلاقة", - "search.filters.filter.queue_last_start_time.head": "آخر وقت للمعالجة ", - "search.filters.filter.queue_last_start_time.min.label": "نطاق الحد الأدنى", - "search.filters.filter.queue_last_start_time.max.label": "أقصى مدى", - "search.filters.applied.f.queue_last_start_time.min": "نطاق الحد الأدنى", - "search.filters.applied.f.queue_last_start_time.max": "أقصى مدى", - "admin.notify.dashboard.outbound": "الرسائل الصادرة", - "admin.notify.dashboard.outbound-logs": "السجلات/الصادرة", - "NOTIFY.incoming.search.results.head": "وارد", - "search.filters.filter.relateditem.head": "البند ذو الصلة", - "search.filters.filter.origin.head": "أصل", - "search.filters.filter.ldn_service.head": "خدمة LDN", - "search.filters.filter.target.head": "هدف", - "search.filters.filter.queue_status.head": "حالة قائمة الانتظار", - "search.filters.filter.activity_stream_type.head": "نوع تيار النشاط", - "search.filters.filter.coar_notify_type.head": "نوع الإخطار COAR", - "search.filters.filter.notification_type.head": "نوع إعلام", - "search.filters.filter.relateditem.label": "البحث عن العناصر ذات الصلة", - "search.filters.filter.queue_status.label": "حالة قائمة انتظار البحث", - "search.filters.filter.target.label": "هدف البحث", - "search.filters.filter.activity_stream_type.label": "نوع دفق نشاط البحث", - "search.filters.applied.f.queue_status": "حالة قائمة الانتظار", - "search.filters.queue_status.0,authority": "IP غير موثوق به", - "search.filters.queue_status.1,authority": "في قائمة الانتظار", - "search.filters.queue_status.2,authority": "يعالج", - "search.filters.queue_status.3,authority": "تمت معالجتها", - "search.filters.queue_status.4,authority": "فشل", - "search.filters.queue_status.5,authority": "غير موثوق به", - "search.filters.queue_status.6,authority": "عمل غير محدد", - "search.filters.queue_status.7,authority": "في قائمة الانتظار لإعادة المحاولة", - "search.filters.applied.f.activity_stream_type": "نوع تيار النشاط", - "search.filters.applied.f.coar_notify_type": "نوع الإخطار COAR", - "search.filters.applied.f.notification_type": "نوع إعلام", - "search.filters.filter.coar_notify_type.label": "بحث COAR نوع الإخطار", - "search.filters.filter.notification_type.label": "بحث نوع الإخطار", - "search.filters.filter.relateditem.placeholder": "الأصناف المتعلقة", - "search.filters.filter.target.placeholder": "هدف", - "search.filters.filter.origin.label": "مصدر البحث", - "search.filters.filter.origin.placeholder": "مصدر", - "search.filters.filter.ldn_service.label": "ابحث في خدمة LDN", - "search.filters.filter.ldn_service.placeholder": "خدمة LDN", - "search.filters.filter.queue_status.placeholder": "حالة قائمة الانتظار", - "search.filters.filter.activity_stream_type.placeholder": "نوع تيار النشاط", - "search.filters.filter.coar_notify_type.placeholder": "نوع الإخطار COAR", - "search.filters.filter.notification_type.placeholder": "إشعار", - "search.filters.filter.notifyRelation.head": "إخطار العلاقة", - "search.filters.filter.notifyRelation.label": "بحث إخطار العلاقة", - "search.filters.filter.notifyRelation.placeholder": "إخطار العلاقة", - "search.filters.filter.notifyReview.head": "إخطار المراجعة", - "search.filters.filter.notifyReview.label": "بحث إخطار المراجعة", - "search.filters.filter.notifyReview.placeholder": "إخطار المراجعة", - "search.filters.coar_notify_type.coar-notify:ReviewAction": "إجراء المراجعة", - "search.filters.coar_notify_type.coar-notify:ReviewAction,authority": "إجراء المراجعة", - "notify-detail-modal.coar-notify:ReviewAction": "إجراء المراجعة", - "search.filters.coar_notify_type.coar-notify:EndorsementAction": "إجراء الإقرار", - "search.filters.coar_notify_type.coar-notify:EndorsementAction,authority": "إجراء الإقرار", - "notify-detail-modal.coar-notify:EndorsementAction": "إجراء الإقرار", - "search.filters.coar_notify_type.coar-notify:IngestAction": "استيعاب العمل", - "search.filters.coar_notify_type.coar-notify:IngestAction,authority": "استيعاب العمل", - "notify-detail-modal.coar-notify:IngestAction": "استيعاب العمل", - "search.filters.coar_notify_type.coar-notify:RelationshipAction": "عمل العلاقة", - "search.filters.coar_notify_type.coar-notify:RelationshipAction,authority": "عمل العلاقة", - "notify-detail-modal.coar-notify:RelationshipAction": "عمل العلاقة", - "search.filters.queue_status.QUEUE_STATUS_QUEUED": "في قائمة الانتظار", - "notify-detail-modal.QUEUE_STATUS_QUEUED": "في قائمة الانتظار", - "search.filters.queue_status.QUEUE_STATUS_QUEUED_FOR_RETRY": "في قائمة الانتظار لإعادة المحاولة", - "notify-detail-modal.QUEUE_STATUS_QUEUED_FOR_RETRY": "في قائمة الانتظار لإعادة المحاولة", - "search.filters.queue_status.QUEUE_STATUS_PROCESSING": "يعالج", - "notify-detail-modal.QUEUE_STATUS_PROCESSING": "يعالج", - "search.filters.queue_status.QUEUE_STATUS_PROCESSED": "تمت معالجتها", - "notify-detail-modal.QUEUE_STATUS_PROCESSED": "تمت معالجتها", - "search.filters.queue_status.QUEUE_STATUS_FAILED": "فشل", - "notify-detail-modal.QUEUE_STATUS_FAILED": "فشل", - "search.filters.queue_status.QUEUE_STATUS_UNTRUSTED": "غير موثوق به", - "search.filters.queue_status.QUEUE_STATUS_UNTRUSTED_IP": "IP غير موثوق به", - "notify-detail-modal.QUEUE_STATUS_UNTRUSTED": "غير موثوق به", - "notify-detail-modal.QUEUE_STATUS_UNTRUSTED_IP": "IP غير موثوق به", - "search.filters.queue_status.QUEUE_STATUS_UNMAPPED_ACTION": "عمل غير محدد", - "notify-detail-modal.QUEUE_STATUS_UNMAPPED_ACTION": "عمل غير محدد", - "sorting.queue_last_start_time.DESC": "آخر قائمة انتظار بدأت تنازليًا", - "sorting.queue_last_start_time.ASC": "آخر قائمة انتظار بدأت تصاعديًا", - "sorting.queue_attempts.DESC": "حاولت قائمة الانتظار التنازلي", - "sorting.queue_attempts.ASC": "حاولت قائمة الانتظار التصاعدي", - "NOTIFY.incoming.involvedItems.search.results.head": "العناصر المشاركة في LDN الوارد", - "NOTIFY.outgoing.involvedItems.search.results.head": "العناصر المشاركة في LDN الصادرة", - "type.notify-detail-modal": "يكتب", - "id.notify-detail-modal": "بطاقة تعريف", - "coarNotifyType.notify-detail-modal": "نوع الإخطار COAR", - "activityStreamType.notify-detail-modal": "نوع تيار النشاط", - "inReplyTo.notify-detail-modal": "ردا على", - "object.notify-detail-modal": "عنصر المستودع", - "context.notify-detail-modal": "عنصر المستودع", - "queueAttempts.notify-detail-modal": "محاولات قائمة الانتظار", - "queueLastStartTime.notify-detail-modal": "بدأت قائمة الانتظار آخر مرة", - "origin.notify-detail-modal": "خدمة LDN", - "target.notify-detail-modal": "خدمة LDN", - "queueStatusLabel.notify-detail-modal": "حالة قائمة الانتظار", - "queueTimeout.notify-detail-modal": "مهلة قائمة الانتظار", - "notify-message-modal.title": "تفاصيل الرسالة", - "notify-message-modal.show-message": "اظهر الرسالة", - "notify-message-result.timestamp": "الطابع الزمني", - "notify-message-result.repositoryItem": "عنصر المستودع", - "notify-message-result.ldnService": "خدمة LDN", - "notify-message-result.type": "يكتب", - "notify-message-result.status": "حالة", - "notify-message-result.action": "فعل", - "notify-message-result.detail": "التفاصيل", - "notify-message-result.reprocess": "إعادة المعالجة", - "notify-queue-status.processed": "تمت معالجتها", - "notify-queue-status.failed": "فشل", - "notify-queue-status.queue_retry": "في قائمة الانتظار لإعادة المحاولة", - "notify-queue-status.unmapped_action": "عمل غير معين", - "notify-queue-status.processing": "يعالج", - "notify-queue-status.queued": "في قائمة الانتظار", - "notify-queue-status.untrusted": "غير موثوق به", - "ldnService.notify-detail-modal": "خدمة LDN", - "relatedItem.notify-detail-modal": "البند ذو الصلة", - "search.filters.filter.notifyEndorsement.head": "إخطار المصادقة", - "search.filters.filter.notifyEndorsement.placeholder": "إخطار المصادقة", - "search.filters.filter.notifyEndorsement.label": "بحث الإخطار بالمصادقة", + + // "admin.notifications.publicationclaim.breadcrumbs": "Publication Claim", + // TODO New key - Add a translation + "admin.notifications.publicationclaim.breadcrumbs": "Publication Claim", + + // "admin.notifications.publicationclaim.page.title": "Publication Claim", + // TODO New key - Add a translation + "admin.notifications.publicationclaim.page.title": "Publication Claim", + + // "filter.search.operator.placeholder": "Operator", + // TODO New key - Add a translation + "filter.search.operator.placeholder": "Operator", + + // "search.filters.filter.entityType.text": "Item Type", + // TODO New key - Add a translation + "search.filters.filter.entityType.text": "Item Type", + + // "search.filters.operator.equals.text": "Equals", + // TODO New key - Add a translation + "search.filters.operator.equals.text": "Equals", + + // "search.filters.operator.notequals.text": "Not Equals", + // TODO New key - Add a translation + "search.filters.operator.notequals.text": "Not Equals", + + // "search.filters.operator.notcontains.text": "Not Contains", + // TODO New key - Add a translation + "search.filters.operator.notcontains.text": "Not Contains", + + // "search.filters.operator.contains.text": "Contains", + // TODO New key - Add a translation + "search.filters.operator.contains.text": "Contains", + + // "search.filters.filter.title.text": "Title", + // TODO New key - Add a translation + "search.filters.filter.title.text": "Title", + + // "search.filters.applied.f.title": "Title", + // TODO New key - Add a translation + "search.filters.applied.f.title": "Title", + + // "search.filters.filter.author.text": "Author", + // TODO New key - Add a translation + "search.filters.filter.author.text": "Author", + + // "coar-notify-support.title": "COAR Notify Protocol", + // TODO New key - Add a translation + "coar-notify-support.title": "COAR Notify Protocol", + + // "coar-notify-support-title.content": "Here, we fully support the COAR Notify protocol, which is designed to enhance the communication between repositories. To learn more about the COAR Notify protocol, visit the COAR Notify website.", + // TODO New key - Add a translation + "coar-notify-support-title.content": "Here, we fully support the COAR Notify protocol, which is designed to enhance the communication between repositories. To learn more about the COAR Notify protocol, visit the COAR Notify website.", + + // "coar-notify-support.ldn-inbox.title": "LDN InBox", + // TODO New key - Add a translation + "coar-notify-support.ldn-inbox.title": "LDN InBox", + + // "coar-notify-support.ldn-inbox.content": "For your convenience, our LDN (Linked Data Notifications) InBox is easily accessible at {ldnInboxUrl}. The LDN InBox enables seamless communication and data exchange, ensuring efficient and effective collaboration.", + // TODO New key - Add a translation + "coar-notify-support.ldn-inbox.content": "For your convenience, our LDN (Linked Data Notifications) InBox is easily accessible at {ldnInboxUrl}. The LDN InBox enables seamless communication and data exchange, ensuring efficient and effective collaboration.", + + // "coar-notify-support.message-moderation.title": "Message Moderation", + // TODO New key - Add a translation + "coar-notify-support.message-moderation.title": "Message Moderation", + + // "coar-notify-support.message-moderation.content": "To ensure a secure and productive environment, all incoming LDN messages are moderated. If you are planning to exchange information with us, kindly reach out via our dedicated", + // TODO New key - Add a translation + "coar-notify-support.message-moderation.content": "To ensure a secure and productive environment, all incoming LDN messages are moderated. If you are planning to exchange information with us, kindly reach out via our dedicated", + + // "coar-notify-support.message-moderation.feedback-form": " Feedback form.", + // TODO New key - Add a translation + "coar-notify-support.message-moderation.feedback-form": " Feedback form.", + + // "service.overview.delete.header": "Delete Service", + // TODO New key - Add a translation + "service.overview.delete.header": "Delete Service", + + // "ldn-registered-services.title": "Registered Services", + // TODO New key - Add a translation + "ldn-registered-services.title": "Registered Services", + // "ldn-registered-services.table.name": "Name", + // TODO New key - Add a translation + "ldn-registered-services.table.name": "Name", + // "ldn-registered-services.table.description": "Description", + // TODO New key - Add a translation + "ldn-registered-services.table.description": "Description", + // "ldn-registered-services.table.status": "Status", + // TODO New key - Add a translation + "ldn-registered-services.table.status": "Status", + // "ldn-registered-services.table.action": "Action", + // TODO New key - Add a translation + "ldn-registered-services.table.action": "Action", + // "ldn-registered-services.new": "NEW", + // TODO New key - Add a translation + "ldn-registered-services.new": "NEW", + // "ldn-registered-services.new.breadcrumbs": "Registered Services", + // TODO New key - Add a translation + "ldn-registered-services.new.breadcrumbs": "Registered Services", + + // "ldn-service.overview.table.enabled": "Enabled", + // TODO New key - Add a translation + "ldn-service.overview.table.enabled": "Enabled", + // "ldn-service.overview.table.disabled": "Disabled", + // TODO New key - Add a translation + "ldn-service.overview.table.disabled": "Disabled", + // "ldn-service.overview.table.clickToEnable": "Click to enable", + // TODO New key - Add a translation + "ldn-service.overview.table.clickToEnable": "Click to enable", + // "ldn-service.overview.table.clickToDisable": "Click to disable", + // TODO New key - Add a translation + "ldn-service.overview.table.clickToDisable": "Click to disable", + + // "ldn-edit-registered-service.title": "Edit Service", + // TODO New key - Add a translation + "ldn-edit-registered-service.title": "Edit Service", + // "ldn-create-service.title": "Create service", + // TODO New key - Add a translation + "ldn-create-service.title": "Create service", + // "service.overview.create.modal": "Create Service", + // TODO New key - Add a translation + "service.overview.create.modal": "Create Service", + // "service.overview.create.body": "Please confirm the creation of this service.", + // TODO New key - Add a translation + "service.overview.create.body": "Please confirm the creation of this service.", + // "ldn-service-status": "Status", + // TODO New key - Add a translation + "ldn-service-status": "Status", + // "service.confirm.create": "Create", + // TODO New key - Add a translation + "service.confirm.create": "Create", + // "service.refuse.create": "Cancel", + // TODO New key - Add a translation + "service.refuse.create": "Cancel", + // "ldn-register-new-service.title": "Register a new service", + // TODO New key - Add a translation + "ldn-register-new-service.title": "Register a new service", + // "ldn-new-service.form.label.submit": "Save", + // TODO New key - Add a translation + "ldn-new-service.form.label.submit": "Save", + // "ldn-new-service.form.label.name": "Name", + // TODO New key - Add a translation + "ldn-new-service.form.label.name": "Name", + // "ldn-new-service.form.label.description": "Description", + // TODO New key - Add a translation + "ldn-new-service.form.label.description": "Description", + // "ldn-new-service.form.label.url": "Service URL", + // TODO New key - Add a translation + "ldn-new-service.form.label.url": "Service URL", + // "ldn-new-service.form.label.ip-range": "Service IP range", + // TODO New key - Add a translation + "ldn-new-service.form.label.ip-range": "Service IP range", + // "ldn-new-service.form.label.score": "Level of trust", + // TODO New key - Add a translation + "ldn-new-service.form.label.score": "Level of trust", + // "ldn-new-service.form.label.ldnUrl": "LDN Inbox URL", + // TODO New key - Add a translation + "ldn-new-service.form.label.ldnUrl": "LDN Inbox URL", + // "ldn-new-service.form.placeholder.name": "Please provide service name", + // TODO New key - Add a translation + "ldn-new-service.form.placeholder.name": "Please provide service name", + // "ldn-new-service.form.placeholder.description": "Please provide a description regarding your service", + // TODO New key - Add a translation + "ldn-new-service.form.placeholder.description": "Please provide a description regarding your service", + // "ldn-new-service.form.placeholder.url": "Please input the URL for users to check out more information about the service", + // TODO New key - Add a translation + "ldn-new-service.form.placeholder.url": "Please input the URL for users to check out more information about the service", + // "ldn-new-service.form.placeholder.lowerIp": "IPv4 range lower bound", + // TODO New key - Add a translation + "ldn-new-service.form.placeholder.lowerIp": "IPv4 range lower bound", + // "ldn-new-service.form.placeholder.upperIp": "IPv4 range upper bound", + // TODO New key - Add a translation + "ldn-new-service.form.placeholder.upperIp": "IPv4 range upper bound", + // "ldn-new-service.form.placeholder.ldnUrl": "Please specify the URL of the LDN Inbox", + // TODO New key - Add a translation + "ldn-new-service.form.placeholder.ldnUrl": "Please specify the URL of the LDN Inbox", + // "ldn-new-service.form.placeholder.score": "Please enter a value between 0 and 1. Use the “.” as decimal separator", + // TODO New key - Add a translation + "ldn-new-service.form.placeholder.score": "Please enter a value between 0 and 1. Use the “.” as decimal separator", + // "ldn-service.form.label.placeholder.default-select": "Select a pattern", + // TODO New key - Add a translation + "ldn-service.form.label.placeholder.default-select": "Select a pattern", + + // "ldn-service.form.pattern.ack-accept.label": "Acknowledge and Accept", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-accept.label": "Acknowledge and Accept", + // "ldn-service.form.pattern.ack-accept.description": "This pattern is used to acknowledge and accept a request (offer). It implies an intention to act on the request.", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-accept.description": "This pattern is used to acknowledge and accept a request (offer). It implies an intention to act on the request.", + // "ldn-service.form.pattern.ack-accept.category": "Acknowledgements", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-accept.category": "Acknowledgements", + + // "ldn-service.form.pattern.ack-reject.label": "Acknowledge and Reject", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-reject.label": "Acknowledge and Reject", + // "ldn-service.form.pattern.ack-reject.description": "This pattern is used to acknowledge and reject a request (offer). It signifies no further action regarding the request.", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-reject.description": "This pattern is used to acknowledge and reject a request (offer). It signifies no further action regarding the request.", + // "ldn-service.form.pattern.ack-reject.category": "Acknowledgements", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-reject.category": "Acknowledgements", + + // "ldn-service.form.pattern.ack-tentative-accept.label": "Acknowledge and Tentatively Accept", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-tentative-accept.label": "Acknowledge and Tentatively Accept", + // "ldn-service.form.pattern.ack-tentative-accept.description": "This pattern is used to acknowledge and tentatively accept a request (offer). It implies an intention to act, which may change.", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-tentative-accept.description": "This pattern is used to acknowledge and tentatively accept a request (offer). It implies an intention to act, which may change.", + // "ldn-service.form.pattern.ack-tentative-accept.category": "Acknowledgements", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-tentative-accept.category": "Acknowledgements", + + // "ldn-service.form.pattern.ack-tentative-reject.label": "Acknowledge and Tentatively Reject", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-tentative-reject.label": "Acknowledge and Tentatively Reject", + // "ldn-service.form.pattern.ack-tentative-reject.description": "This pattern is used to acknowledge and tentatively reject a request (offer). It signifies no further action, subject to change.", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-tentative-reject.description": "This pattern is used to acknowledge and tentatively reject a request (offer). It signifies no further action, subject to change.", + // "ldn-service.form.pattern.ack-tentative-reject.category": "Acknowledgements", + // TODO New key - Add a translation + "ldn-service.form.pattern.ack-tentative-reject.category": "Acknowledgements", + + // "ldn-service.form.pattern.announce-endorsement.label": "Announce Endorsement", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-endorsement.label": "Announce Endorsement", + // "ldn-service.form.pattern.announce-endorsement.description": "This pattern is used to announce the existence of an endorsement, referencing the endorsed resource.", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-endorsement.description": "This pattern is used to announce the existence of an endorsement, referencing the endorsed resource.", + // "ldn-service.form.pattern.announce-endorsement.category": "Announcements", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-endorsement.category": "Announcements", + + // "ldn-service.form.pattern.announce-ingest.label": "Announce Ingest", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-ingest.label": "Announce Ingest", + // "ldn-service.form.pattern.announce-ingest.description": "This pattern is used to announce that a resource has been ingested.", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-ingest.description": "This pattern is used to announce that a resource has been ingested.", + // "ldn-service.form.pattern.announce-ingest.category": "Announcements", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-ingest.category": "Announcements", + + // "ldn-service.form.pattern.announce-relationship.label": "Announce Relationship", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-relationship.label": "Announce Relationship", + // "ldn-service.form.pattern.announce-relationship.description": "This pattern is used to announce a relationship between two resources.", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-relationship.description": "This pattern is used to announce a relationship between two resources.", + // "ldn-service.form.pattern.announce-relationship.category": "Announcements", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-relationship.category": "Announcements", + + // "ldn-service.form.pattern.announce-review.label": "Announce Review", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-review.label": "Announce Review", + // "ldn-service.form.pattern.announce-review.description": "This pattern is used to announce the existence of a review, referencing the reviewed resource.", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-review.description": "This pattern is used to announce the existence of a review, referencing the reviewed resource.", + // "ldn-service.form.pattern.announce-review.category": "Announcements", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-review.category": "Announcements", + + // "ldn-service.form.pattern.announce-service-result.label": "Announce Service Result", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-service-result.label": "Announce Service Result", + // "ldn-service.form.pattern.announce-service-result.description": "This pattern is used to announce the existence of a 'service result', referencing the relevant resource.", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-service-result.description": "This pattern is used to announce the existence of a 'service result', referencing the relevant resource.", + // "ldn-service.form.pattern.announce-service-result.category": "Announcements", + // TODO New key - Add a translation + "ldn-service.form.pattern.announce-service-result.category": "Announcements", + + // "ldn-service.form.pattern.request-endorsement.label": "Request Endorsement", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-endorsement.label": "Request Endorsement", + // "ldn-service.form.pattern.request-endorsement.description": "This pattern is used to request endorsement of a resource owned by the origin system.", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-endorsement.description": "This pattern is used to request endorsement of a resource owned by the origin system.", + // "ldn-service.form.pattern.request-endorsement.category": "Requests", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-endorsement.category": "Requests", + + // "ldn-service.form.pattern.request-ingest.label": "Request Ingest", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-ingest.label": "Request Ingest", + // "ldn-service.form.pattern.request-ingest.description": "This pattern is used to request that the target system ingest a resource.", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-ingest.description": "This pattern is used to request that the target system ingest a resource.", + // "ldn-service.form.pattern.request-ingest.category": "Requests", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-ingest.category": "Requests", + + // "ldn-service.form.pattern.request-review.label": "Request Review", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-review.label": "Request Review", + // "ldn-service.form.pattern.request-review.description": "This pattern is used to request a review of a resource owned by the origin system.", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-review.description": "This pattern is used to request a review of a resource owned by the origin system.", + // "ldn-service.form.pattern.request-review.category": "Requests", + // TODO New key - Add a translation + "ldn-service.form.pattern.request-review.category": "Requests", + + // "ldn-service.form.pattern.undo-offer.label": "Undo Offer", + // TODO New key - Add a translation + "ldn-service.form.pattern.undo-offer.label": "Undo Offer", + // "ldn-service.form.pattern.undo-offer.description": "This pattern is used to undo (retract) an offer previously made.", + // TODO New key - Add a translation + "ldn-service.form.pattern.undo-offer.description": "This pattern is used to undo (retract) an offer previously made.", + // "ldn-service.form.pattern.undo-offer.category": "Undo", + // TODO New key - Add a translation + "ldn-service.form.pattern.undo-offer.category": "Undo", + + // "ldn-new-service.form.label.placeholder.selectedItemFilter": "No Item Filter Selected", + // TODO New key - Add a translation + "ldn-new-service.form.label.placeholder.selectedItemFilter": "No Item Filter Selected", + // "ldn-new-service.form.label.ItemFilter": "Item Filter", + // TODO New key - Add a translation + "ldn-new-service.form.label.ItemFilter": "Item Filter", + // "ldn-new-service.form.label.automatic": "Automatic", + // TODO New key - Add a translation + "ldn-new-service.form.label.automatic": "Automatic", + // "ldn-new-service.form.error.name": "Name is required", + // TODO New key - Add a translation + "ldn-new-service.form.error.name": "Name is required", + // "ldn-new-service.form.error.url": "URL is required", + // TODO New key - Add a translation + "ldn-new-service.form.error.url": "URL is required", + // "ldn-new-service.form.error.ipRange": "Please enter a valid IP range", + // TODO New key - Add a translation + "ldn-new-service.form.error.ipRange": "Please enter a valid IP range", + // "ldn-new-service.form.hint.ipRange": "Please enter a valid IpV4 in both range bounds (note: for single IP, please enter the same value in both fields)", + // TODO New key - Add a translation + "ldn-new-service.form.hint.ipRange": "Please enter a valid IpV4 in both range bounds (note: for single IP, please enter the same value in both fields)", + // "ldn-new-service.form.error.ldnurl": "LDN URL is required", + // TODO New key - Add a translation + "ldn-new-service.form.error.ldnurl": "LDN URL is required", + // "ldn-new-service.form.error.patterns": "At least a pattern is required", + // TODO New key - Add a translation + "ldn-new-service.form.error.patterns": "At least a pattern is required", + // "ldn-new-service.form.error.score": "Please enter a valid score (between 0 and 1). Use the “.” as decimal separator", + // TODO New key - Add a translation + "ldn-new-service.form.error.score": "Please enter a valid score (between 0 and 1). Use the “.” as decimal separator", + + // "ldn-new-service.form.label.inboundPattern": "Inbound Pattern", + // TODO New key - Add a translation + "ldn-new-service.form.label.inboundPattern": "Inbound Pattern", + // "ldn-new-service.form.label.addPattern": "+ Add more", + // TODO New key - Add a translation + "ldn-new-service.form.label.addPattern": "+ Add more", + // "ldn-new-service.form.label.removeItemFilter": "Remove", + // TODO New key - Add a translation + "ldn-new-service.form.label.removeItemFilter": "Remove", + // "ldn-register-new-service.breadcrumbs": "New Service", + // TODO New key - Add a translation + "ldn-register-new-service.breadcrumbs": "New Service", + // "service.overview.delete.body": "Are you sure you want to delete this service?", + // TODO New key - Add a translation + "service.overview.delete.body": "Are you sure you want to delete this service?", + // "service.overview.edit.body": "Do you confirm the changes?", + // TODO New key - Add a translation + "service.overview.edit.body": "Do you confirm the changes?", + // "service.overview.edit.modal": "Edit Service", + // TODO New key - Add a translation + "service.overview.edit.modal": "Edit Service", + // "service.detail.update": "Confirm", + // TODO New key - Add a translation + "service.detail.update": "Confirm", + // "service.detail.return": "Cancel", + // TODO New key - Add a translation + "service.detail.return": "Cancel", + // "service.overview.reset-form.body": "Are you sure you want to discard the changes and leave?", + // TODO New key - Add a translation + "service.overview.reset-form.body": "Are you sure you want to discard the changes and leave?", + // "service.overview.reset-form.modal": "Discard Changes", + // TODO New key - Add a translation + "service.overview.reset-form.modal": "Discard Changes", + // "service.overview.reset-form.reset-confirm": "Discard", + // TODO New key - Add a translation + "service.overview.reset-form.reset-confirm": "Discard", + // "admin.registries.services-formats.modify.success.head": "Successful Edit", + // TODO New key - Add a translation + "admin.registries.services-formats.modify.success.head": "Successful Edit", + // "admin.registries.services-formats.modify.success.content": "The service has been edited", + // TODO New key - Add a translation + "admin.registries.services-formats.modify.success.content": "The service has been edited", + // "admin.registries.services-formats.modify.failure.head": "Failed Edit", + // TODO New key - Add a translation + "admin.registries.services-formats.modify.failure.head": "Failed Edit", + // "admin.registries.services-formats.modify.failure.content": "The service has not been edited", + // TODO New key - Add a translation + "admin.registries.services-formats.modify.failure.content": "The service has not been edited", + // "ldn-service-notification.created.success.title": "Successful Create", + // TODO New key - Add a translation + "ldn-service-notification.created.success.title": "Successful Create", + // "ldn-service-notification.created.success.body": "The service has been created", + // TODO New key - Add a translation + "ldn-service-notification.created.success.body": "The service has been created", + // "ldn-service-notification.created.failure.title": "Failed Create", + // TODO New key - Add a translation + "ldn-service-notification.created.failure.title": "Failed Create", + // "ldn-service-notification.created.failure.body": "The service has not been created", + // TODO New key - Add a translation + "ldn-service-notification.created.failure.body": "The service has not been created", + // "ldn-service-notification.created.warning.title": "Please select at least one Inbound Pattern", + // TODO New key - Add a translation + "ldn-service-notification.created.warning.title": "Please select at least one Inbound Pattern", + // "ldn-enable-service.notification.success.title": "Successful status updated", + // TODO New key - Add a translation + "ldn-enable-service.notification.success.title": "Successful status updated", + // "ldn-enable-service.notification.success.content": "The service status has been updated", + // TODO New key - Add a translation + "ldn-enable-service.notification.success.content": "The service status has been updated", + // "ldn-service-delete.notification.success.title": "Successful Deletion", + // TODO New key - Add a translation + "ldn-service-delete.notification.success.title": "Successful Deletion", + // "ldn-service-delete.notification.success.content": "The service has been deleted", + // TODO New key - Add a translation + "ldn-service-delete.notification.success.content": "The service has been deleted", + // "ldn-service-delete.notification.error.title": "Failed Deletion", + // TODO New key - Add a translation + "ldn-service-delete.notification.error.title": "Failed Deletion", + // "ldn-service-delete.notification.error.content": "The service has not been deleted", + // TODO New key - Add a translation + "ldn-service-delete.notification.error.content": "The service has not been deleted", + // "service.overview.reset-form.reset-return": "Cancel", + // TODO New key - Add a translation + "service.overview.reset-form.reset-return": "Cancel", + // "service.overview.delete": "Delete service", + // TODO New key - Add a translation + "service.overview.delete": "Delete service", + // "ldn-edit-service.title": "Edit service", + // TODO New key - Add a translation + "ldn-edit-service.title": "Edit service", + // "ldn-edit-service.form.label.name": "Name", + // TODO New key - Add a translation + "ldn-edit-service.form.label.name": "Name", + // "ldn-edit-service.form.label.description": "Description", + // TODO New key - Add a translation + "ldn-edit-service.form.label.description": "Description", + // "ldn-edit-service.form.label.url": "Service URL", + // TODO New key - Add a translation + "ldn-edit-service.form.label.url": "Service URL", + // "ldn-edit-service.form.label.ldnUrl": "LDN Inbox URL", + // TODO New key - Add a translation + "ldn-edit-service.form.label.ldnUrl": "LDN Inbox URL", + // "ldn-edit-service.form.label.inboundPattern": "Inbound Pattern", + // TODO New key - Add a translation + "ldn-edit-service.form.label.inboundPattern": "Inbound Pattern", + // "ldn-edit-service.form.label.noInboundPatternSelected": "No Inbound Pattern", + // TODO New key - Add a translation + "ldn-edit-service.form.label.noInboundPatternSelected": "No Inbound Pattern", + // "ldn-edit-service.form.label.selectedItemFilter": "Selected Item Filter", + // TODO New key - Add a translation + "ldn-edit-service.form.label.selectedItemFilter": "Selected Item Filter", + // "ldn-edit-service.form.label.selectItemFilter": "No Item Filter", + // TODO New key - Add a translation + "ldn-edit-service.form.label.selectItemFilter": "No Item Filter", + // "ldn-edit-service.form.label.automatic": "Automatic", + // TODO New key - Add a translation + "ldn-edit-service.form.label.automatic": "Automatic", + // "ldn-edit-service.form.label.addInboundPattern": "+ Add more", + // TODO New key - Add a translation + "ldn-edit-service.form.label.addInboundPattern": "+ Add more", + // "ldn-edit-service.form.label.submit": "Save", + // TODO New key - Add a translation + "ldn-edit-service.form.label.submit": "Save", + // "ldn-edit-service.breadcrumbs": "Edit Service", + // TODO New key - Add a translation + "ldn-edit-service.breadcrumbs": "Edit Service", + // "ldn-service.control-constaint-select-none": "Select none", + // TODO New key - Add a translation + "ldn-service.control-constaint-select-none": "Select none", + + // "ldn-register-new-service.notification.error.title": "Error", + // TODO New key - Add a translation + "ldn-register-new-service.notification.error.title": "Error", + // "ldn-register-new-service.notification.error.content": "An error occurred while creating this process", + // TODO New key - Add a translation + "ldn-register-new-service.notification.error.content": "An error occurred while creating this process", + // "ldn-register-new-service.notification.success.title": "Success", + // TODO New key - Add a translation + "ldn-register-new-service.notification.success.title": "Success", + // "ldn-register-new-service.notification.success.content": "The process was successfully created", + // TODO New key - Add a translation + "ldn-register-new-service.notification.success.content": "The process was successfully created", + + // "submission.sections.notify.info": "The selected service is compatible with the item according to its current status. {{ service.name }}: {{ service.description }}", + // TODO New key - Add a translation + "submission.sections.notify.info": "The selected service is compatible with the item according to its current status. {{ service.name }}: {{ service.description }}", + + // "item.page.endorsement": "Endorsement", + // TODO New key - Add a translation + "item.page.endorsement": "Endorsement", + + // "item.page.review": "Review", + // TODO New key - Add a translation + "item.page.review": "Review", + + // "item.page.dataset": "Dataset", + // TODO New key - Add a translation + "item.page.dataset": "Dataset", + // "menu.section.icon.ldn_services": "LDN Services overview", + // TODO New key - Add a translation + "menu.section.icon.ldn_services": "LDN Services overview", + // "menu.section.services": "LDN Services", + // TODO New key - Add a translation + "menu.section.services": "LDN Services", + + // "menu.section.services_new": "LDN Service", + // TODO New key - Add a translation + "menu.section.services_new": "LDN Service", + + // "quality-assurance.topics.description-with-target": "Below you can see all the topics received from the subscriptions to {{source}} in regards to the", + // TODO New key - Add a translation + "quality-assurance.topics.description-with-target": "Below you can see all the topics received from the subscriptions to {{source}} in regards to the", + // "quality-assurance.events.description": "Below the list of all the suggestions for the selected topic {{topic}}, related to {{source}}.", + "quality-assurance.events.description": "توجد أدناه القائمة التي تحتوي على كافة الاقتراحات للموضوع المحدد.", + + // "quality-assurance.events.description-with-topic-and-target": "Below the list of all the suggestions for the selected topic {{topic}}, related to {{source}} and ", + // TODO New key - Add a translation + "quality-assurance.events.description-with-topic-and-target": "Below the list of all the suggestions for the selected topic {{topic}}, related to {{source}} and ", + + // "quality-assurance.event.table.event.message.serviceUrl": "Service URL:", + // TODO New key - Add a translation + "quality-assurance.event.table.event.message.serviceUrl": "Service URL:", + + // "quality-assurance.event.table.event.message.link": "Link:", + // TODO New key - Add a translation + "quality-assurance.event.table.event.message.link": "Link:", + + // "service.detail.delete.cancel": "Cancel", + // TODO New key - Add a translation + "service.detail.delete.cancel": "Cancel", + + // "service.detail.delete.button": "Delete service", + // TODO New key - Add a translation + "service.detail.delete.button": "Delete service", + + // "service.detail.delete.header": "Delete service", + // TODO New key - Add a translation + "service.detail.delete.header": "Delete service", + + // "service.detail.delete.body": "Are you sure you want to delete the current service?", + // TODO New key - Add a translation + "service.detail.delete.body": "Are you sure you want to delete the current service?", + + // "service.detail.delete.confirm": "Delete service", + // TODO New key - Add a translation + "service.detail.delete.confirm": "Delete service", + + // "service.detail.delete.success": "The service was successfully deleted.", + // TODO New key - Add a translation + "service.detail.delete.success": "The service was successfully deleted.", + + // "service.detail.delete.error": "Something went wrong when deleting the service", + // TODO New key - Add a translation + "service.detail.delete.error": "Something went wrong when deleting the service", + + // "service.overview.table.id": "Services ID", + // TODO New key - Add a translation + "service.overview.table.id": "Services ID", + + // "service.overview.table.name": "Name", + // TODO New key - Add a translation + "service.overview.table.name": "Name", + + // "service.overview.table.start": "Start time (UTC)", + // TODO New key - Add a translation + "service.overview.table.start": "Start time (UTC)", + + // "service.overview.table.status": "Status", + // TODO New key - Add a translation + "service.overview.table.status": "Status", + + // "service.overview.table.user": "User", + // TODO New key - Add a translation + "service.overview.table.user": "User", + + // "service.overview.title": "Services Overview", + // TODO New key - Add a translation + "service.overview.title": "Services Overview", + + // "service.overview.breadcrumbs": "Services Overview", + // TODO New key - Add a translation + "service.overview.breadcrumbs": "Services Overview", + + // "service.overview.table.actions": "Actions", + // TODO New key - Add a translation + "service.overview.table.actions": "Actions", + + // "service.overview.table.description": "Description", + // TODO New key - Add a translation + "service.overview.table.description": "Description", + + // "submission.sections.submit.progressbar.coarnotify": "COAR Notify", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.coarnotify": "COAR Notify", + + // "submission.section.section-coar-notify.control.request-review.label": "You can request a review to one of the following services", + // TODO New key - Add a translation + "submission.section.section-coar-notify.control.request-review.label": "You can request a review to one of the following services", + + // "submission.section.section-coar-notify.control.request-endorsement.label": "You can request an Endorsement to one of the following overlay journals", + // TODO New key - Add a translation + "submission.section.section-coar-notify.control.request-endorsement.label": "You can request an Endorsement to one of the following overlay journals", + + // "submission.section.section-coar-notify.control.request-ingest.label": "You can request to ingest a copy of your submission to one of the following services", + // TODO New key - Add a translation + "submission.section.section-coar-notify.control.request-ingest.label": "You can request to ingest a copy of your submission to one of the following services", + + // "submission.section.section-coar-notify.dropdown.no-data": "No data available", + // TODO New key - Add a translation + "submission.section.section-coar-notify.dropdown.no-data": "No data available", + + // "submission.section.section-coar-notify.dropdown.select-none": "Select none", + // TODO New key - Add a translation + "submission.section.section-coar-notify.dropdown.select-none": "Select none", + + // "submission.section.section-coar-notify.small.notification": "Select a service for {{ pattern }} of this item", + // TODO New key - Add a translation + "submission.section.section-coar-notify.small.notification": "Select a service for {{ pattern }} of this item", + + // "submission.section.section-coar-notify.selection.description": "Selected service's description:", + // TODO New key - Add a translation + "submission.section.section-coar-notify.selection.description": "Selected service's description:", + + // "submission.section.section-coar-notify.selection.no-description": "No further information is available", + // TODO New key - Add a translation + "submission.section.section-coar-notify.selection.no-description": "No further information is available", + + // "submission.section.section-coar-notify.notification.error": "The selected service is not suitable for the current item. Please check the description for details about which record can be managed by this service.", + // TODO New key - Add a translation + "submission.section.section-coar-notify.notification.error": "The selected service is not suitable for the current item. Please check the description for details about which record can be managed by this service.", + + // "submission.section.section-coar-notify.info.no-pattern": "No configurable patterns found.", + // TODO New key - Add a translation + "submission.section.section-coar-notify.info.no-pattern": "No configurable patterns found.", + + // "error.validation.coarnotify.invalidfilter": "Invalid filter, try to select another service or none.", + // TODO New key - Add a translation + "error.validation.coarnotify.invalidfilter": "Invalid filter, try to select another service or none.", + + // "request-status-alert-box.accepted": "The requested {{ offerType }} for {{ serviceName }} has been taken in charge.", + // TODO New key - Add a translation + "request-status-alert-box.accepted": "The requested {{ offerType }} for {{ serviceName }} has been taken in charge.", + + // "request-status-alert-box.rejected": "The requested {{ offerType }} for {{ serviceName }} has been rejected.", + // TODO New key - Add a translation + "request-status-alert-box.rejected": "The requested {{ offerType }} for {{ serviceName }} has been rejected.", + + // "request-status-alert-box.requested": "The requested {{ offerType }} for {{ serviceName }} is pending.", + // TODO New key - Add a translation + "request-status-alert-box.requested": "The requested {{ offerType }} for {{ serviceName }} is pending.", + + // "ldn-service-button-mark-inbound-deletion": "Mark inbound pattern for deletion", + // TODO New key - Add a translation + "ldn-service-button-mark-inbound-deletion": "Mark inbound pattern for deletion", + + // "ldn-service-button-unmark-inbound-deletion": "Unmark inbound pattern for deletion", + // TODO New key - Add a translation + "ldn-service-button-unmark-inbound-deletion": "Unmark inbound pattern for deletion", + + // "ldn-service-input-inbound-item-filter-dropdown": "Select Item filter for inbound pattern", + // TODO New key - Add a translation + "ldn-service-input-inbound-item-filter-dropdown": "Select Item filter for inbound pattern", + + // "ldn-service-input-inbound-pattern-dropdown": "Select inbound pattern for service", + // TODO New key - Add a translation + "ldn-service-input-inbound-pattern-dropdown": "Select inbound pattern for service", + + // "ldn-service-overview-select-delete": "Select service for deletion", + // TODO New key - Add a translation + "ldn-service-overview-select-delete": "Select service for deletion", + + // "ldn-service-overview-select-edit": "Edit LDN service", + // TODO New key - Add a translation + "ldn-service-overview-select-edit": "Edit LDN service", + + // "ldn-service-overview-close-modal": "Close modal", + // TODO New key - Add a translation + "ldn-service-overview-close-modal": "Close modal", + + // "a-common-or_statement.label": "Item type is Journal Article or Dataset", + // TODO New key - Add a translation + "a-common-or_statement.label": "Item type is Journal Article or Dataset", + + // "always_true_filter.label": "Always true", + // TODO New key - Add a translation + "always_true_filter.label": "Always true", + + // "automatic_processing_collection_filter_16.label": "Automatic processing", + // TODO New key - Add a translation + "automatic_processing_collection_filter_16.label": "Automatic processing", + + // "dc-identifier-uri-contains-doi_condition.label": "URI contains DOI", + // TODO New key - Add a translation + "dc-identifier-uri-contains-doi_condition.label": "URI contains DOI", + + // "doi-filter.label": "DOI filter", + // TODO New key - Add a translation + "doi-filter.label": "DOI filter", + + // "driver-document-type_condition.label": "Document type equals driver", + // TODO New key - Add a translation + "driver-document-type_condition.label": "Document type equals driver", + + // "has-at-least-one-bitstream_condition.label": "Has at least one Bitstream", + // TODO New key - Add a translation + "has-at-least-one-bitstream_condition.label": "Has at least one Bitstream", + + // "has-bitstream_filter.label": "Has Bitstream", + // TODO New key - Add a translation + "has-bitstream_filter.label": "Has Bitstream", + + // "has-one-bitstream_condition.label": "Has one Bitstream", + // TODO New key - Add a translation + "has-one-bitstream_condition.label": "Has one Bitstream", + + // "is-archived_condition.label": "Is archived", + // TODO New key - Add a translation + "is-archived_condition.label": "Is archived", + + // "is-withdrawn_condition.label": "Is withdrawn", + // TODO New key - Add a translation + "is-withdrawn_condition.label": "Is withdrawn", + + // "item-is-public_condition.label": "Item is public", + // TODO New key - Add a translation + "item-is-public_condition.label": "Item is public", + + // "journals_ingest_suggestion_collection_filter_18.label": "Journals ingest", + // TODO New key - Add a translation + "journals_ingest_suggestion_collection_filter_18.label": "Journals ingest", + + // "title-starts-with-pattern_condition.label": "Title starts with pattern", + // TODO New key - Add a translation + "title-starts-with-pattern_condition.label": "Title starts with pattern", + + // "type-equals-dataset_condition.label": "Type equals Dataset", + // TODO New key - Add a translation + "type-equals-dataset_condition.label": "Type equals Dataset", + + // "type-equals-journal-article_condition.label": "Type equals Journal Article", + // TODO New key - Add a translation + "type-equals-journal-article_condition.label": "Type equals Journal Article", + + // "search.filters.filter.subject.text": "Subject", + // TODO New key - Add a translation + "search.filters.filter.subject.text": "Subject", + + // "search.advanced.filters.head": "Advanced Search", + // TODO New key - Add a translation + "search.advanced.filters.head": "Advanced Search", + + // "filter.search.text.placeholder": "Search text", + // TODO New key - Add a translation + "filter.search.text.placeholder": "Search text", + + // "advancesearch.form.submit": "Add", + // TODO New key - Add a translation + "advancesearch.form.submit": "Add", + + // "ldn.no-filter.label": "None", + // TODO New key - Add a translation + "ldn.no-filter.label": "None", + + // "admin.notify.dashboard": "Dashboard", + // TODO New key - Add a translation + "admin.notify.dashboard": "Dashboard", + + // "menu.section.notify_dashboard": "Dashboard", + // TODO New key - Add a translation + "menu.section.notify_dashboard": "Dashboard", + + // "menu.section.coar_notify": "COAR Notify", + // TODO New key - Add a translation + "menu.section.coar_notify": "COAR Notify", + + // "admin-notify-dashboard.title": "Notify Dashboard", + // TODO New key - Add a translation + "admin-notify-dashboard.title": "Notify Dashboard", + + // "admin-notify-dashboard.description": "The Notify dashboard monitor the general usage of the COAR Notify protocol across the repository. In the “Metrics” tab are statistics about usage of the COAR Notify protocol. In the “Logs/Inbound” and “Logs/Outbound” tabs it’s possible to search and check the individual status of each LDN message, either received or sent.", + // TODO New key - Add a translation + "admin-notify-dashboard.description": "The Notify dashboard monitor the general usage of the COAR Notify protocol across the repository. In the “Metrics” tab are statistics about usage of the COAR Notify protocol. In the “Logs/Inbound” and “Logs/Outbound” tabs it’s possible to search and check the individual status of each LDN message, either received or sent.", + + // "admin-notify-dashboard.metrics": "Metrics", + // TODO New key - Add a translation + "admin-notify-dashboard.metrics": "Metrics", + + // "admin-notify-dashboard.received-ldn": "Number of received LDN", + // TODO New key - Add a translation + "admin-notify-dashboard.received-ldn": "Number of received LDN", + + // "admin-notify-dashboard.generated-ldn": "Number of generated LDN", + // TODO New key - Add a translation + "admin-notify-dashboard.generated-ldn": "Number of generated LDN", + + // "admin-notify-dashboard.NOTIFY.incoming.accepted": "Accepted", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.accepted": "Accepted", + + // "admin-notify-dashboard.NOTIFY.incoming.accepted.description": "Accepted inbound notifications", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.accepted.description": "Accepted inbound notifications", + + // "admin-notify-logs.NOTIFY.incoming.accepted": "Currently displaying: Accepted notifications", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.incoming.accepted": "Currently displaying: Accepted notifications", + + // "admin-notify-dashboard.NOTIFY.incoming.processed": "Processed LDN", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.processed": "Processed LDN", + + // "admin-notify-dashboard.NOTIFY.incoming.processed.description": "Processed inbound notifications", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.processed.description": "Processed inbound notifications", + + // "admin-notify-logs.NOTIFY.incoming.processed": "Currently displaying: Processed LDN", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.incoming.processed": "Currently displaying: Processed LDN", + + // "admin-notify-logs.NOTIFY.incoming.failure": "Currently displaying: Failed notifications", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.incoming.failure": "Currently displaying: Failed notifications", + + // "admin-notify-dashboard.NOTIFY.incoming.failure": "Failure", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.failure": "Failure", + + // "admin-notify-dashboard.NOTIFY.incoming.failure.description": "Failed inbound notifications", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.failure.description": "Failed inbound notifications", + + // "admin-notify-logs.NOTIFY.outgoing.failure": "Currently displaying: Failed notifications", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.outgoing.failure": "Currently displaying: Failed notifications", + + // "admin-notify-dashboard.NOTIFY.outgoing.failure": "Failure", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.failure": "Failure", + + // "admin-notify-dashboard.NOTIFY.outgoing.failure.description": "Failed outbound notifications", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.failure.description": "Failed outbound notifications", + + // "admin-notify-logs.NOTIFY.incoming.untrusted": "Currently displaying: Untrusted notifications", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.incoming.untrusted": "Currently displaying: Untrusted notifications", + + // "admin-notify-dashboard.NOTIFY.incoming.untrusted": "Untrusted", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.untrusted": "Untrusted", + + // "admin-notify-dashboard.NOTIFY.incoming.untrusted.description": "Inbound notifications not trusted", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.untrusted.description": "Inbound notifications not trusted", + + // "admin-notify-logs.NOTIFY.incoming.delivered": "Currently displaying: Delivered notifications", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.incoming.delivered": "Currently displaying: Delivered notifications", + + // "admin-notify-dashboard.NOTIFY.incoming.delivered.description": "Inbound notifications successfully delivered", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.delivered.description": "Inbound notifications successfully delivered", + + // "admin-notify-dashboard.NOTIFY.outgoing.delivered": "Delivered", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.delivered": "Delivered", + + // "admin-notify-logs.NOTIFY.outgoing.delivered": "Currently displaying: Delivered notifications", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.outgoing.delivered": "Currently displaying: Delivered notifications", + + // "admin-notify-dashboard.NOTIFY.outgoing.delivered.description": "Outbound notifications successfully delivered", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.delivered.description": "Outbound notifications successfully delivered", + + // "admin-notify-logs.NOTIFY.outgoing.queued": "Currently displaying: Queued notifications", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.outgoing.queued": "Currently displaying: Queued notifications", + + // "admin-notify-dashboard.NOTIFY.outgoing.queued.description": "Notifications currently queued", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.queued.description": "Notifications currently queued", + + // "admin-notify-dashboard.NOTIFY.outgoing.queued": "Queued", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.queued": "Queued", + + // "admin-notify-logs.NOTIFY.outgoing.queued_for_retry": "Currently displaying: Queued for retry notifications", + // TODO New key - Add a translation + "admin-notify-logs.NOTIFY.outgoing.queued_for_retry": "Currently displaying: Queued for retry notifications", + + // "admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry": "Queued for retry", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry": "Queued for retry", + + // "admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry.description": "Notifications currently queued for retry", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry.description": "Notifications currently queued for retry", + + // "admin-notify-dashboard.NOTIFY.incoming.involvedItems": "Items involved", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.involvedItems": "Items involved", + + // "admin-notify-dashboard.NOTIFY.incoming.involvedItems.description": "Items related to inbound notifications", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.incoming.involvedItems.description": "Items related to inbound notifications", + + // "admin-notify-dashboard.NOTIFY.outgoing.involvedItems": "Items involved", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.involvedItems": "Items involved", + + // "admin-notify-dashboard.NOTIFY.outgoing.involvedItems.description": "Items related to outbound notifications", + // TODO New key - Add a translation + "admin-notify-dashboard.NOTIFY.outgoing.involvedItems.description": "Items related to outbound notifications", + + // "admin.notify.dashboard.breadcrumbs": "Dashboard", + // TODO New key - Add a translation + "admin.notify.dashboard.breadcrumbs": "Dashboard", + + // "admin.notify.dashboard.inbound": "Inbound messages", + // TODO New key - Add a translation + "admin.notify.dashboard.inbound": "Inbound messages", + + // "admin.notify.dashboard.inbound-logs": "Logs/Inbound", + // TODO New key - Add a translation + "admin.notify.dashboard.inbound-logs": "Logs/Inbound", + + // "admin.notify.dashboard.filter": "Filter: ", + // TODO New key - Add a translation + "admin.notify.dashboard.filter": "Filter: ", + + // "search.filters.applied.f.relateditem": "Related items", + // TODO New key - Add a translation + "search.filters.applied.f.relateditem": "Related items", + + // "search.filters.applied.f.ldn_service": "LDN Service", + // TODO New key - Add a translation + "search.filters.applied.f.ldn_service": "LDN Service", + + // "search.filters.applied.f.notifyReview": "Notify Review", + // TODO New key - Add a translation + "search.filters.applied.f.notifyReview": "Notify Review", + + // "search.filters.applied.f.notifyEndorsement": "Notify Endorsement", + // TODO New key - Add a translation + "search.filters.applied.f.notifyEndorsement": "Notify Endorsement", + + // "search.filters.applied.f.notifyRelation": "Notify Relation", + // TODO New key - Add a translation + "search.filters.applied.f.notifyRelation": "Notify Relation", + + // "search.filters.filter.queue_last_start_time.head": "Last processing time ", + // TODO New key - Add a translation + "search.filters.filter.queue_last_start_time.head": "Last processing time ", + + // "search.filters.filter.queue_last_start_time.min.label": "Min range", + // TODO New key - Add a translation + "search.filters.filter.queue_last_start_time.min.label": "Min range", + + // "search.filters.filter.queue_last_start_time.max.label": "Max range", + // TODO New key - Add a translation + "search.filters.filter.queue_last_start_time.max.label": "Max range", + + // "search.filters.applied.f.queue_last_start_time.min": "Min range", + // TODO New key - Add a translation + "search.filters.applied.f.queue_last_start_time.min": "Min range", + + // "search.filters.applied.f.queue_last_start_time.max": "Max range", + // TODO New key - Add a translation + "search.filters.applied.f.queue_last_start_time.max": "Max range", + + // "admin.notify.dashboard.outbound": "Outbound messages", + // TODO New key - Add a translation + "admin.notify.dashboard.outbound": "Outbound messages", + + // "admin.notify.dashboard.outbound-logs": "Logs/Outbound", + // TODO New key - Add a translation + "admin.notify.dashboard.outbound-logs": "Logs/Outbound", + + // "NOTIFY.incoming.search.results.head": "Incoming", + // TODO New key - Add a translation + "NOTIFY.incoming.search.results.head": "Incoming", + + // "search.filters.filter.relateditem.head": "Related item", + // TODO New key - Add a translation + "search.filters.filter.relateditem.head": "Related item", + + // "search.filters.filter.origin.head": "Origin", + // TODO New key - Add a translation + "search.filters.filter.origin.head": "Origin", + + // "search.filters.filter.ldn_service.head": "LDN Service", + // TODO New key - Add a translation + "search.filters.filter.ldn_service.head": "LDN Service", + + // "search.filters.filter.target.head": "Target", + // TODO New key - Add a translation + "search.filters.filter.target.head": "Target", + + // "search.filters.filter.queue_status.head": "Queue status", + // TODO New key - Add a translation + "search.filters.filter.queue_status.head": "Queue status", + + // "search.filters.filter.activity_stream_type.head": "Activity stream type", + // TODO New key - Add a translation + "search.filters.filter.activity_stream_type.head": "Activity stream type", + + // "search.filters.filter.coar_notify_type.head": "COAR Notify type", + // TODO New key - Add a translation + "search.filters.filter.coar_notify_type.head": "COAR Notify type", + + // "search.filters.filter.notification_type.head": "Notification type", + // TODO New key - Add a translation + "search.filters.filter.notification_type.head": "Notification type", + + // "search.filters.filter.relateditem.label": "Search related items", + // TODO New key - Add a translation + "search.filters.filter.relateditem.label": "Search related items", + + // "search.filters.filter.queue_status.label": "Search queue status", + // TODO New key - Add a translation + "search.filters.filter.queue_status.label": "Search queue status", + + // "search.filters.filter.target.label": "Search target", + // TODO New key - Add a translation + "search.filters.filter.target.label": "Search target", + + // "search.filters.filter.activity_stream_type.label": "Search activity stream type", + // TODO New key - Add a translation + "search.filters.filter.activity_stream_type.label": "Search activity stream type", + + // "search.filters.applied.f.queue_status": "Queue Status", + // TODO New key - Add a translation + "search.filters.applied.f.queue_status": "Queue Status", + + // "search.filters.queue_status.0,authority": "Untrusted Ip", + // TODO New key - Add a translation + "search.filters.queue_status.0,authority": "Untrusted Ip", + + // "search.filters.queue_status.1,authority": "Queued", + // TODO New key - Add a translation + "search.filters.queue_status.1,authority": "Queued", + + // "search.filters.queue_status.2,authority": "Processing", + // TODO New key - Add a translation + "search.filters.queue_status.2,authority": "Processing", + + // "search.filters.queue_status.3,authority": "Processed", + // TODO New key - Add a translation + "search.filters.queue_status.3,authority": "Processed", + + // "search.filters.queue_status.4,authority": "Failed", + // TODO New key - Add a translation + "search.filters.queue_status.4,authority": "Failed", + + // "search.filters.queue_status.5,authority": "Untrusted", + // TODO New key - Add a translation + "search.filters.queue_status.5,authority": "Untrusted", + + // "search.filters.queue_status.6,authority": "Unmapped Action", + // TODO New key - Add a translation + "search.filters.queue_status.6,authority": "Unmapped Action", + + // "search.filters.queue_status.7,authority": "Queued for retry", + // TODO New key - Add a translation + "search.filters.queue_status.7,authority": "Queued for retry", + + // "search.filters.applied.f.activity_stream_type": "Activity stream type", + // TODO New key - Add a translation + "search.filters.applied.f.activity_stream_type": "Activity stream type", + + // "search.filters.applied.f.coar_notify_type": "COAR Notify type", + // TODO New key - Add a translation + "search.filters.applied.f.coar_notify_type": "COAR Notify type", + + // "search.filters.applied.f.notification_type": "Notification type", + // TODO New key - Add a translation + "search.filters.applied.f.notification_type": "Notification type", + + // "search.filters.filter.coar_notify_type.label": "Search COAR Notify type", + // TODO New key - Add a translation + "search.filters.filter.coar_notify_type.label": "Search COAR Notify type", + + // "search.filters.filter.notification_type.label": "Search notification type", + // TODO New key - Add a translation + "search.filters.filter.notification_type.label": "Search notification type", + + // "search.filters.filter.relateditem.placeholder": "Related items", + // TODO New key - Add a translation + "search.filters.filter.relateditem.placeholder": "Related items", + + // "search.filters.filter.target.placeholder": "Target", + // TODO New key - Add a translation + "search.filters.filter.target.placeholder": "Target", + + // "search.filters.filter.origin.label": "Search source", + // TODO New key - Add a translation + "search.filters.filter.origin.label": "Search source", + + // "search.filters.filter.origin.placeholder": "Source", + // TODO New key - Add a translation + "search.filters.filter.origin.placeholder": "Source", + + // "search.filters.filter.ldn_service.label": "Search LDN Service", + // TODO New key - Add a translation + "search.filters.filter.ldn_service.label": "Search LDN Service", + + // "search.filters.filter.ldn_service.placeholder": "LDN Service", + // TODO New key - Add a translation + "search.filters.filter.ldn_service.placeholder": "LDN Service", + + // "search.filters.filter.queue_status.placeholder": "Queue status", + // TODO New key - Add a translation + "search.filters.filter.queue_status.placeholder": "Queue status", + + // "search.filters.filter.activity_stream_type.placeholder": "Activity stream type", + // TODO New key - Add a translation + "search.filters.filter.activity_stream_type.placeholder": "Activity stream type", + + // "search.filters.filter.coar_notify_type.placeholder": "COAR Notify type", + // TODO New key - Add a translation + "search.filters.filter.coar_notify_type.placeholder": "COAR Notify type", + + // "search.filters.filter.notification_type.placeholder": "Notification", + // TODO New key - Add a translation + "search.filters.filter.notification_type.placeholder": "Notification", + + // "search.filters.filter.notifyRelation.head": "Notify Relation", + // TODO New key - Add a translation + "search.filters.filter.notifyRelation.head": "Notify Relation", + + // "search.filters.filter.notifyRelation.label": "Search Notify Relation", + // TODO New key - Add a translation + "search.filters.filter.notifyRelation.label": "Search Notify Relation", + + // "search.filters.filter.notifyRelation.placeholder": "Notify Relation", + // TODO New key - Add a translation + "search.filters.filter.notifyRelation.placeholder": "Notify Relation", + + // "search.filters.filter.notifyReview.head": "Notify Review", + // TODO New key - Add a translation + "search.filters.filter.notifyReview.head": "Notify Review", + + // "search.filters.filter.notifyReview.label": "Search Notify Review", + // TODO New key - Add a translation + "search.filters.filter.notifyReview.label": "Search Notify Review", + + // "search.filters.filter.notifyReview.placeholder": "Notify Review", + // TODO New key - Add a translation + "search.filters.filter.notifyReview.placeholder": "Notify Review", + + // "search.filters.coar_notify_type.coar-notify:ReviewAction": "Review action", + // TODO New key - Add a translation + "search.filters.coar_notify_type.coar-notify:ReviewAction": "Review action", + + // "search.filters.coar_notify_type.coar-notify:ReviewAction,authority": "Review action", + // TODO New key - Add a translation + "search.filters.coar_notify_type.coar-notify:ReviewAction,authority": "Review action", + + // "notify-detail-modal.coar-notify:ReviewAction": "Review action", + // TODO New key - Add a translation + "notify-detail-modal.coar-notify:ReviewAction": "Review action", + + // "search.filters.coar_notify_type.coar-notify:EndorsementAction": "Endorsement action", + // TODO New key - Add a translation + "search.filters.coar_notify_type.coar-notify:EndorsementAction": "Endorsement action", + + // "search.filters.coar_notify_type.coar-notify:EndorsementAction,authority": "Endorsement action", + // TODO New key - Add a translation + "search.filters.coar_notify_type.coar-notify:EndorsementAction,authority": "Endorsement action", + + // "notify-detail-modal.coar-notify:EndorsementAction": "Endorsement action", + // TODO New key - Add a translation + "notify-detail-modal.coar-notify:EndorsementAction": "Endorsement action", + + // "search.filters.coar_notify_type.coar-notify:IngestAction": "Ingest action", + // TODO New key - Add a translation + "search.filters.coar_notify_type.coar-notify:IngestAction": "Ingest action", + + // "search.filters.coar_notify_type.coar-notify:IngestAction,authority": "Ingest action", + // TODO New key - Add a translation + "search.filters.coar_notify_type.coar-notify:IngestAction,authority": "Ingest action", + + // "notify-detail-modal.coar-notify:IngestAction": "Ingest action", + // TODO New key - Add a translation + "notify-detail-modal.coar-notify:IngestAction": "Ingest action", + + // "search.filters.coar_notify_type.coar-notify:RelationshipAction": "Relationship action", + // TODO New key - Add a translation + "search.filters.coar_notify_type.coar-notify:RelationshipAction": "Relationship action", + + // "search.filters.coar_notify_type.coar-notify:RelationshipAction,authority": "Relationship action", + // TODO New key - Add a translation + "search.filters.coar_notify_type.coar-notify:RelationshipAction,authority": "Relationship action", + + // "notify-detail-modal.coar-notify:RelationshipAction": "Relationship action", + // TODO New key - Add a translation + "notify-detail-modal.coar-notify:RelationshipAction": "Relationship action", + + // "search.filters.queue_status.QUEUE_STATUS_QUEUED": "Queued", + // TODO New key - Add a translation + "search.filters.queue_status.QUEUE_STATUS_QUEUED": "Queued", + + // "notify-detail-modal.QUEUE_STATUS_QUEUED": "Queued", + // TODO New key - Add a translation + "notify-detail-modal.QUEUE_STATUS_QUEUED": "Queued", + + // "search.filters.queue_status.QUEUE_STATUS_QUEUED_FOR_RETRY": "Queued for retry", + // TODO New key - Add a translation + "search.filters.queue_status.QUEUE_STATUS_QUEUED_FOR_RETRY": "Queued for retry", + + // "notify-detail-modal.QUEUE_STATUS_QUEUED_FOR_RETRY": "Queued for retry", + // TODO New key - Add a translation + "notify-detail-modal.QUEUE_STATUS_QUEUED_FOR_RETRY": "Queued for retry", + + // "search.filters.queue_status.QUEUE_STATUS_PROCESSING": "Processing", + // TODO New key - Add a translation + "search.filters.queue_status.QUEUE_STATUS_PROCESSING": "Processing", + + // "notify-detail-modal.QUEUE_STATUS_PROCESSING": "Processing", + // TODO New key - Add a translation + "notify-detail-modal.QUEUE_STATUS_PROCESSING": "Processing", + + // "search.filters.queue_status.QUEUE_STATUS_PROCESSED": "Processed", + // TODO New key - Add a translation + "search.filters.queue_status.QUEUE_STATUS_PROCESSED": "Processed", + + // "notify-detail-modal.QUEUE_STATUS_PROCESSED": "Processed", + // TODO New key - Add a translation + "notify-detail-modal.QUEUE_STATUS_PROCESSED": "Processed", + + // "search.filters.queue_status.QUEUE_STATUS_FAILED": "Failed", + // TODO New key - Add a translation + "search.filters.queue_status.QUEUE_STATUS_FAILED": "Failed", + + // "notify-detail-modal.QUEUE_STATUS_FAILED": "Failed", + // TODO New key - Add a translation + "notify-detail-modal.QUEUE_STATUS_FAILED": "Failed", + + // "search.filters.queue_status.QUEUE_STATUS_UNTRUSTED": "Untrusted", + // TODO New key - Add a translation + "search.filters.queue_status.QUEUE_STATUS_UNTRUSTED": "Untrusted", + + // "search.filters.queue_status.QUEUE_STATUS_UNTRUSTED_IP": "Untrusted Ip", + // TODO New key - Add a translation + "search.filters.queue_status.QUEUE_STATUS_UNTRUSTED_IP": "Untrusted Ip", + + // "notify-detail-modal.QUEUE_STATUS_UNTRUSTED": "Untrusted", + // TODO New key - Add a translation + "notify-detail-modal.QUEUE_STATUS_UNTRUSTED": "Untrusted", + + // "notify-detail-modal.QUEUE_STATUS_UNTRUSTED_IP": "Untrusted Ip", + // TODO New key - Add a translation + "notify-detail-modal.QUEUE_STATUS_UNTRUSTED_IP": "Untrusted Ip", + + // "search.filters.queue_status.QUEUE_STATUS_UNMAPPED_ACTION": "Unmapped Action", + // TODO New key - Add a translation + "search.filters.queue_status.QUEUE_STATUS_UNMAPPED_ACTION": "Unmapped Action", + + // "notify-detail-modal.QUEUE_STATUS_UNMAPPED_ACTION": "Unmapped Action", + // TODO New key - Add a translation + "notify-detail-modal.QUEUE_STATUS_UNMAPPED_ACTION": "Unmapped Action", + + // "sorting.queue_last_start_time.DESC": "Last started queue Descending", + // TODO New key - Add a translation + "sorting.queue_last_start_time.DESC": "Last started queue Descending", + + // "sorting.queue_last_start_time.ASC": "Last started queue Ascending", + // TODO New key - Add a translation + "sorting.queue_last_start_time.ASC": "Last started queue Ascending", + + // "sorting.queue_attempts.DESC": "Queue attempted Descending", + // TODO New key - Add a translation + "sorting.queue_attempts.DESC": "Queue attempted Descending", + + // "sorting.queue_attempts.ASC": "Queue attempted Ascending", + // TODO New key - Add a translation + "sorting.queue_attempts.ASC": "Queue attempted Ascending", + + // "NOTIFY.incoming.involvedItems.search.results.head": "Items involved in incoming LDN", + // TODO New key - Add a translation + "NOTIFY.incoming.involvedItems.search.results.head": "Items involved in incoming LDN", + + // "NOTIFY.outgoing.involvedItems.search.results.head": "Items involved in outgoing LDN", + // TODO New key - Add a translation + "NOTIFY.outgoing.involvedItems.search.results.head": "Items involved in outgoing LDN", + + // "type.notify-detail-modal": "Type", + // TODO New key - Add a translation + "type.notify-detail-modal": "Type", + + // "id.notify-detail-modal": "Id", + // TODO New key - Add a translation + "id.notify-detail-modal": "Id", + + // "coarNotifyType.notify-detail-modal": "COAR Notify type", + // TODO New key - Add a translation + "coarNotifyType.notify-detail-modal": "COAR Notify type", + + // "activityStreamType.notify-detail-modal": "Activity stream type", + // TODO New key - Add a translation + "activityStreamType.notify-detail-modal": "Activity stream type", + + // "inReplyTo.notify-detail-modal": "In reply to", + // TODO New key - Add a translation + "inReplyTo.notify-detail-modal": "In reply to", + + // "object.notify-detail-modal": "Repository Item", + // TODO New key - Add a translation + "object.notify-detail-modal": "Repository Item", + + // "context.notify-detail-modal": "Repository Item", + // TODO New key - Add a translation + "context.notify-detail-modal": "Repository Item", + + // "queueAttempts.notify-detail-modal": "Queue attempts", + // TODO New key - Add a translation + "queueAttempts.notify-detail-modal": "Queue attempts", + + // "queueLastStartTime.notify-detail-modal": "Queue last started", + // TODO New key - Add a translation + "queueLastStartTime.notify-detail-modal": "Queue last started", + + // "origin.notify-detail-modal": "LDN Service", + // TODO New key - Add a translation + "origin.notify-detail-modal": "LDN Service", + + // "target.notify-detail-modal": "LDN Service", + // TODO New key - Add a translation + "target.notify-detail-modal": "LDN Service", + + // "queueStatusLabel.notify-detail-modal": "Queue status", + // TODO New key - Add a translation + "queueStatusLabel.notify-detail-modal": "Queue status", + + // "queueTimeout.notify-detail-modal": "Queue timeout", + // TODO New key - Add a translation + "queueTimeout.notify-detail-modal": "Queue timeout", + + // "notify-message-modal.title": "Message Detail", + // TODO New key - Add a translation + "notify-message-modal.title": "Message Detail", + + // "notify-message-modal.show-message": "Show message", + // TODO New key - Add a translation + "notify-message-modal.show-message": "Show message", + + // "notify-message-result.timestamp": "Timestamp", + // TODO New key - Add a translation + "notify-message-result.timestamp": "Timestamp", + + // "notify-message-result.repositoryItem": "Repository Item", + // TODO New key - Add a translation + "notify-message-result.repositoryItem": "Repository Item", + + // "notify-message-result.ldnService": "LDN Service", + // TODO New key - Add a translation + "notify-message-result.ldnService": "LDN Service", + + // "notify-message-result.type": "Type", + // TODO New key - Add a translation + "notify-message-result.type": "Type", + + // "notify-message-result.status": "Status", + // TODO New key - Add a translation + "notify-message-result.status": "Status", + + // "notify-message-result.action": "Action", + // TODO New key - Add a translation + "notify-message-result.action": "Action", + + // "notify-message-result.detail": "Detail", + // TODO New key - Add a translation + "notify-message-result.detail": "Detail", + + // "notify-message-result.reprocess": "Reprocess", + // TODO New key - Add a translation + "notify-message-result.reprocess": "Reprocess", + + // "notify-queue-status.processed": "Processed", + // TODO New key - Add a translation + "notify-queue-status.processed": "Processed", + + // "notify-queue-status.failed": "Failed", + // TODO New key - Add a translation + "notify-queue-status.failed": "Failed", + + // "notify-queue-status.queue_retry": "Queued for retry", + // TODO New key - Add a translation + "notify-queue-status.queue_retry": "Queued for retry", + + // "notify-queue-status.unmapped_action": "Unmapped action", + // TODO New key - Add a translation + "notify-queue-status.unmapped_action": "Unmapped action", + + // "notify-queue-status.processing": "Processing", + // TODO New key - Add a translation + "notify-queue-status.processing": "Processing", + + // "notify-queue-status.queued": "Queued", + // TODO New key - Add a translation + "notify-queue-status.queued": "Queued", + + // "notify-queue-status.untrusted": "Untrusted", + // TODO New key - Add a translation + "notify-queue-status.untrusted": "Untrusted", + + // "ldnService.notify-detail-modal": "LDN Service", + // TODO New key - Add a translation + "ldnService.notify-detail-modal": "LDN Service", + + // "relatedItem.notify-detail-modal": "Related Item", + // TODO New key - Add a translation + "relatedItem.notify-detail-modal": "Related Item", + + // "search.filters.filter.notifyEndorsement.head": "Notify Endorsement", + // TODO New key - Add a translation + "search.filters.filter.notifyEndorsement.head": "Notify Endorsement", + + // "search.filters.filter.notifyEndorsement.placeholder": "Notify Endorsement", + // TODO New key - Add a translation + "search.filters.filter.notifyEndorsement.placeholder": "Notify Endorsement", + + // "search.filters.filter.notifyEndorsement.label": "Search Notify Endorsement", + // TODO New key - Add a translation + "search.filters.filter.notifyEndorsement.label": "Search Notify Endorsement", + } From 533da6624f1140fb182505ca5b3cf69ceb1e9a67 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 9 Jul 2024 17:56:06 +0200 Subject: [PATCH 178/822] add missing German translations (cherry picked from commit 2af168bd5423e6917adc18990aeda8ee9f5da962) --- src/assets/i18n/de.json5 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 36b092178cb..82420d691b9 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -4815,6 +4815,12 @@ // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Zeitschriftenband importieren", + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.none": "Import remote item", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.none": "Item importieren", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication": "Import remote publication", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication": "Metadaten der Publikation importieren", + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Importiere Autor:innen-Metadaten", From 26e02639d0df25825dfe6464c41b313d6aab1e97 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 9 Jul 2024 17:56:06 +0200 Subject: [PATCH 179/822] add missing German translations (cherry picked from commit 2af168bd5423e6917adc18990aeda8ee9f5da962) --- src/assets/i18n/de.json5 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index e1ebb489cf1..640352c4fa9 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -5226,6 +5226,12 @@ // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Zeitschriftenband importieren", + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.none": "Import remote item", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.none": "Item importieren", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication": "Import remote publication", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication": "Metadaten der Publikation importieren", + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Importiere Autor:innen-Metadaten", From dac4d4a71321dd776d1af384535815b3ac63e53e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 13:57:17 +0000 Subject: [PATCH 180/822] Bump the angular group with 10 updates Bumps the angular group with 10 updates: | Package | From | To | | --- | --- | --- | | [@angular/localize](https://github.com/angular/angular) | `17.3.11` | `17.3.12` | | [@angular/ssr](https://github.com/angular/angular-cli) | `17.3.9` | `17.3.10` | | [@angular-devkit/build-angular](https://github.com/angular/angular-cli) | `17.3.9` | `17.3.10` | | [@angular-eslint/builder](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/builder) | `17.2.1` | `17.5.3` | | [@angular-eslint/bundled-angular-compiler](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/bundled-angular-compiler) | `17.2.1` | `17.5.3` | | [@angular-eslint/eslint-plugin](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin) | `17.2.1` | `17.5.3` | | [@angular-eslint/eslint-plugin-template](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin-template) | `17.2.1` | `17.5.3` | | [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/schematics) | `17.2.1` | `17.5.3` | | [@angular-eslint/template-parser](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/template-parser) | `17.2.1` | `17.5.3` | | [@angular/cli](https://github.com/angular/angular-cli) | `17.3.9` | `17.3.10` | Updates `@angular/localize` from 17.3.11 to 17.3.12 - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md) - [Commits](https://github.com/angular/angular/compare/17.3.11...17.3.12) Updates `@angular/ssr` from 17.3.9 to 17.3.10 - [Release notes](https://github.com/angular/angular-cli/releases) - [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md) - [Commits](https://github.com/angular/angular-cli/compare/17.3.9...17.3.10) Updates `@angular-devkit/build-angular` from 17.3.9 to 17.3.10 - [Release notes](https://github.com/angular/angular-cli/releases) - [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md) - [Commits](https://github.com/angular/angular-cli/compare/17.3.9...17.3.10) Updates `@angular-eslint/builder` from 17.2.1 to 17.5.3 - [Release notes](https://github.com/angular-eslint/angular-eslint/releases) - [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/builder/CHANGELOG.md) - [Commits](https://github.com/angular-eslint/angular-eslint/commits/HEAD/packages/builder) Updates `@angular-eslint/bundled-angular-compiler` from 17.2.1 to 17.5.3 - [Release notes](https://github.com/angular-eslint/angular-eslint/releases) - [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/bundled-angular-compiler/CHANGELOG.md) - [Commits](https://github.com/angular-eslint/angular-eslint/commits/HEAD/packages/bundled-angular-compiler) Updates `@angular-eslint/eslint-plugin` from 17.2.1 to 17.5.3 - [Release notes](https://github.com/angular-eslint/angular-eslint/releases) - [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/angular-eslint/angular-eslint/commits/HEAD/packages/eslint-plugin) Updates `@angular-eslint/eslint-plugin-template` from 17.2.1 to 17.5.3 - [Release notes](https://github.com/angular-eslint/angular-eslint/releases) - [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin-template/CHANGELOG.md) - [Commits](https://github.com/angular-eslint/angular-eslint/commits/HEAD/packages/eslint-plugin-template) Updates `@angular-eslint/schematics` from 17.2.1 to 17.5.3 - [Release notes](https://github.com/angular-eslint/angular-eslint/releases) - [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/schematics/CHANGELOG.md) - [Commits](https://github.com/angular-eslint/angular-eslint/commits/HEAD/packages/schematics) Updates `@angular-eslint/template-parser` from 17.2.1 to 17.5.3 - [Release notes](https://github.com/angular-eslint/angular-eslint/releases) - [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/template-parser/CHANGELOG.md) - [Commits](https://github.com/angular-eslint/angular-eslint/commits/HEAD/packages/template-parser) Updates `@angular/cli` from 17.3.9 to 17.3.10 - [Release notes](https://github.com/angular/angular-cli/releases) - [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md) - [Commits](https://github.com/angular/angular-cli/compare/17.3.9...17.3.10) --- updated-dependencies: - dependency-name: "@angular/localize" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/ssr" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular-devkit/build-angular" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular-eslint/builder" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: angular - dependency-name: "@angular-eslint/bundled-angular-compiler" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: angular - dependency-name: "@angular-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: angular - dependency-name: "@angular-eslint/eslint-plugin-template" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: angular - dependency-name: "@angular-eslint/schematics" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: angular - dependency-name: "@angular-eslint/template-parser" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: angular - dependency-name: "@angular/cli" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular ... Signed-off-by: dependabot[bot] --- package.json | 20 +- yarn.lock | 684 ++++++++++++++------------------------------------- 2 files changed, 199 insertions(+), 505 deletions(-) diff --git a/package.json b/package.json index ad82a8fcd0f..c67f948ed00 100644 --- a/package.json +++ b/package.json @@ -67,12 +67,12 @@ "@angular/compiler": "^17.3.11", "@angular/core": "^17.3.11", "@angular/forms": "^17.3.11", - "@angular/localize": "17.3.11", + "@angular/localize": "17.3.12", "@angular/platform-browser": "^17.3.11", "@angular/platform-browser-dynamic": "^17.3.11", "@angular/platform-server": "^17.3.11", "@angular/router": "^17.3.11", - "@angular/ssr": "^17.3.8", + "@angular/ssr": "^17.3.10", "@babel/runtime": "7.21.0", "@kolkov/ngx-gallery": "^2.0.1", "@material-ui/core": "^4.11.0", @@ -140,14 +140,14 @@ }, "devDependencies": { "@angular-builders/custom-webpack": "~17.0.2", - "@angular-devkit/build-angular": "^17.3.8", - "@angular-eslint/builder": "17.2.1", - "@angular-eslint/bundled-angular-compiler": "17.2.1", - "@angular-eslint/eslint-plugin": "17.2.1", - "@angular-eslint/eslint-plugin-template": "17.2.1", - "@angular-eslint/schematics": "17.2.1", - "@angular-eslint/template-parser": "17.2.1", - "@angular/cli": "^17.3.8", + "@angular-devkit/build-angular": "^17.3.10", + "@angular-eslint/builder": "17.5.3", + "@angular-eslint/bundled-angular-compiler": "17.5.3", + "@angular-eslint/eslint-plugin": "17.5.3", + "@angular-eslint/eslint-plugin-template": "17.5.3", + "@angular-eslint/schematics": "17.5.3", + "@angular-eslint/template-parser": "17.5.3", + "@angular/cli": "^17.3.10", "@angular/compiler-cli": "^17.3.11", "@angular/language-service": "^17.3.11", "@cypress/schematic": "^1.5.0", diff --git a/yarn.lock b/yarn.lock index 3888a2384ed..0753b822a5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31,12 +31,12 @@ lodash "^4.17.15" webpack-merge "^5.7.3" -"@angular-devkit/architect@0.1703.9", "@angular-devkit/architect@>=0.1700.0 < 0.1800.0": - version "0.1703.9" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1703.9.tgz#f99d01a704407c5467841c49654f5c3ac930f143" - integrity sha512-kEPfTOVnzrJxPGTvaXy8653HU9Fucxttx9gVfQR1yafs+yIEGx3fKGKe89YPmaEay32bIm7ZUpxDF1FO14nkdQ== +"@angular-devkit/architect@0.1703.10", "@angular-devkit/architect@>=0.1700.0 < 0.1800.0": + version "0.1703.10" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1703.10.tgz#c70a59f6dcc5228ac41713a14582253d5e348b40" + integrity sha512-wmjx5GspSPprdUGryK5+9vNawbEO7p8h9dxgX3uoeFwPAECcHC+/KK3qPhX2NiGcM6MDsyt25SrbSktJp6PRsA== dependencies: - "@angular-devkit/core" "17.3.9" + "@angular-devkit/core" "17.3.10" rxjs "7.8.1" "@angular-devkit/architect@^0.1202.10": @@ -47,15 +47,15 @@ "@angular-devkit/core" "12.2.18" rxjs "6.6.7" -"@angular-devkit/build-angular@^17.0.0", "@angular-devkit/build-angular@^17.3.8": - version "17.3.9" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.3.9.tgz#54d55052be3fcc9034a1a0659acd6dcd664cf034" - integrity sha512-EuAPSC4c2DSJLlL4ieviKLx1faTyY+ymWycq6KFwoxu1FgWly/dqBeWyXccYinLhPVZmoh6+A/5S4YWXlOGSnA== +"@angular-devkit/build-angular@^17.0.0", "@angular-devkit/build-angular@^17.3.10": + version "17.3.10" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.3.10.tgz#68c34b2922991f22369e912e080ddc5a0b112ca4" + integrity sha512-syz7xgzmp8/0tPJWwQIKZt7KNJfp9U7hkqNacXz4XTYz6YM0oyBXlqk2claSxywWBEkc0eJVSMD9e2ArusZBuA== dependencies: "@ampproject/remapping" "2.3.0" - "@angular-devkit/architect" "0.1703.9" - "@angular-devkit/build-webpack" "0.1703.9" - "@angular-devkit/core" "17.3.9" + "@angular-devkit/architect" "0.1703.10" + "@angular-devkit/build-webpack" "0.1703.10" + "@angular-devkit/core" "17.3.10" "@babel/core" "7.24.0" "@babel/generator" "7.23.6" "@babel/helper-annotate-as-pure" "7.22.5" @@ -66,7 +66,7 @@ "@babel/preset-env" "7.24.0" "@babel/runtime" "7.24.0" "@discoveryjs/json-ext" "0.5.7" - "@ngtools/webpack" "17.3.9" + "@ngtools/webpack" "17.3.10" "@vitejs/plugin-basic-ssl" "1.1.0" ansi-colors "4.1.3" autoprefixer "10.4.18" @@ -108,7 +108,7 @@ tree-kill "1.2.2" tslib "2.6.2" undici "6.11.1" - vite "5.1.7" + vite "5.1.8" watchpack "2.4.0" webpack "5.94.0" webpack-dev-middleware "6.1.2" @@ -118,12 +118,12 @@ optionalDependencies: esbuild "0.20.1" -"@angular-devkit/build-webpack@0.1703.9": - version "0.1703.9" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1703.9.tgz#9eff5c69638d6cbb083b5c406e6dfca369e8641b" - integrity sha512-3b0LND39Nc+DwCQ0N7Tbsd7RAFWTeIc4VDwk/7RO8EMYTP5Kfgr/TK66nwTBypHsjmD69IMKHZZaZuiDfGfx2A== +"@angular-devkit/build-webpack@0.1703.10": + version "0.1703.10" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1703.10.tgz#235760406246594b9c898eecef9e8703ad20769a" + integrity sha512-m6dDgzKLW+c3z9/TUxYmbJEtEhrdYNQ4ogdtAgEYA/FRrKueDU0WztLNr+dVbvwNP99Skovtr8sAQfN6twproQ== dependencies: - "@angular-devkit/architect" "0.1703.9" + "@angular-devkit/architect" "0.1703.10" rxjs "7.8.1" "@angular-devkit/core@12.2.18", "@angular-devkit/core@^12.2.17": @@ -138,10 +138,10 @@ rxjs "6.6.7" source-map "0.7.3" -"@angular-devkit/core@17.3.9", "@angular-devkit/core@^17.0.0", "@angular-devkit/core@^17.1.0": - version "17.3.9" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.3.9.tgz#68b72e775195f07742f84b6ebd60b241eee98a72" - integrity sha512-/iKyn5YT7NW5ylrg9yufUydS8byExeQ2HHIwFC4Ebwb/JYYCz+k4tBf2LdP+zXpemDpLznXTQGWia0/yJjG8Vg== +"@angular-devkit/core@17.3.10", "@angular-devkit/core@^17.0.0", "@angular-devkit/core@^17.1.0": + version "17.3.10" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.3.10.tgz#c259052a891ad0bd1a7708d1081571683b3fa814" + integrity sha512-czdl54yxU5DOAGy/uUPNjJruoBDTgwi/V+eOgLNybYhgrc+TsY0f7uJ11yEk/pz5sCov7xIiS7RdRv96waS7vg== dependencies: ajv "8.12.0" ajv-formats "2.1.1" @@ -159,78 +159,74 @@ ora "5.4.1" rxjs "6.6.7" -"@angular-devkit/schematics@17.3.9": - version "17.3.9" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.3.9.tgz#0fcf22d51f49fd23eeb88620134f2cb622094b7b" - integrity sha512-9qg+uWywgAtaQlvbnCQv47hcL6ZuA+d9ucgZ0upZftBllZ2vp5WIthCPb2mB0uBkj84Csmtz9MsErFjOQtTj4g== +"@angular-devkit/schematics@17.3.10": + version "17.3.10" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.3.10.tgz#a3d62b33f82fd1fa51246d00ada92efe82a00ae7" + integrity sha512-FHcNa1ktYRd0SKExCsNJpR75RffsyuPIV8kvBXzXnLHmXMqvl25G2te3yYJ9yYqy9OLy/58HZznZTxWRyUdHOg== dependencies: - "@angular-devkit/core" "17.3.9" + "@angular-devkit/core" "17.3.10" jsonc-parser "3.2.1" magic-string "0.30.8" ora "5.4.1" rxjs "7.8.1" -"@angular-eslint/builder@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/builder/-/builder-17.2.1.tgz#c7ba17e3a9de3a65d010f101b0c6cd3d5e9c26a8" - integrity sha512-O30eaR0wCPiP+zKWvXj2JM8hVq30Wok2rp7zJMFm3PurjF9nWIIyexXkE5fa538DYZYxu8N3gQRqhpv5jvTXCg== - dependencies: - "@nx/devkit" "17.2.8" - nx "17.2.8" - -"@angular-eslint/bundled-angular-compiler@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.2.1.tgz#d849b0845371b41856b9f598af81ce5bf799bca0" - integrity sha512-puC0itsZv2QlrDOCcWtq1KZH+DvfrpV+mV78HHhi6+h25R5iIhr8ARKcl3EQxFjvrFq34jhG8pSupxKvFbHVfA== - -"@angular-eslint/eslint-plugin-template@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.2.1.tgz#226a623219375a2344112c1c896fefef0dae4df6" - integrity sha512-hl1hcHtcm90wyVL1OQGTz16oA0KHon+FFb3Qg0fLXObaXxA495Ecefd9ub5Xxg4JEOPRDi29bF1Y3YKpwflgeg== - dependencies: - "@angular-eslint/bundled-angular-compiler" "17.2.1" - "@angular-eslint/utils" "17.2.1" - "@typescript-eslint/type-utils" "6.19.0" - "@typescript-eslint/utils" "6.19.0" +"@angular-eslint/builder@17.5.3": + version "17.5.3" + resolved "https://registry.yarnpkg.com/@angular-eslint/builder/-/builder-17.5.3.tgz#d04756dc2e6d70108100445aae206051d115ab1f" + integrity sha512-DoPCwt8qp5oMkfxY8V3wygf6/E7zzgXkPCwTRhIelklfpB3nYwLnbRSD8G5hueAU4eyASKiIuhR79E996AuUSw== + +"@angular-eslint/bundled-angular-compiler@17.5.3": + version "17.5.3" + resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.5.3.tgz#6bdeb55881b2be796196cc3e0c684250923dd89f" + integrity sha512-x9jZ6mME9wxumErPGonWERXX/9TJ7mzEkQhOKt3BxBFm0sy9XQqLMAenp1PBSg3RF3rH7EEVdB2+jb75RtHp0g== + +"@angular-eslint/eslint-plugin-template@17.5.3": + version "17.5.3" + resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.5.3.tgz#fa4f91cf028c64d38d0bcb5087cf8546811f5694" + integrity sha512-RkRFagxqBPV2xdNyeQQROUm6I1Izto1Z3Wy73lCk2zq1RhVgbznniH/epmOIE8PMkHmMKmZ765FV++J/90p4Ig== + dependencies: + "@angular-eslint/bundled-angular-compiler" "17.5.3" + "@angular-eslint/utils" "17.5.3" + "@typescript-eslint/type-utils" "7.11.0" + "@typescript-eslint/utils" "7.11.0" aria-query "5.3.0" axobject-query "4.0.0" -"@angular-eslint/eslint-plugin@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin/-/eslint-plugin-17.2.1.tgz#2be51ead1785950feb8351001e0683eae42f4c29" - integrity sha512-9yA81BHpsaCUKRBtHGN3ieAy8HpIoffzPQMu34lYqZFT4yGHGhYmhQjNSQGBRbV2LD9dVv2U35rMHNmUcozXpw== +"@angular-eslint/eslint-plugin@17.5.3": + version "17.5.3" + resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin/-/eslint-plugin-17.5.3.tgz#56c6bf09262089dd10a27b22ac1de979b6bc805b" + integrity sha512-2gMRZ+SkiygrPDtCJwMfjmwIFOcvxxC4NRX/MqRo6udsa0gtqPrc8acRbwrmAXlullmhzmaeUfkHpGDSzW8pFw== dependencies: - "@angular-eslint/utils" "17.2.1" - "@typescript-eslint/utils" "6.19.0" + "@angular-eslint/bundled-angular-compiler" "17.5.3" + "@angular-eslint/utils" "17.5.3" + "@typescript-eslint/utils" "7.11.0" -"@angular-eslint/schematics@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/schematics/-/schematics-17.2.1.tgz#8c0c15f106afe9fc9f89dd6573e6325afd2bf1e1" - integrity sha512-7ldtIePI4ZTp/TBpeOZkzfv30HSAn//4TgtFuqvojudI8n8batV5FqQ0VNm1e0zitl75t8Zwtr0KYT4I6vh59g== +"@angular-eslint/schematics@17.5.3": + version "17.5.3" + resolved "https://registry.yarnpkg.com/@angular-eslint/schematics/-/schematics-17.5.3.tgz#8957d5b47eb89b6c962628056d192fceb877fc81" + integrity sha512-a0MlOjNLIM18l/66S+CzhANQR3QH3jDUa1MC50E4KBf1mwjQyfqd6RdfbOTMDjgFlPrfB+5JvoWOHHGj7FFM1A== dependencies: - "@angular-eslint/eslint-plugin" "17.2.1" - "@angular-eslint/eslint-plugin-template" "17.2.1" - "@nx/devkit" "17.2.8" - ignore "5.3.0" - nx "17.2.8" + "@angular-eslint/eslint-plugin" "17.5.3" + "@angular-eslint/eslint-plugin-template" "17.5.3" + ignore "5.3.1" strip-json-comments "3.1.1" - tmp "0.2.1" + tmp "0.2.3" -"@angular-eslint/template-parser@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/template-parser/-/template-parser-17.2.1.tgz#005f997346eb17c6dbca5fffc41da51b7e755013" - integrity sha512-WPQYFvRju0tCDXQ/pwrzC911pE07JvpeDgcN2elhzV6lxDHJEZpA5O9pnW9qgNA6J6XM9Q7dBkJ22ztAzC4WFw== +"@angular-eslint/template-parser@17.5.3": + version "17.5.3" + resolved "https://registry.yarnpkg.com/@angular-eslint/template-parser/-/template-parser-17.5.3.tgz#5bfb6558a131bf54a67e3bd00bcf493d21f94e20" + integrity sha512-NYybOsMkJUtFOW2JWALicipq0kK5+jGwA1MYyRoXjdbDlXltHUb9qkXj7p0fE6uRutBGXDl4288s8g/fZCnAIA== dependencies: - "@angular-eslint/bundled-angular-compiler" "17.2.1" + "@angular-eslint/bundled-angular-compiler" "17.5.3" eslint-scope "^8.0.0" -"@angular-eslint/utils@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/utils/-/utils-17.2.1.tgz#3d4217775d86479348fdd0e1ad83014c9d8339f2" - integrity sha512-qQYTBXy90dWM7fhhpa5i9lTtqqhJisvRa+naCrQx9kBgR458JScLdkVIdcZ9D/rPiDCmKiVUfgcDISnjUeqTqg== +"@angular-eslint/utils@17.5.3": + version "17.5.3" + resolved "https://registry.yarnpkg.com/@angular-eslint/utils/-/utils-17.5.3.tgz#0b162a84e6f6af4e9ac5a3de95d95ee1df360232" + integrity sha512-0nNm1FUOLhVHrdK2PP5dZCYYVmTIkEJ4CmlwpuC4JtCLbD5XAHQpY/ZW5Ff5n1b7KfJt1Zy//jlhkkIaw3LaBQ== dependencies: - "@angular-eslint/bundled-angular-compiler" "17.2.1" - "@typescript-eslint/utils" "6.19.0" + "@angular-eslint/bundled-angular-compiler" "17.5.3" + "@typescript-eslint/utils" "7.11.0" "@angular/animations@^17.3.11": version "17.3.12" @@ -248,15 +244,15 @@ optionalDependencies: parse5 "^7.1.2" -"@angular/cli@^17.3.8": - version "17.3.9" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-17.3.9.tgz#cd571d288be3b3eb80acd25b54dd8a5008af417a" - integrity sha512-b5RGu5RO4VKZlMQDatwABAn1qocgD9u4IrGN2dvHDcrz5apTKYftUdGyG42vngyDNBCg1mWkSDQEWK4f2HfuGg== +"@angular/cli@^17.3.10": + version "17.3.10" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-17.3.10.tgz#15156dc511a6c43a798f5015e0345d7678691418" + integrity sha512-lA0kf4Cpo8Jcuennq6wGyBTP/UG1oX4xsM9uLRZ2vkPoisjHCk46rWaVP7vfAqdUH39vbATFXftpy1SiEmAI4w== dependencies: - "@angular-devkit/architect" "0.1703.9" - "@angular-devkit/core" "17.3.9" - "@angular-devkit/schematics" "17.3.9" - "@schematics/angular" "17.3.9" + "@angular-devkit/architect" "0.1703.10" + "@angular-devkit/core" "17.3.10" + "@angular-devkit/schematics" "17.3.10" + "@schematics/angular" "17.3.10" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.3" ini "4.1.2" @@ -319,10 +315,10 @@ resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-17.3.12.tgz#87a3d71e94ee7442eac046ca64be73a6a31a0027" integrity sha512-MVmEXonXwdhFtIpU4q8qbXHsrAsdTjZcPPuWCU0zXVQ+VaB/y6oF7BVpmBtfyBcBCums1guEncPP+AZVvulXmQ== -"@angular/localize@17.3.11": - version "17.3.11" - resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-17.3.11.tgz#2eaec8c8126caaa7bad7cc7433ea91882fbe4885" - integrity sha512-uc38JfGpIEb13rDZu7wZfEvLxBpWbhfsOR+yI21M4zIiKYQxI7RGgtH9GbCKZDEZmeTUSz/idA4zwRiiX8wNvQ== +"@angular/localize@17.3.12": + version "17.3.12" + resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-17.3.12.tgz#e38fbb595b6e045d49488afb0ad3e276da6721e3" + integrity sha512-b7J7zY/CgJhFVPtmu/pEjefU5SHuTy7lQgX6kTrJPaUSJ5i578R17xr4SwrWe7G4jzQwO6GXZZd17a62uNRyOA== dependencies: "@babel/core" "7.23.9" "@types/babel__core" "7.20.5" @@ -358,10 +354,10 @@ dependencies: tslib "^2.3.0" -"@angular/ssr@^17.3.8": - version "17.3.9" - resolved "https://registry.yarnpkg.com/@angular/ssr/-/ssr-17.3.9.tgz#69422608b9756c3e46f0489bc43433d8a90c4afe" - integrity sha512-AbS3tsHUVOqwC3XI4B8hQDWThfrOyv8Qhe1N9a712nJKcqmfrMO0gtvdhI//VxYz0X08/l97Yh5D61WqF7+CQw== +"@angular/ssr@^17.3.10": + version "17.3.10" + resolved "https://registry.yarnpkg.com/@angular/ssr/-/ssr-17.3.10.tgz#bf13834e3115ca7779834820dcb5b3b9659056bf" + integrity sha512-t+NX1HufU38c0u+8mDg31cqrXZo5SEUxjBuXwdu3mOvYbkanjhbtyIgIMYr9Vru8pqncasgHLJv2RVWDvAjlEw== dependencies: critters "0.0.22" tslib "^2.3.0" @@ -1922,13 +1918,6 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - "@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -2127,10 +2116,10 @@ dependencies: tslib "^2.0.0" -"@ngtools/webpack@17.3.9": - version "17.3.9" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.3.9.tgz#cfb27add90a1bb522ecbf869b79369145d4d9e6e" - integrity sha512-2+NvEQuYKRWdZaJbRJWEnR48tpW0uYbhwfHBHLDI9Kazb3mb0oAwYBVXdq+TtDLBypXnMsFpCewjRHTvkVx4/A== +"@ngtools/webpack@17.3.10": + version "17.3.10" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.3.10.tgz#6f077ef3d1fa4363cffcfee66f9b2e52164069b2" + integrity sha512-yPKmdbTJzxROAl2NS8P8eHB2mU0BqV2I0ZiKmX6oTetY2Ea4i2WzlTK39pPpG7atmdF2NPWYLXdJWAup+JxSyw== "@ngtools/webpack@^16.2.12": version "16.2.15" @@ -2277,84 +2266,6 @@ node-gyp "^10.0.0" which "^4.0.0" -"@nrwl/devkit@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-17.2.8.tgz#dd3467b484c4611454a45541ffb29e4de5b2ebe7" - integrity sha512-l2dFy5LkWqSA45s6pee6CoqJeluH+sjRdVnAAQfjLHRNSx6mFAKblyzq5h1f4P0EUCVVVqLs+kVqmNx5zxYqvw== - dependencies: - "@nx/devkit" "17.2.8" - -"@nrwl/tao@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-17.2.8.tgz#41ff3d715a0763e95cf5c35e7f79cd3be358dc5f" - integrity sha512-Qpk5YKeJ+LppPL/wtoDyNGbJs2MsTi6qyX/RdRrEc8lc4bk6Cw3Oul1qTXCI6jT0KzTz+dZtd0zYD/G7okkzvg== - dependencies: - nx "17.2.8" - tslib "^2.3.0" - -"@nx/devkit@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-17.2.8.tgz#49b6c94a3c12fba63eae6514fb37a468d0570e2e" - integrity sha512-6LtiQihtZwqz4hSrtT5cCG5XMCWppG6/B8c1kNksg97JuomELlWyUyVF+sxmeERkcLYFaKPTZytP0L3dmCFXaw== - dependencies: - "@nrwl/devkit" "17.2.8" - ejs "^3.1.7" - enquirer "~2.3.6" - ignore "^5.0.4" - semver "7.5.3" - tmp "~0.2.1" - tslib "^2.3.0" - -"@nx/nx-darwin-arm64@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-17.2.8.tgz#26645c9548d5e387b43c06fccfa18e2c1f08055e" - integrity sha512-dMb0uxug4hM7tusISAU1TfkDK3ixYmzc1zhHSZwpR7yKJIyKLtUpBTbryt8nyso37AS1yH+dmfh2Fj2WxfBHTg== - -"@nx/nx-darwin-x64@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-17.2.8.tgz#5143d6d01d24e338cb3d39076fe2af95146cb538" - integrity sha512-0cXzp1tGr7/6lJel102QiLA4NkaLCkQJj6VzwbwuvmuCDxPbpmbz7HC1tUteijKBtOcdXit1/MEoEU007To8Bw== - -"@nx/nx-freebsd-x64@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-17.2.8.tgz#82a018a1855170e0243b8fe7b0032af279c3fb83" - integrity sha512-YFMgx5Qpp2btCgvaniDGdu7Ctj56bfFvbbaHQWmOeBPK1krNDp2mqp8HK6ZKOfEuDJGOYAp7HDtCLvdZKvJxzA== - -"@nx/nx-linux-arm-gnueabihf@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-17.2.8.tgz#18b9c324221ff6a30589f3fc272a843aca57b70f" - integrity sha512-iN2my6MrhLRkVDtdivQHugK8YmR7URo1wU9UDuHQ55z3tEcny7LV3W9NSsY9UYPK/FrxdDfevj0r2hgSSdhnzA== - -"@nx/nx-linux-arm64-gnu@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-17.2.8.tgz#54a08640a2babe78bcf3283565b00eb487db595e" - integrity sha512-Iy8BjoW6mOKrSMiTGujUcNdv+xSM1DALTH6y3iLvNDkGbjGK1Re6QNnJAzqcXyDpv32Q4Fc57PmuexyysZxIGg== - -"@nx/nx-linux-arm64-musl@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-17.2.8.tgz#cd7b673bb9f45fec7aa1b6c880a0d23d658e927f" - integrity sha512-9wkAxWzknjpzdofL1xjtU6qPFF1PHlvKCZI3hgEYJDo4mQiatGI+7Ttko+lx/ZMP6v4+Umjtgq7+qWrApeKamQ== - -"@nx/nx-linux-x64-gnu@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-17.2.8.tgz#009eb75c77bf075bc9c13ec4f9caf77821eee639" - integrity sha512-sjG1bwGsjLxToasZ3lShildFsF0eyeGu+pOQZIp9+gjFbeIkd19cTlCnHrOV9hoF364GuKSXQyUlwtFYFR4VTQ== - -"@nx/nx-linux-x64-musl@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-17.2.8.tgz#8ee2324068732a135ca4b01081942d5956885167" - integrity sha512-QiakXZ1xBCIptmkGEouLHQbcM4klQkcr+kEaz2PlNwy/sW3gH1b/1c0Ed5J1AN9xgQxWspriAONpScYBRgxdhA== - -"@nx/nx-win32-arm64-msvc@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-17.2.8.tgz#9bdce5b4d1f9cec7ef326eaf43b99e68576398b0" - integrity sha512-XBWUY/F/GU3vKN9CAxeI15gM4kr3GOBqnzFZzoZC4qJt2hKSSUEWsMgeZtsMgeqEClbi4ZyCCkY7YJgU32WUGA== - -"@nx/nx-win32-x64-msvc@17.2.8": - version "17.2.8" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-17.2.8.tgz#8a86ff250021ad47686b58f1840b348a209b1158" - integrity sha512-HTqDv+JThlLzbcEm/3f+LbS5/wYQWzb5YDXbP1wi7nlCTihNZOLNqGOkEmwlrR5tAdNHPRpHSmkYg4305W0CtA== - "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -2513,13 +2424,13 @@ resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== -"@schematics/angular@17.3.9": - version "17.3.9" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.3.9.tgz#38ad60fea904592ea5d39be6581b22fb16f1baf1" - integrity sha512-q6N8mbcYC6cgPyjTrMH7ehULQoUUwEYN4g7uo4ylZ/PFklSLJvpSp4BuuxANgW449qHSBvQfdIoui9ayAUXQzA== +"@schematics/angular@17.3.10": + version "17.3.10" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.3.10.tgz#87c77ae2eb917f391d654df3c908f4a00d3d9443" + integrity sha512-cI+VB/WXlOeAMamni932lE/AZgui8o81dMyEXNXqCuYagNAMuKXliW79Mi5BwYQEABv/BUb4hB4zYtbQqHyACA== dependencies: - "@angular-devkit/core" "17.3.9" - "@angular-devkit/schematics" "17.3.9" + "@angular-devkit/core" "17.3.10" + "@angular-devkit/schematics" "17.3.10" jsonc-parser "3.2.1" "@schematics/angular@^12.2.17": @@ -2577,11 +2488,6 @@ "@sigstore/core" "^1.1.0" "@sigstore/protobuf-specs" "^0.3.2" -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - "@socket.io/component-emitter@~3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" @@ -3001,14 +2907,6 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/scope-manager@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.19.0.tgz#b6d2abb825b29ab70cb542d220e40c61c1678116" - integrity sha512-dO1XMhV2ehBI6QN8Ufi7I10wmUovmLU0Oru3n5LVlM2JuzB4M+dVphCPLkVpKvGij2j/pHBWuJ9piuXx+BhzxQ== - dependencies: - "@typescript-eslint/types" "6.19.0" - "@typescript-eslint/visitor-keys" "6.19.0" - "@typescript-eslint/scope-manager@6.21.0": version "6.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" @@ -3017,6 +2915,14 @@ "@typescript-eslint/types" "6.21.0" "@typescript-eslint/visitor-keys" "6.21.0" +"@typescript-eslint/scope-manager@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz#cf5619b01de62a226a59add15a02bde457335d1d" + integrity sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw== + dependencies: + "@typescript-eslint/types" "7.11.0" + "@typescript-eslint/visitor-keys" "7.11.0" + "@typescript-eslint/scope-manager@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" @@ -3025,15 +2931,15 @@ "@typescript-eslint/types" "7.18.0" "@typescript-eslint/visitor-keys" "7.18.0" -"@typescript-eslint/type-utils@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.19.0.tgz#522a494ef0d3e9fdc5e23a7c22c9331bbade0101" - integrity sha512-mcvS6WSWbjiSxKCwBcXtOM5pRkPQ6kcDds/juxcy/727IQr3xMEcwr/YLHW2A2+Fp5ql6khjbKBzOyjuPqGi/w== +"@typescript-eslint/type-utils@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz#ac216697d649084fedf4a910347b9642bd0ff099" + integrity sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg== dependencies: - "@typescript-eslint/typescript-estree" "6.19.0" - "@typescript-eslint/utils" "6.19.0" + "@typescript-eslint/typescript-estree" "7.11.0" + "@typescript-eslint/utils" "7.11.0" debug "^4.3.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" "@typescript-eslint/type-utils@7.18.0": version "7.18.0" @@ -3050,16 +2956,16 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/types@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.19.0.tgz#689b0498c436272a6a2059b09f44bcbd90de294a" - integrity sha512-lFviGV/vYhOy3m8BJ/nAKoAyNhInTdXpftonhWle66XHAtT1ouBlkjL496b5H5hb8dWXHwtypTqgtb/DEa+j5A== - "@typescript-eslint/types@6.21.0": version "6.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== +"@typescript-eslint/types@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.11.0.tgz#5e9702a5e8b424b7fc690e338d359939257d6722" + integrity sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w== + "@typescript-eslint/types@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" @@ -3078,20 +2984,6 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.0.tgz#0813ba364a409afb4d62348aec0202600cb468fa" - integrity sha512-o/zefXIbbLBZ8YJ51NlkSAt2BamrK6XOmuxSR3hynMIzzyMY33KuJ9vuMdFSXW+H0tVvdF9qBPTHA91HDb4BIQ== - dependencies: - "@typescript-eslint/types" "6.19.0" - "@typescript-eslint/visitor-keys" "6.19.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - "@typescript-eslint/typescript-estree@6.21.0": version "6.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" @@ -3106,6 +2998,20 @@ semver "^7.5.4" ts-api-utils "^1.0.1" +"@typescript-eslint/typescript-estree@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz#7cbc569bc7336c3a494ceaf8204fdee5d5dbb7fa" + integrity sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ== + dependencies: + "@typescript-eslint/types" "7.11.0" + "@typescript-eslint/visitor-keys" "7.11.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + "@typescript-eslint/typescript-estree@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" @@ -3134,18 +3040,15 @@ eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/utils@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.19.0.tgz#557b72c3eeb4f73bef8037c85dae57b21beb1a4b" - integrity sha512-QR41YXySiuN++/dC9UArYOg4X86OAYP83OWTewpVx5ct1IZhjjgTLocj7QNxGhWoTqknsgpl7L+hGygCO+sdYw== +"@typescript-eslint/utils@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.11.0.tgz#524f047f2209959424c3ef689b0d83b3bc09919c" + integrity sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.19.0" - "@typescript-eslint/types" "6.19.0" - "@typescript-eslint/typescript-estree" "6.19.0" - semver "^7.5.4" + "@typescript-eslint/scope-manager" "7.11.0" + "@typescript-eslint/types" "7.11.0" + "@typescript-eslint/typescript-estree" "7.11.0" "@typescript-eslint/utils@7.18.0", "@typescript-eslint/utils@^7.2.0": version "7.18.0" @@ -3178,14 +3081,6 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.0.tgz#4565e0ecd63ca1f81b96f1dd76e49f746c6b2b49" - integrity sha512-hZaUCORLgubBvtGpp1JEFEazcuEdfxta9j4iUwdSAr7mEsYYAp3EAUyCZk3VEEqGj6W+AV4uWyrDGtrlawAsgQ== - dependencies: - "@typescript-eslint/types" "6.19.0" - eslint-visitor-keys "^3.4.1" - "@typescript-eslint/visitor-keys@6.21.0": version "6.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" @@ -3194,6 +3089,14 @@ "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" +"@typescript-eslint/visitor-keys@7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz#2c50cd292e67645eec05ac0830757071b4a4d597" + integrity sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ== + dependencies: + "@typescript-eslint/types" "7.11.0" + eslint-visitor-keys "^3.4.3" + "@typescript-eslint/visitor-keys@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" @@ -3358,26 +3261,11 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -"@yarnpkg/lockfile@1.1.0", "@yarnpkg/lockfile@^1.1.0": +"@yarnpkg/lockfile@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -"@yarnpkg/parsers@3.0.0-rc.46": - version "3.0.0-rc.46" - resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" - integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== - dependencies: - js-yaml "^3.10.0" - tslib "^2.4.0" - -"@zkochan/js-yaml@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" - integrity sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg== - dependencies: - argparse "^2.0.1" - abbrev@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" @@ -3575,11 +3463,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - ansi-styles@^6.1.0: version "6.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" @@ -3810,7 +3693,7 @@ axe-core@^4.7.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.0.tgz#d9e56ab0147278272739a000880196cdfe113b59" integrity sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g== -axios@^1.5.1, axios@^1.7.4: +axios@^1.7.4: version "1.7.7" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== @@ -3927,7 +3810,7 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -bl@^4.0.3, bl@^4.1.0: +bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -4291,7 +4174,7 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-cursor@3.1.0, cli-cursor@^3.1.0: +cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== @@ -4305,11 +4188,6 @@ cli-progress@^3.12.0: dependencies: string-width "^4.2.3" -cli-spinners@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" - integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== - cli-spinners@^2.5.0: version "2.9.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" @@ -5035,11 +4913,6 @@ di@^0.0.1: resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -5140,17 +5013,7 @@ domutils@^3.0.1: domelementtype "^2.3.0" domhandler "^5.0.3" -dotenv-expand@~10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" - integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== - -dotenv@~16.3.1: - version "16.3.2" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.2.tgz#3cb611ce5a63002dbabf7c281bc331f69d28f03f" - integrity sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ== - -duplexer@^0.1.1, duplexer@^0.1.2: +duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== @@ -5187,7 +5050,7 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -ejs@^3.1.10, ejs@^3.1.7: +ejs@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== @@ -5238,7 +5101,7 @@ encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -5293,13 +5156,6 @@ enquirer@^2.3.6: ansi-colors "^4.1.1" strip-ansi "^6.0.1" -enquirer@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - ent@~2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.1.tgz#68dc99a002f115792c26239baedaaea9e70c0ca2" @@ -6020,7 +5876,7 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -figures@3.2.0, figures@^3.2.0: +figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -6210,11 +6066,6 @@ fresh@0.5.2, fresh@^0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - fs-extra@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" @@ -6224,15 +6075,6 @@ fs-extra@3.0.1: jsonfile "^3.0.0" universalify "^0.1.0" -fs-extra@^11.1.0: - version "11.2.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" - integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -6386,18 +6228,6 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^10.2.2, glob@^10.3.10: version "10.4.5" resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" @@ -6814,12 +6644,12 @@ ignore-walk@^6.0.4: dependencies: minimatch "^9.0.0" -ignore@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" - integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== +ignore@5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== -ignore@^5.0.4, ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: +ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== @@ -7372,21 +7202,6 @@ jasmine@^3.8.0: glob "^7.1.6" jasmine-core "~3.99.0" -jest-diff@^29.4.1: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - jest-worker@^27.4.5: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" @@ -7411,14 +7226,7 @@ js-cookie@2.2.1: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.10.0, js-yaml@^3.13.1: +js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -7426,6 +7234,13 @@ js-yaml@^3.10.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbn@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" @@ -7518,11 +7333,6 @@ jsonc-parser@3.0.0: resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== -jsonc-parser@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - jsonc-parser@3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" @@ -7837,11 +7647,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -lines-and-columns@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" - integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== - linkify-it@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" @@ -8179,13 +7984,6 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" - integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== - dependencies: - brace-expansion "^1.1.7" - minimatch@9.0.3: version "9.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" @@ -8534,11 +8332,6 @@ node-gyp@^10.0.0: tar "^6.2.1" which "^4.0.0" -node-machine-id@1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" - integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== - node-releases@^2.0.18: version "2.0.18" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" @@ -8690,57 +8483,6 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -nx@17.2.8: - version "17.2.8" - resolved "https://registry.yarnpkg.com/nx/-/nx-17.2.8.tgz#09482acd5d9b64c115d5ccf12417f1af2787d4d1" - integrity sha512-rM5zXbuXLEuqQqcjVjClyvHwRJwt+NVImR2A6KFNG40Z60HP6X12wAxxeLHF5kXXTDRU0PFhf/yACibrpbPrAw== - dependencies: - "@nrwl/tao" "17.2.8" - "@yarnpkg/lockfile" "^1.1.0" - "@yarnpkg/parsers" "3.0.0-rc.46" - "@zkochan/js-yaml" "0.0.6" - axios "^1.5.1" - chalk "^4.1.0" - cli-cursor "3.1.0" - cli-spinners "2.6.1" - cliui "^8.0.1" - dotenv "~16.3.1" - dotenv-expand "~10.0.0" - enquirer "~2.3.6" - figures "3.2.0" - flat "^5.0.2" - fs-extra "^11.1.0" - glob "7.1.4" - ignore "^5.0.4" - jest-diff "^29.4.1" - js-yaml "4.1.0" - jsonc-parser "3.2.0" - lines-and-columns "~2.0.3" - minimatch "3.0.5" - node-machine-id "1.1.12" - npm-run-path "^4.0.1" - open "^8.4.0" - semver "7.5.3" - string-width "^4.2.3" - strong-log-transformer "^2.1.0" - tar-stream "~2.2.0" - tmp "~0.2.1" - tsconfig-paths "^4.1.2" - tslib "^2.3.0" - yargs "^17.6.2" - yargs-parser "21.1.1" - optionalDependencies: - "@nx/nx-darwin-arm64" "17.2.8" - "@nx/nx-darwin-x64" "17.2.8" - "@nx/nx-freebsd-x64" "17.2.8" - "@nx/nx-linux-arm-gnueabihf" "17.2.8" - "@nx/nx-linux-arm64-gnu" "17.2.8" - "@nx/nx-linux-arm64-musl" "17.2.8" - "@nx/nx-linux-x64-gnu" "17.2.8" - "@nx/nx-linux-x64-musl" "17.2.8" - "@nx/nx-win32-arm64-msvc" "17.2.8" - "@nx/nx-win32-x64-msvc" "17.2.8" - oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -8837,7 +8579,7 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -open@8.4.2, open@^8.0.9, open@^8.4.0: +open@8.4.2, open@^8.0.9: version "8.4.2" resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== @@ -9587,15 +9329,6 @@ pretty-bytes@^5.6.0: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== -pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - proc-log@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" @@ -9884,11 +9617,6 @@ react-is@^16.13.1, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" - integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== - react-mosaic-component@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/react-mosaic-component/-/react-mosaic-component-4.1.1.tgz#48a34e5e5c16654075212666c2aebeb488bab9f2" @@ -10010,7 +9738,7 @@ readable-stream@^2.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0: +readable-stream@^3.0.6, readable-stream@^3.4.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -10268,7 +9996,7 @@ rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.6.3: dependencies: glob "^7.1.3" -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -10525,13 +10253,6 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== -semver@7.5.3: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== - dependencies: - lru-cache "^6.0.0" - semver@7.6.0: version "7.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" @@ -11140,15 +10861,6 @@ strip-json-comments@3.1.1, strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strong-log-transformer@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" - integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== - dependencies: - duplexer "^0.1.1" - minimist "^1.2.0" - through "^2.3.4" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -11197,17 +10909,6 @@ tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar-stream@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - tar@^6.0.2, tar@^6.1.11, tar@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" @@ -11275,7 +10976,7 @@ throttleit@^1.0.0: resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.1.tgz#304ec51631c3b770c65c6c6f76938b384000f4d5" integrity sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ== -through@^2.3.4, through@^2.3.8: +through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== @@ -11295,12 +10996,10 @@ tiny-warning@^1.0.2: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== -tmp@0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" +tmp@0.2.3, tmp@^0.2.1, tmp@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== tmp@^0.0.33: version "0.0.33" @@ -11309,11 +11008,6 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmp@^0.2.1, tmp@~0.2.1, tmp@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" - integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -11418,7 +11112,7 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tsconfig-paths@^4.1.0, tsconfig-paths@^4.1.2: +tsconfig-paths@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== @@ -11437,7 +11131,7 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0: +tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1: version "2.7.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== @@ -11782,10 +11476,10 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vite@5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.7.tgz#9f685a2c4c70707fef6d37341b0e809c366da619" - integrity sha512-sgnEEFTZYMui/sTlH1/XEnVNHMujOahPLGMxn1+5sIT45Xjng1Ec1K78jRP15dSmVgg5WBin9yO81j3o9OxofA== +vite@5.1.8: + version "5.1.8" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.8.tgz#f728feda90c3f30b0ab530c0981e5aa7745b8aee" + integrity sha512-mB8ToUuSmzODSpENgvpFk2fTiU/YQ1tmcVJJ4WZbq4fPdGJkFNVcmVL5k7iDug6xzWjjuGDKAuSievIsD6H7Xw== dependencies: esbuild "^0.19.3" postcss "^8.4.35" @@ -12223,17 +11917,17 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@21.1.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs@17.7.2, yargs@^17.0.0, yargs@^17.2.1, yargs@^17.3.1, yargs@^17.6.2: +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@17.7.2, yargs@^17.0.0, yargs@^17.2.1, yargs@^17.3.1: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== From e6ce7512790384d7f737061c66f32ad9c6b15160 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 13:57:36 +0000 Subject: [PATCH 181/822] Bump @types/lodash from 4.17.7 to 4.17.10 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.7 to 4.17.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ad82a8fcd0f..c848a14e2e4 100644 --- a/package.json +++ b/package.json @@ -159,7 +159,7 @@ "@types/express": "^4.17.17", "@types/jasmine": "~3.6.0", "@types/js-cookie": "2.2.6", - "@types/lodash": "^4.14.194", + "@types/lodash": "^4.17.10", "@types/node": "^14.14.9", "@types/sanitize-html": "^2.9.0", "@typescript-eslint/eslint-plugin": "^7.2.0", diff --git a/yarn.lock b/yarn.lock index 3888a2384ed..87236afd2c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2785,10 +2785,10 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/lodash@^4.14.194": - version "4.17.7" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.7.tgz#2f776bcb53adc9e13b2c0dfd493dfcbd7de43612" - integrity sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA== +"@types/lodash@^4.17.10": + version "4.17.10" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.10.tgz#64f3edf656af2fe59e7278b73d3e62404144a6e6" + integrity sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ== "@types/mime@^1": version "1.3.5" From 3352a966f3c6d727ed250259c0c78d32d05659e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 13:57:49 +0000 Subject: [PATCH 182/822] Bump @types/deep-freeze from 0.1.2 to 0.1.5 Bumps [@types/deep-freeze](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/deep-freeze) from 0.1.2 to 0.1.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/deep-freeze) --- updated-dependencies: - dependency-name: "@types/deep-freeze" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ad82a8fcd0f..279cab3fc21 100644 --- a/package.json +++ b/package.json @@ -154,7 +154,7 @@ "@fortawesome/fontawesome-free": "^6.4.0", "@ngrx/store-devtools": "^17.1.1", "@ngtools/webpack": "^16.2.12", - "@types/deep-freeze": "0.1.2", + "@types/deep-freeze": "0.1.5", "@types/ejs": "^3.1.2", "@types/express": "^4.17.17", "@types/jasmine": "~3.6.0", diff --git a/yarn.lock b/yarn.lock index 3888a2384ed..926db0ca4b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2700,10 +2700,10 @@ dependencies: "@types/node" "*" -"@types/deep-freeze@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@types/deep-freeze/-/deep-freeze-0.1.2.tgz#68e5379291910e82c2f0d1629732163c2aa662cc" - integrity sha512-M6x29Vk4681dght4IMnPIcF1SNmeEm0c4uatlTFhp+++H1oDK1THEIzuCC2WeCBVhX+gU0NndsseDS3zaCtlcQ== +"@types/deep-freeze@0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@types/deep-freeze/-/deep-freeze-0.1.5.tgz#ae94f37ca134b4e34facb55f52ed90921192f764" + integrity sha512-KZtR+jtmgkCpgE0f+We/QEI2Fi0towBV/tTkvHVhMzx+qhUVGXMx7pWvAtDp6vEWIjdKLTKpqbI/sORRCo8TKg== "@types/ejs@^3.1.2": version "3.1.5" From 1321b7b8a950340f1aa2edbd30d3229d784bf2d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 13:59:10 +0000 Subject: [PATCH 183/822] Bump reflect-metadata from 0.1.14 to 0.2.2 Bumps [reflect-metadata](https://github.com/rbuckton/reflect-metadata) from 0.1.14 to 0.2.2. - [Release notes](https://github.com/rbuckton/reflect-metadata/releases) - [Changelog](https://github.com/rbuckton/reflect-metadata/blob/main/tsconfig-release.json) - [Commits](https://github.com/rbuckton/reflect-metadata/commits) --- updated-dependencies: - dependency-name: reflect-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index ad82a8fcd0f..1460ec17f3a 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "pem": "1.14.7", "prop-types": "^15.8.1", "react-copy-to-clipboard": "^5.1.0", - "reflect-metadata": "^0.1.13", + "reflect-metadata": "^0.2.2", "rxjs": "^7.8.0", "sanitize-html": "^2.12.1", "sortablejs": "1.15.0", diff --git a/yarn.lock b/yarn.lock index 3888a2384ed..9a55237ed5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10057,12 +10057,7 @@ redux@^4.0.0, redux@^4.0.4, redux@^4.0.5: dependencies: "@babel/runtime" "^7.9.2" -reflect-metadata@^0.1.13: - version "0.1.14" - resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.14.tgz#24cf721fe60677146bb77eeb0e1f9dece3d65859" - integrity sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A== - -reflect-metadata@^0.2.0: +reflect-metadata@^0.2.0, reflect-metadata@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== From 8c88f7052a65bbabde3a19223e967feddb186008 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 16 Oct 2024 14:15:11 -0500 Subject: [PATCH 184/822] Wait on viewevent to trigger before checking Collection Page in e2e tests. This ensures Collection page is fully loaded because viewevent triggers upon loading. --- cypress/e2e/collection-page.cy.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cypress/e2e/collection-page.cy.ts b/cypress/e2e/collection-page.cy.ts index d12536d332a..373da078888 100644 --- a/cypress/e2e/collection-page.cy.ts +++ b/cypress/e2e/collection-page.cy.ts @@ -3,8 +3,15 @@ import { testA11y } from 'cypress/support/utils'; describe('Collection Page', () => { it('should pass accessibility tests', () => { + cy.intercept('POST', '/server/api/statistics/viewevents').as('viewevent'); + + // Visit Collections page cy.visit('/collections/'.concat(Cypress.env('DSPACE_TEST_COLLECTION'))); + // Wait for the "viewevent" to trigger on the Collection page. + // This ensures our tag is fully loaded, as the tag is contained within it. + cy.wait('@viewevent'); + // tag must be loaded cy.get('ds-collection-page').should('be.visible'); From dfe2d4580ebcd305080a67cd44283286b5dda0ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 21:43:58 +0000 Subject: [PATCH 185/822] Bump nouislider from 15.7.1 to 15.8.1 Bumps [nouislider](https://github.com/leongersen/noUiSlider) from 15.7.1 to 15.8.1. - [Release notes](https://github.com/leongersen/noUiSlider/releases) - [Changelog](https://github.com/leongersen/noUiSlider/blob/master/CHANGELOG.MD) - [Commits](https://github.com/leongersen/noUiSlider/compare/15.7.1...15.8.1) --- updated-dependencies: - dependency-name: nouislider dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cb8456501ac..ba2dbd1c626 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "ngx-pagination": "6.0.3", "ngx-sortablejs": "^11.1.0", "ngx-ui-switch": "^14.1.0", - "nouislider": "^15.7.1", + "nouislider": "^15.8.1", "pem": "1.14.7", "prop-types": "^15.8.1", "react-copy-to-clipboard": "^5.1.0", diff --git a/yarn.lock b/yarn.lock index 26f50cb912a..b584dd51813 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8644,10 +8644,10 @@ normalize-url@^4.5.0: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== -nouislider@^15.7.1: - version "15.7.1" - resolved "https://registry.yarnpkg.com/nouislider/-/nouislider-15.7.1.tgz#77d55e47d9b4cd771728515713df43b489db9705" - integrity sha512-5N7C1ru/i8y3dg9+Z6ilj6+m1EfabvOoaRa7ztpxBSKKRZso4vA52DGSbBJjw5XLtFr/LZ9SgGAXqyVtlVHO5w== +nouislider@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/nouislider/-/nouislider-15.8.1.tgz#18729ed29738d2d328a1b5e0429d38eb8be8a696" + integrity sha512-93TweAi8kqntHJSPiSWQ1o/uZ29VWOmal9YKb6KKGGlCkugaNfAupT7o1qTHqdJvNQ7S0su5rO6qRFCjP8fxtw== npm-bundled@^3.0.0: version "3.0.0" From ad8dd8b648d3cdbb3d3ce61f652051ce3d6c4a3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 21:45:45 +0000 Subject: [PATCH 186/822] Bump core-js from 3.30.1 to 3.38.1 Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.30.1 to 3.38.1. - [Release notes](https://github.com/zloirock/core-js/releases) - [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/zloirock/core-js/commits/v3.38.1/packages/core-js) --- updated-dependencies: - dependency-name: core-js dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cb8456501ac..1a866c29093 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "colors": "^1.4.0", "compression": "^1.7.4", "cookie-parser": "1.4.7", - "core-js": "^3.30.1", + "core-js": "^3.38.1", "date-fns": "^2.29.3", "date-fns-tz": "^1.3.7", "deepmerge": "^4.3.1", diff --git a/yarn.lock b/yarn.lock index 26f50cb912a..c12d67a67f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4413,10 +4413,10 @@ core-js-compat@^3.25.1: dependencies: browserslist "^4.21.5" -core-js@^3.30.1: - version "3.30.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.30.1.tgz#fc9c5adcc541d8e9fa3e381179433cbf795628ba" - integrity sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ== +core-js@^3.38.1: + version "3.38.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e" + integrity sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw== core-util-is@1.0.2: version "1.0.2" From e181e854cc6d911021500fac7c8321592077a212 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 21:47:00 +0000 Subject: [PATCH 187/822] Bump @types/node from 14.18.42 to 14.18.63 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.18.42 to 14.18.63. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cb8456501ac..8418678f906 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "@types/jasmine": "~3.6.0", "@types/js-cookie": "2.2.6", "@types/lodash": "^4.14.194", - "@types/node": "^14.14.9", + "@types/node": "^14.18.63", "@types/sanitize-html": "^2.9.0", "@typescript-eslint/eslint-plugin": "^5.59.1", "@typescript-eslint/parser": "^5.59.1", diff --git a/yarn.lock b/yarn.lock index 26f50cb912a..0883a4816fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2593,10 +2593,10 @@ resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz" integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== -"@types/node@*", "@types/node@>=10.0.0", "@types/node@^14.14.9": - version "14.18.42" - resolved "https://registry.npmjs.org/@types/node/-/node-14.18.42.tgz" - integrity sha512-xefu+RBie4xWlK8hwAzGh3npDz/4VhF6icY/shU+zv/1fNn+ZVG7T7CRwe9LId9sAYRPxI+59QBPuKL3WpyGRg== +"@types/node@*", "@types/node@>=10.0.0", "@types/node@^14.18.63": + version "14.18.63" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.63.tgz#1788fa8da838dbb5f9ea994b834278205db6ca2b" + integrity sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ== "@types/parse-json@^4.0.0": version "4.0.0" From d674bcc3908c4cf8469853778fc167295320a51c Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Mon, 16 Sep 2024 15:47:42 +0200 Subject: [PATCH 188/822] 118220: Integrate live-region component into item-edit-bitsream page --- .../item-edit-bitstream-bundle.component.html | 2 +- .../item-edit-bitstream-bundle.component.ts | 21 ++++++++++++------- src/assets/i18n/en.json5 | 4 ++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index 0338055df51..d530fb38d18 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -68,7 +68,7 @@
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index bd99fc1a09a..24319f4a834 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -30,6 +30,8 @@ import { RequestService } from '../../../../core/data/request.service'; import { ItemBitstreamsService } from '../item-bitstreams.service'; import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { hasValue } from '../../../../shared/empty.util'; +import { LiveRegionService } from '../../../../shared/live-region/live-region.service'; +import { TranslateService } from '@ngx-translate/core'; /** * Interface storing all the information necessary to create a row in the bitstream edit table @@ -166,11 +168,6 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ pageSize$: BehaviorSubject; - /** - * Whether the table has multiple pages - */ - hasMultiplePages = false; - /** * The self url of the bundle, also used when retrieving fieldUpdates */ @@ -190,6 +187,8 @@ export class ItemEditBitstreamBundleComponent implements OnInit { protected paginationService: PaginationService, protected requestService: RequestService, protected itemBitstreamsService: ItemBitstreamsService, + protected liveRegionService: LiveRegionService, + protected translateService: TranslateService, ) { } @@ -301,7 +300,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.paginationComponent.doPageSizeChange(pageSize); } - dragStart() { + dragStart(bitstreamName: string) { // Only open the drag tooltip when there are multiple pages this.paginationComponent.shouldShowBottomPager.pipe( take(1), @@ -309,10 +308,18 @@ export class ItemEditBitstreamBundleComponent implements OnInit { ).subscribe(() => { this.dragTooltip.open(); }); + + const message = this.translateService.instant('item.edit.bitstreams.edit.live.drag', + { bitstream: bitstreamName }); + this.liveRegionService.addMessage(message); } - dragEnd() { + dragEnd(bitstreamName: string) { this.dragTooltip.close(); + + const message = this.translateService.instant('item.edit.bitstreams.edit.live.drop', + { bitstream: bitstreamName }); + this.liveRegionService.addMessage(message); } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index f2dbf9b2d1c..48fd581bdf4 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1950,6 +1950,10 @@ "item.edit.bitstreams.edit.buttons.undo": "Undo changes", + "item.edit.bitstreams.edit.live.drag": "{{ bitstream }} grabbed", + + "item.edit.bitstreams.edit.live.drop": "{{ bitstream }} dropped", + "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", "item.edit.bitstreams.headers.actions": "Actions", From 1f909dc6ea0d84859fbeef690c9bd212417c7a99 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 17 Sep 2024 13:34:08 +0200 Subject: [PATCH 189/822] 118223: Add instructive alert to item-bitstreams edit page --- .../item-bitstreams/item-bitstreams.component.html | 7 ++++++- .../item-bitstreams/item-bitstreams.component.ts | 4 ++++ src/assets/i18n/en.json5 | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index 3527f2f5b8c..1c13154bfab 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -1,4 +1,8 @@
+
+ +
+
Date: Wed, 18 Sep 2024 11:57:41 +0200 Subject: [PATCH 190/822] 118223: Implement bitstream reordering with keyboard --- .../item-bitstreams.component.html | 1 - .../item-bitstreams.component.spec.ts | 43 +- .../item-bitstreams.component.ts | 87 ++-- .../item-bitstreams.service.spec.ts | 19 + .../item-bitstreams.service.ts | 303 ++++++++++++- .../item-edit-bitstream-bundle.component.html | 33 +- ...em-edit-bitstream-bundle.component.spec.ts | 1 + .../item-edit-bitstream-bundle.component.ts | 405 ++++++++++++------ .../live-region/live-region.service.stub.ts | 30 ++ src/assets/i18n/en.json5 | 8 +- 10 files changed, 727 insertions(+), 203 deletions(-) create mode 100644 src/app/shared/live-region/live-region.service.stub.ts diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index 1c13154bfab..b9af2a7d18c 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -33,7 +33,6 @@ [item]="item" [columnSizes]="columnSizes" [isFirstTable]="isFirst" - (dropObject)="dropBitstream(bundle, $event)" aria-describedby="reorder-description">
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts index 6ce73944739..a5549a6ba0a 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts @@ -25,6 +25,10 @@ import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } f import { createPaginatedList } from '../../../shared/testing/utils.test'; import { FieldChangeType } from '../../../core/data/object-updates/field-change-type.model'; import { BitstreamDataServiceStub } from '../../../shared/testing/bitstream-data-service.stub'; +import { ItemBitstreamsService } from './item-bitstreams.service'; +import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes'; +import { ResponsiveColumnSizes } from '../../../shared/responsive-table-sizes/responsive-column-sizes'; +import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; let comp: ItemBitstreamsComponent; let fixture: ComponentFixture; @@ -76,6 +80,7 @@ let objectCache: ObjectCacheService; let requestService: RequestService; let searchConfig: SearchConfigurationService; let bundleService: BundleDataService; +let itemBitstreamsService: ItemBitstreamsService; describe('ItemBitstreamsComponent', () => { beforeEach(waitForAsync(() => { @@ -147,6 +152,19 @@ describe('ItemBitstreamsComponent', () => { patch: createSuccessfulRemoteDataObject$({}), }); + itemBitstreamsService = jasmine.createSpyObj('itemBitstreamsService', { + getColumnSizes: new ResponsiveTableSizes([ + new ResponsiveColumnSizes(2, 2, 3, 4, 4), + new ResponsiveColumnSizes(2, 3, 3, 3, 3), + new ResponsiveColumnSizes(2, 2, 2, 2, 2), + new ResponsiveColumnSizes(6, 5, 4, 3, 3) + ]), + getSelectedBitstream$: observableOf({}), + getInitialBundlesPaginationOptions: new PaginationComponentOptions(), + removeMarkedBitstreams: createSuccessfulRemoteDataObject$({}), + displayNotifications: undefined, + }); + TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], declarations: [ItemBitstreamsComponent, ObjectValuesPipe, VarDirective], @@ -161,6 +179,7 @@ describe('ItemBitstreamsComponent', () => { { provide: RequestService, useValue: requestService }, { provide: SearchConfigurationService, useValue: searchConfig }, { provide: BundleDataService, useValue: bundleService }, + { provide: ItemBitstreamsService, useValue: itemBitstreamsService }, ChangeDetectorRef ], schemas: [ NO_ERRORS_SCHEMA @@ -181,28 +200,8 @@ describe('ItemBitstreamsComponent', () => { comp.submit(); }); - it('should call removeMultiple on the bitstreamService for the marked field', () => { - expect(bitstreamService.removeMultiple).toHaveBeenCalledWith([bitstream2]); - }); - - it('should not call removeMultiple on the bitstreamService for the unmarked field', () => { - expect(bitstreamService.removeMultiple).not.toHaveBeenCalledWith([bitstream1]); - }); - }); - - describe('when dropBitstream is called', () => { - beforeEach((done) => { - comp.dropBitstream(bundle, { - fromIndex: 0, - toIndex: 50, - finish: () => { - done(); - } - }); - }); - - it('should send out a patch for the move operation', () => { - expect(bundleService.patch).toHaveBeenCalled(); + it('should call removeMarkedBitstreams on the itemBitstreamsService', () => { + expect(itemBitstreamsService.removeMarkedBitstreams).toHaveBeenCalled(); }); }); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts index 7757170f4ed..4ced3dd6497 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, NgZone, OnDestroy } from '@angular/core'; +import { ChangeDetectorRef, Component, NgZone, OnDestroy, HostListener } from '@angular/core'; import { AbstractItemUpdateComponent } from '../abstract-item-update/abstract-item-update.component'; import { map, switchMap, take } from 'rxjs/operators'; import { Observable, Subscription, zip as observableZip } from 'rxjs'; @@ -8,13 +8,11 @@ import { ActivatedRoute, Router } from '@angular/router'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { BitstreamDataService } from '../../../core/data/bitstream-data.service'; -import { hasValue } from '../../../shared/empty.util'; import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { RequestService } from '../../../core/data/request.service'; import { getFirstSucceededRemoteData, getRemoteDataPayload, - getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; @@ -23,7 +21,6 @@ import { BundleDataService } from '../../../core/data/bundle-data.service'; import { PaginatedSearchOptions } from '../../../shared/search/models/paginated-search-options.model'; import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes'; import { NoContent } from '../../../core/shared/NoContent.model'; -import { Operation } from 'fast-json-patch'; import { ItemBitstreamsService } from './item-bitstreams.service'; import { AlertType } from '../../../shared/alert/aletr-type'; @@ -88,13 +85,63 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme postItemInit(): void { const bundlesOptions = this.itemBitstreamsService.getInitialBundlesPaginationOptions(); - this. bundles$ = this.itemService.getBundles(this.item.id, new PaginatedSearchOptions({pagination: bundlesOptions})).pipe( + this.bundles$ = this.itemService.getBundles(this.item.id, new PaginatedSearchOptions({pagination: bundlesOptions})).pipe( getFirstSucceededRemoteData(), getRemoteDataPayload(), map((bundlePage: PaginatedList) => bundlePage.page) ); } + /** + * Handles keyboard events that should move the currently selected bitstream up + */ + @HostListener('document:keydown.arrowUp', ['$event']) + moveUp(event: KeyboardEvent) { + if (this.itemBitstreamsService.hasSelectedBitstream()) { + event.preventDefault(); + this.itemBitstreamsService.moveSelectedBitstreamUp(); + } + } + + /** + * Handles keyboard events that should move the currently selected bitstream down + */ + @HostListener('document:keydown.arrowDown', ['$event']) + moveDown(event: KeyboardEvent) { + if (this.itemBitstreamsService.hasSelectedBitstream()) { + event.preventDefault(); + this.itemBitstreamsService.moveSelectedBitstreamDown(); + } + } + + /** + * Handles keyboard events that should cancel the currently selected bitstream. + * A cancel means that the selected bitstream is returned to its original position and is no longer selected. + * @param event + */ + @HostListener('document:keyup.escape', ['$event']) + cancelSelection(event: KeyboardEvent) { + if (this.itemBitstreamsService.hasSelectedBitstream()) { + event.preventDefault(); + this.itemBitstreamsService.cancelSelection(); + } + } + + /** + * Handles keyboard events that should clear the currently selected bitstream. + * A clear means that the selected bitstream remains in its current position but is no longer selected. + */ + @HostListener('document:keydown.enter', ['$event']) + @HostListener('document:keydown.space', ['$event']) + clearSelection(event: KeyboardEvent) { + // Only when no specific element is in focus do we want to clear the currently selected bitstream + // Otherwise we might clear the selection when a different action was intended, e.g. clicking a button or selecting + // a different bitstream. + if (event.target instanceof Element && event.target.tagName === 'BODY') { + this.itemBitstreamsService.clearSelection(); + } + } + /** * Initialize the notification messages prefix */ @@ -120,36 +167,6 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme }); } - /** - * A bitstream was dropped in a new location. Send out a Move Patch request to the REST API, display notifications, - * refresh the bundle's cache (so the lists can properly reload) and call the event's callback function (which will - * navigate the user to the correct page) - * @param bundle The bundle to send patch requests to - * @param event The event containing the index the bitstream came from and was dropped to - */ - dropBitstream(bundle: Bundle, event: any) { - this.zone.runOutsideAngular(() => { - if (hasValue(event) && hasValue(event.fromIndex) && hasValue(event.toIndex) && hasValue(event.finish)) { - const moveOperation = { - op: 'move', - from: `/_links/bitstreams/${event.fromIndex}/href`, - path: `/_links/bitstreams/${event.toIndex}/href` - } as Operation; - this.bundleService.patch(bundle, [moveOperation]).pipe( - getFirstCompletedRemoteData(), - ).subscribe((response: RemoteData) => { - this.zone.run(() => { - this.itemBitstreamsService.displayNotifications('item.edit.bitstreams.notifications.move', [response]); - // Remove all cached requests from this bundle and call the event's callback when the requests are cleared - this.requestService.setStaleByHrefSubstring(bundle.self).pipe( - take(1) - ).subscribe(() => event.finish()); - }); - }); - } - }); - } - /** * Request the object updates service to discard all current changes to this item * Shows a notification to remind the user that they can undo this diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts index 89ecfb518f9..e144e81ec7e 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts @@ -16,6 +16,12 @@ import { createFailedRemoteDataObject, createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils'; +import { BundleDataService } from '../../../core/data/bundle-data.service'; +import { RequestService } from '../../../core/data/request.service'; +import { LiveRegionService } from '../../../shared/live-region/live-region.service'; +import { Bundle } from '../../../core/shared/bundle.model'; +import { of } from 'rxjs'; +import { getLiveRegionServiceStub } from '../../../shared/live-region/live-region.service.stub'; describe('ItemBitstreamsService', () => { let service: ItemBitstreamsService; @@ -23,21 +29,34 @@ describe('ItemBitstreamsService', () => { let translateService: TranslateService; let objectUpdatesService: ObjectUpdatesService; let bitstreamDataService: BitstreamDataService; + let bundleDataService: BundleDataService; let dsoNameService: DSONameService; + let requestService: RequestService; + let liveRegionService: LiveRegionService; beforeEach(() => { notificationsService = new NotificationsServiceStub() as any; translateService = getMockTranslateService(); objectUpdatesService = new ObjectUpdatesServiceStub() as any; bitstreamDataService = new BitstreamDataServiceStub() as any; + bundleDataService = jasmine.createSpyObj('bundleDataService', { + patch: createSuccessfulRemoteDataObject$(new Bundle()), + }); dsoNameService = new DSONameServiceMock() as any; + requestService = jasmine.createSpyObj('requestService', { + setStaleByHrefSubstring: of(true), + }); + liveRegionService = getLiveRegionServiceStub(); service = new ItemBitstreamsService( notificationsService, translateService, objectUpdatesService, bitstreamDataService, + bundleDataService, dsoNameService, + requestService, + liveRegionService, ); }); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts index 487df77b28e..21dc4151987 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts @@ -3,38 +3,277 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes'; import { ResponsiveColumnSizes } from '../../../shared/responsive-table-sizes/responsive-column-sizes'; import { RemoteData } from '../../../core/data/remote-data'; -import { isNotEmpty, hasValue } from '../../../shared/empty.util'; +import { isNotEmpty, hasValue, hasNoValue } from '../../../shared/empty.util'; import { Bundle } from '../../../core/shared/bundle.model'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; -import { Observable, zip as observableZip } from 'rxjs'; +import { Observable, zip as observableZip, BehaviorSubject } from 'rxjs'; import { NoContent } from '../../../core/shared/NoContent.model'; -import { take, switchMap, map } from 'rxjs/operators'; +import { take, switchMap, map, tap } from 'rxjs/operators'; import { FieldUpdates } from '../../../core/data/object-updates/field-updates.model'; import { FieldUpdate } from '../../../core/data/object-updates/field-update.model'; import { FieldChangeType } from '../../../core/data/object-updates/field-change-type.model'; import { Bitstream } from '../../../core/shared/bitstream.model'; import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; import { BitstreamDataService } from '../../../core/data/bitstream-data.service'; -import { BitstreamTableEntry } from './item-edit-bitstream-bundle/item-edit-bitstream-bundle.component'; -import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators'; +import { getFirstSucceededRemoteDataPayload, getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { getBitstreamDownloadRoute } from '../../../app-routing-paths'; import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; +import { BitstreamFormat } from '../../../core/shared/bitstream-format.model'; +import { MoveOperation } from 'fast-json-patch'; +import { BundleDataService } from '../../../core/data/bundle-data.service'; +import { RequestService } from '../../../core/data/request.service'; +import { LiveRegionService } from '../../../shared/live-region/live-region.service'; +/** + * Interface storing all the information necessary to create a row in the bitstream edit table + */ +export interface BitstreamTableEntry { + /** + * The bitstream + */ + bitstream: Bitstream, + /** + * The uuid of the Bitstream + */ + id: string, + /** + * The name of the Bitstream + */ + name: string, + /** + * The name of the Bitstream with all whitespace removed + */ + nameStripped: string, + /** + * The description of the Bitstream + */ + description: string, + /** + * Observable emitting the Format of the Bitstream + */ + format: Observable, + /** + * The download url of the Bitstream + */ + downloadUrl: string, +} + +/** + * Interface storing information necessary to highlight and reorder the selected bitstream entry + */ +export interface SelectedBitstreamTableEntry { + /** + * The selected entry + */ + bitstream: BitstreamTableEntry, + /** + * The bundle the bitstream belongs to + */ + bundle: Bundle, + /** + * The total number of bitstreams in the bundle + */ + bundleSize: number, + /** + * The original position of the bitstream within the bundle. + */ + originalPosition: number, + /** + * The current position of the bitstream within the bundle. + */ + currentPosition: number, +} + +/** + * This service handles the selection and updating of the bitstreams and their order on the + * 'Edit Item' -> 'Bitstreams' page. + */ @Injectable( { providedIn: 'root' }, ) export class ItemBitstreamsService { + /** + * BehaviorSubject which emits every time the selected bitstream changes. + */ + protected selectedBitstream$: BehaviorSubject = new BehaviorSubject(null); + + protected isPerformingMoveRequest = false; + constructor( protected notificationsService: NotificationsService, protected translateService: TranslateService, protected objectUpdatesService: ObjectUpdatesService, protected bitstreamService: BitstreamDataService, + protected bundleService: BundleDataService, protected dsoNameService: DSONameService, + protected requestService: RequestService, + protected liveRegionService: LiveRegionService, ) { } + /** + * Returns the observable emitting the currently selected bitstream + */ + getSelectedBitstream$(): Observable { + return this.selectedBitstream$; + } + + /** + * Returns a copy of the currently selected bitstream + */ + getSelectedBitstream(): SelectedBitstreamTableEntry { + const selected = this.selectedBitstream$.getValue(); + + if (hasNoValue(selected)) { + return selected; + } + + return Object.assign({}, selected); + } + + hasSelectedBitstream(): boolean { + return hasValue(this.getSelectedBitstream()); + } + + /** + * Select the provided entry + */ + selectBitstreamEntry(entry: SelectedBitstreamTableEntry) { + if (entry !== this.selectedBitstream$.getValue()) { + this.announceSelect(entry.bitstream.name); + this.updateSelectedBitstream(entry); + } + } + + /** + * Makes the {@link selectedBitstream$} observable emit the provided {@link SelectedBitstreamTableEntry}. + * @protected + */ + protected updateSelectedBitstream(entry: SelectedBitstreamTableEntry) { + this.selectedBitstream$.next(entry); + } + + /** + * Unselects the selected bitstream. Does nothing if no bitstream is selected. + */ + clearSelection() { + const selected = this.getSelectedBitstream(); + + if (hasValue(selected)) { + this.updateSelectedBitstream(null); + this.announceClear(selected.bitstream.name); + } + } + + /** + * Returns the currently selected bitstream to its original position and unselects the bitstream. + * Does nothing if no bitstream is selected. + */ + cancelSelection() { + const selected = this.getSelectedBitstream(); + + if (hasNoValue(selected) || this.isPerformingMoveRequest) { + return; + } + + this.selectedBitstream$.next(null); + + const originalPosition = selected.originalPosition; + const currentPosition = selected.currentPosition; + + // If the selected bitstream has not moved, there is no need to return it to its original position + if (currentPosition === originalPosition) { + this.announceClear(selected.bitstream.name); + } else { + this.announceCancel(selected.bitstream.name, originalPosition); + this.performBitstreamMoveRequest(selected.bundle, currentPosition, originalPosition); + } + } + + /** + * Moves the selected bitstream one position up in the bundle. Does nothing if no bitstream is selected or the + * selected bitstream already is at the beginning of the bundle. + */ + moveSelectedBitstreamUp() { + const selected = this.getSelectedBitstream(); + + if (hasNoValue(selected) || this.isPerformingMoveRequest) { + return; + } + + const originalPosition = selected.currentPosition; + if (originalPosition > 0) { + const newPosition = originalPosition - 1; + selected.currentPosition = newPosition; + + const onRequestCompleted = () => { + this.announceMove(selected.bitstream.name, newPosition); + }; + + this.performBitstreamMoveRequest(selected.bundle, originalPosition, newPosition, onRequestCompleted); + this.updateSelectedBitstream(selected); + } + } + + /** + * Moves the selected bitstream one position down in the bundle. Does nothing if no bitstream is selected or the + * selected bitstream already is at the end of the bundle. + */ + moveSelectedBitstreamDown() { + const selected = this.getSelectedBitstream(); + + if (hasNoValue(selected) || this.isPerformingMoveRequest) { + return; + } + + const originalPosition = selected.currentPosition; + if (originalPosition < selected.bundleSize - 1) { + const newPosition = originalPosition + 1; + selected.currentPosition = newPosition; + + const onRequestCompleted = () => { + this.announceMove(selected.bitstream.name, newPosition); + }; + + this.performBitstreamMoveRequest(selected.bundle, originalPosition, newPosition, onRequestCompleted); + this.updateSelectedBitstream(selected); + } + } + + /** + * Sends out a Move Patch request to the REST API, display notifications, + * refresh the bundle's cache (so the lists can properly reload) + * @param bundle The bundle to send patch requests to + * @param fromIndex The index to move from + * @param toIndex The index to move to + * @param finish Optional: Function to execute once the response has been received + */ + performBitstreamMoveRequest(bundle: Bundle, fromIndex: number, toIndex: number, finish?: () => void) { + if (this.isPerformingMoveRequest) { + console.warn('Attempted to perform move request while previous request has not completed yet'); + return; + } + + const moveOperation: MoveOperation = { + op: 'move', + from: `/_links/bitstreams/${fromIndex}/href`, + path: `/_links/bitstreams/${toIndex}/href`, + }; + + this.isPerformingMoveRequest = true; + this.bundleService.patch(bundle, [moveOperation]).pipe( + getFirstCompletedRemoteData(), + tap((response: RemoteData) => this.displayNotifications('item.edit.bitstreams.notifications.move', [response])), + switchMap(() => this.requestService.setStaleByHrefSubstring(bundle.self)), + take(1), + ).subscribe(() => { + this.isPerformingMoveRequest = false; + finish?.(); + }); + } + /** * Returns the pagination options to use when fetching the bundles */ @@ -46,6 +285,10 @@ export class ItemBitstreamsService { }); } + /** + * Returns the initial pagination options to use when fetching the bitstreams + * @param bundleName The name of the bundle, will be as pagination id. + */ getInitialBitstreamsPaginationOptions(bundleName: string): PaginationComponentOptions { return Object.assign(new PaginationComponentOptions(),{ id: bundleName, // This might behave unexpectedly if the item contains two bundles with the same name @@ -118,6 +361,10 @@ export class ItemBitstreamsService { ); } + /** + * Creates an array of {@link BitstreamTableEntry}s from an array of {@link Bitstream}s + * @param bitstreams The bitstreams array to map to table entries + */ mapBitstreamsToTableEntries(bitstreams: Bitstream[]): BitstreamTableEntry[] { return bitstreams.map((bitstream) => { const name = this.dsoNameService.getName(bitstream); @@ -143,7 +390,7 @@ export class ItemBitstreamsService { // To make it clear which headers are relevant for a specific field in the table, the 'headers' attribute is used to // refer to specific headers. The Bitstream's name is used as header ID for the row containing information regarding // that bitstream. As the 'headers' attribute contains a space-separated string of header IDs, the Bitstream's header - // ID can not contain strings itself. + // ID can not contain spaces itself. return this.stripWhiteSpace(name); } @@ -155,4 +402,48 @@ export class ItemBitstreamsService { // '/\s+/g' matches all occurrences of any amount of whitespace characters return str.replace(/\s+/g, ''); } + + /** + * Adds a message to the live region mentioning that the bitstream with the provided name was selected. + * @param bitstreamName The name of the bitstream that was selected. + */ + announceSelect(bitstreamName: string) { + const message = this.translateService.instant('item.edit.bitstreams.edit.live.select', + { bitstream: bitstreamName }); + this.liveRegionService.addMessage(message); + } + + /** + * Adds a message to the live region mentioning that the bitstream with the provided name was moved to the provided + * position. + * @param bitstreamName The name of the bitstream that moved. + * @param toPosition The zero-indexed position that the bitstream moved to. + */ + announceMove(bitstreamName: string, toPosition: number) { + const message = this.translateService.instant('item.edit.bitstreams.edit.live.move', + { bitstream: bitstreamName, toIndex: toPosition + 1 }); + this.liveRegionService.addMessage(message); + } + + /** + * Adds a message to the live region mentioning that the bitstream with the provided name is no longer selected and + * was returned to the provided position. + * @param bitstreamName The name of the bitstream that is no longer selected + * @param toPosition The zero-indexed position the bitstream returned to. + */ + announceCancel(bitstreamName: string, toPosition: number) { + const message = this.translateService.instant('item.edit.bitstreams.edit.live.cancel', + { bitstream: bitstreamName, toIndex: toPosition + 1 }); + this.liveRegionService.addMessage(message); + } + + /** + * Adds a message to the live region mentioning that the bitstream with the provided name is no longer selected. + * @param bitstreamName The name of the bitstream that is no longer selected. + */ + announceClear(bitstreamName: string) { + const message = this.translateService.instant('item.edit.bitstreams.edit.live.clear', + { bitstream: bitstreamName }); + this.liveRegionService.addMessage(message); + } } diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index d530fb38d18..06fb571ce46 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -5,7 +5,8 @@ [hidePagerWhenSinglePage]="true" [hidePaginationDetail]="true" [paginationOptions]="paginationOptions" - [collectionSize]="bitstreamsList.totalElements"> + [collectionSize]="bitstreamsList.totalElements" + [retainScrollPosition]="true"> -
- -
+ diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts index 1502ad23113..25274b89415 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts @@ -58,6 +58,7 @@ describe('ItemEditBitstreamBundleComponent', () => { currentPage: 1, pageSize: 9999 }), + getSelectedBitstream$: observableOf({}), }); beforeEach(waitForAsync(() => { diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 24319f4a834..7d2a519bafc 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -1,4 +1,10 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewChild, ViewContainerRef } from '@angular/core'; +import { + Component, + Input, + OnInit, + ViewChild, + ViewContainerRef, OnDestroy, +} from '@angular/core'; import { Bundle } from '../../../../core/shared/bundle.model'; import { Item } from '../../../../core/shared/item.model'; import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes/responsive-column-sizes'; @@ -8,7 +14,7 @@ import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; import { RemoteData } from 'src/app/core/data/remote-data'; import { PaginatedList } from 'src/app/core/data/paginated-list.model'; import { Bitstream } from 'src/app/core/shared/bitstream.model'; -import { Observable, BehaviorSubject, switchMap } from 'rxjs'; +import { Observable, BehaviorSubject, switchMap, shareReplay, Subscription } from 'rxjs'; import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; import { FieldUpdates } from '../../../../core/data/object-updates/field-updates.model'; import { PaginatedSearchOptions } from '../../../../shared/search/models/paginated-search-options.model'; @@ -17,55 +23,17 @@ import { followLink } from '../../../../shared/utils/follow-link-config.model'; import { getAllSucceededRemoteData, paginatedListToArray, - getFirstSucceededRemoteData } from '../../../../core/shared/operators'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; -import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model'; -import { map, take, filter } from 'rxjs/operators'; +import { map, take, filter, tap, pairwise } from 'rxjs/operators'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; import { RequestService } from '../../../../core/data/request.service'; -import { ItemBitstreamsService } from '../item-bitstreams.service'; -import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; -import { hasValue } from '../../../../shared/empty.util'; -import { LiveRegionService } from '../../../../shared/live-region/live-region.service'; -import { TranslateService } from '@ngx-translate/core'; - -/** - * Interface storing all the information necessary to create a row in the bitstream edit table - */ -export interface BitstreamTableEntry { - /** - * The bitstream - */ - bitstream: Bitstream, - /** - * The uuid of the Bitstream - */ - id: string, - /** - * The name of the Bitstream - */ - name: string, - /** - * The name of the Bitstream with all whitespace removed - */ - nameStripped: string, - /** - * The description of the Bitstream - */ - description: string, - /** - * Observable emitting the Format of the Bitstream - */ - format: Observable, - /** - * The download url of the Bitstream - */ - downloadUrl: string, -} +import { ItemBitstreamsService, BitstreamTableEntry, SelectedBitstreamTableEntry } from '../item-bitstreams.service'; +import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { hasValue, hasNoValue } from '../../../../shared/empty.util'; @Component({ selector: 'ds-item-edit-bitstream-bundle', @@ -77,7 +45,7 @@ export interface BitstreamTableEntry { * Creates an embedded view of the contents. This is to ensure the table structure won't break. * (which means it'll be added to the parents html without a wrapping ds-item-edit-bitstream-bundle element) */ -export class ItemEditBitstreamBundleComponent implements OnInit { +export class ItemEditBitstreamBundleComponent implements OnInit, OnDestroy { protected readonly FieldChangeType = FieldChangeType; /** @@ -115,13 +83,6 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ @Input() isFirstTable = false; - /** - * Send an event when the user drops an object on the pagination - * The event contains details about the index the object came from and is dropped to (across the entirety of the list, - * not just within a single page) - */ - @Output() dropObject: EventEmitter = new EventEmitter(); - /** * The bootstrap sizes used for the Bundle Name column * This column stretches over the first 3 columns and thus is a combination of their sizes processed in ngOnInit @@ -138,6 +99,11 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ bundleName: string; + /** + * The number of bitstreams in the bundle + */ + bundleSize: number; + /** * The bitstreams to show in the table */ @@ -146,7 +112,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { /** * The data to show in the table */ - tableEntries$: BehaviorSubject = new BehaviorSubject(null); + tableEntries$: BehaviorSubject = new BehaviorSubject([]); /** * The initial page options to use for fetching the bitstreams @@ -158,11 +124,6 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ currentPaginationOptions$: BehaviorSubject; - /** - * The available page size options - */ - pageSizeOptions: number[]; - /** * The currently selected page size */ @@ -178,6 +139,11 @@ export class ItemEditBitstreamBundleComponent implements OnInit { */ updates$: BehaviorSubject = new BehaviorSubject(null); + /** + * Array containing all subscriptions created by this component + */ + subscriptions: Subscription[] = []; + constructor( protected viewContainerRef: ViewContainerRef, @@ -187,8 +153,6 @@ export class ItemEditBitstreamBundleComponent implements OnInit { protected paginationService: PaginationService, protected requestService: RequestService, protected itemBitstreamsService: ItemBitstreamsService, - protected liveRegionService: LiveRegionService, - protected translateService: TranslateService, ) { } @@ -201,23 +165,27 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.initializePagination(); this.initializeBitstreams(); + this.initializeSelectionActions(); + } - // this.bitstreamsRD = this. + ngOnDestroy() { + this.subscriptions.forEach(sub => sub?.unsubscribe()); } protected initializePagination() { this.paginationOptions = this.itemBitstreamsService.getInitialBitstreamsPaginationOptions(this.bundleName); - this.pageSizeOptions = this.paginationOptions.pageSizeOptions; - this.currentPaginationOptions$ = new BehaviorSubject(this.paginationOptions); this.pageSize$ = new BehaviorSubject(this.paginationOptions.pageSize); - this.paginationService.getCurrentPagination(this.paginationOptions.id, this.paginationOptions) - .subscribe((pagination) => { - this.currentPaginationOptions$.next(pagination); - this.pageSize$.next(pagination.pageSize); - }); + this.subscriptions.push( + this.paginationService.getCurrentPagination(this.paginationOptions.id, this.paginationOptions) + .subscribe((pagination) => { + this.currentPaginationOptions$.next(pagination); + this.pageSize$.next(pagination.pageSize); + }) + ); + } protected initializeBitstreams() { @@ -233,26 +201,88 @@ export class ItemEditBitstreamBundleComponent implements OnInit { )) ); }), + getAllSucceededRemoteData(), + shareReplay(1), ); - this.bitstreamsRD$.pipe( - getFirstSucceededRemoteData(), - paginatedListToArray(), - ).subscribe((bitstreams) => { - this.objectUpdatesService.initialize(this.bundleUrl, bitstreams, new Date()); - }); + this.subscriptions.push( + this.bitstreamsRD$.pipe( + take(1), + tap(bitstreamsRD => this.bundleSize = bitstreamsRD.payload.totalElements), + paginatedListToArray(), + ).subscribe((bitstreams) => { + this.objectUpdatesService.initialize(this.bundleUrl, bitstreams, new Date()); + }), - this.bitstreamsRD$.pipe( - getAllSucceededRemoteData(), - paginatedListToArray(), - switchMap((bitstreams) => this.objectUpdatesService.getFieldUpdatesExclusive(this.bundleUrl, bitstreams)) - ).subscribe((updates) => this.updates$.next(updates)); + this.bitstreamsRD$.pipe( + paginatedListToArray(), + switchMap((bitstreams) => this.objectUpdatesService.getFieldUpdatesExclusive(this.bundleUrl, bitstreams)) + ).subscribe((updates) => this.updates$.next(updates)), - this.bitstreamsRD$.pipe( - getAllSucceededRemoteData(), - paginatedListToArray(), - map((bitstreams) => this.itemBitstreamsService.mapBitstreamsToTableEntries(bitstreams)), - ).subscribe((tableEntries) => this.tableEntries$.next(tableEntries)); + this.bitstreamsRD$.pipe( + paginatedListToArray(), + map((bitstreams) => this.itemBitstreamsService.mapBitstreamsToTableEntries(bitstreams)), + ).subscribe((tableEntries) => this.tableEntries$.next(tableEntries)), + ); + } + + protected initializeSelectionActions() { + this.subscriptions.push( + this.itemBitstreamsService.getSelectedBitstream$().pipe(pairwise()).subscribe( + ([previousSelection, currentSelection]) => + this.handleSelectedEntryChange(previousSelection, currentSelection)) + ); + } + + /** + * Handles a change in selected bitstream by changing the pagination if the change happened on a different page + * @param previousSelectedEntry The previously selected entry + * @param currentSelectedEntry The currently selected entry + * @protected + */ + protected handleSelectedEntryChange( + previousSelectedEntry: SelectedBitstreamTableEntry, + currentSelectedEntry: SelectedBitstreamTableEntry + ) { + if (hasValue(currentSelectedEntry) && currentSelectedEntry.bundle === this.bundle) { + // If the currently selected bitstream belongs to this bundle, it has possibly moved to a different page. + // In that case we want to change the pagination to the new page. + this.redirectToCurrentPage(currentSelectedEntry); + } + + // If the selection is cancelled or cleared, it is possible the selected bitstream is currently on a different page + // In that case we want to change the pagination to the place where the bitstream was returned to + if (hasNoValue(currentSelectedEntry) && hasValue(previousSelectedEntry) && previousSelectedEntry.bundle === this.bundle) { + this.redirectToOriginalPage(previousSelectedEntry); + } + } + + /** + * Redirect the user to the current page of the provided bitstream if it is on a different page. + * @param bitstreamEntry The entry that the current position will be taken from to determine the page to move to + * @protected + */ + protected redirectToCurrentPage(bitstreamEntry: SelectedBitstreamTableEntry) { + const currentPage = this.getCurrentPage(); + const selectedEntryPage = this.bundleIndexToPage(bitstreamEntry.currentPosition); + + if (currentPage !== selectedEntryPage) { + this.changeToPage(selectedEntryPage); + } + } + + /** + * Redirect the user to the original page of the provided bitstream if it is on a different page. + * @param bitstreamEntry The entry that the original position will be taken from to determine the page to move to + * @protected + */ + protected redirectToOriginalPage(bitstreamEntry: SelectedBitstreamTableEntry) { + const currentPage = this.getCurrentPage(); + const originPage = this.bundleIndexToPage(bitstreamEntry.originalPosition); + + if (currentPage !== originPage) { + this.changeToPage(originPage); + } } /** @@ -283,7 +313,18 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.objectUpdatesService.removeSingleFieldUpdate(this.bundleUrl, bitstream.uuid); } - getRowClass(update: FieldUpdate): string { + /** + * Returns the css class for a table row depending on the state of the table entry. + * @param update + * @param bitstream + */ + getRowClass(update: FieldUpdate, bitstream: BitstreamTableEntry): string { + const selected = this.itemBitstreamsService.getSelectedBitstream(); + + if (hasValue(selected) && bitstream.id === selected.bitstream.id) { + return 'table-info'; + } + switch (update.changeType) { case FieldChangeType.UPDATE: return 'table-warning'; @@ -296,11 +337,19 @@ export class ItemEditBitstreamBundleComponent implements OnInit { } } + /** + * Changes the page size to the provided page size. + * @param pageSize + */ public doPageSizeChange(pageSize: number) { this.paginationComponent.doPageSizeChange(pageSize); } - dragStart(bitstreamName: string) { + /** + * Handles start of dragging by opening the tooltip mentioning that it is possible to drag a bitstream to a different + * page by dropping it on the page number, only if there are multiple pages. + */ + dragStart() { // Only open the drag tooltip when there are multiple pages this.paginationComponent.shouldShowBottomPager.pipe( take(1), @@ -308,66 +357,170 @@ export class ItemEditBitstreamBundleComponent implements OnInit { ).subscribe(() => { this.dragTooltip.open(); }); - - const message = this.translateService.instant('item.edit.bitstreams.edit.live.drag', - { bitstream: bitstreamName }); - this.liveRegionService.addMessage(message); } - dragEnd(bitstreamName: string) { + /** + * Handles end of dragging by closing the tooltip. + */ + dragEnd() { this.dragTooltip.close(); - - const message = this.translateService.instant('item.edit.bitstreams.edit.live.drop', - { bitstream: bitstreamName }); - this.liveRegionService.addMessage(message); } - + /** + * Handles dropping by calculation the target position, and changing the page if the bitstream was dropped on a + * different page. + * @param event + */ drop(event: CdkDragDrop) { const dragIndex = event.previousIndex; let dropIndex = event.currentIndex; - const dragPage = this.currentPaginationOptions$.value.currentPage - 1; - let dropPage = this.currentPaginationOptions$.value.currentPage - 1; + const dragPage = this.getCurrentPage(); + let dropPage = this.getCurrentPage(); // Check if the user is hovering over any of the pagination's pages at the time of dropping the object const droppedOnElement = document.elementFromPoint(event.dropPoint.x, event.dropPoint.y); if (hasValue(droppedOnElement) && hasValue(droppedOnElement.textContent) && droppedOnElement.classList.contains('page-link')) { // The user is hovering over a page, fetch the page's number from the element - const droppedPage = Number(droppedOnElement.textContent); + let droppedPage = Number(droppedOnElement.textContent); if (hasValue(droppedPage) && !Number.isNaN(droppedPage)) { - dropPage = droppedPage - 1; - dropIndex = 0; + droppedPage -= 1; + + if (droppedPage !== dragPage) { + dropPage = droppedPage; + + if (dropPage > dragPage) { + // When moving to later page, place bitstream at the top + dropIndex = 0; + } else { + // When moving to earlier page, place bitstream at the bottom + dropIndex = this.getCurrentPageSize() - 1; + } + } } } - const isNewPage = dragPage !== dropPage; - // Move the object in the custom order array if the drop happened within the same page - // This allows us to instantly display a change in the order, instead of waiting for the REST API's response first - if (!isNewPage && dragIndex !== dropIndex) { - const currentEntries = [...this.tableEntries$.value]; - moveItemInArray(currentEntries, dragIndex, dropIndex); - this.tableEntries$.next(currentEntries); + const fromIndex = this.pageIndexToBundleIndex(dragIndex, dragPage); + const toIndex = this.pageIndexToBundleIndex(dropIndex, dropPage); + + if (fromIndex === toIndex) { + return; } - const pageSize = this.currentPaginationOptions$.value.pageSize; - const redirectPage = dropPage + 1; - const fromIndex = (dragPage * pageSize) + dragIndex; - const toIndex = (dropPage * pageSize) + dropIndex; - // Send out a drop event (and navigate to the new page) when the "from" and "to" indexes are different from each other - if (fromIndex !== toIndex) { - // if (isNewPage) { - // this.loading$.next(true); - // } - this.dropObject.emit(Object.assign({ - fromIndex, - toIndex, - finish: () => { - if (isNewPage) { - this.paginationComponent.doPageChange(redirectPage); - } - } - })); + const selectedBitstream = this.tableEntries$.value[dragIndex]; + + const finish = () => { + this.itemBitstreamsService.announceMove(selectedBitstream.name, toIndex); + + if (dropPage !== this.getCurrentPage()) { + this.changeToPage(dropPage); + } + }; + + this.itemBitstreamsService.performBitstreamMoveRequest(this.bundle, fromIndex, toIndex, finish); + } + + /** + * Handles a select action for the provided bitstream entry. + * If the selected bitstream is currently selected, the selection is cleared. + * If no, or a different bitstream, is selected, the provided bitstream becomes the selected bitstream. + * @param bitstream + */ + select(bitstream: BitstreamTableEntry) { + const selectedBitstream = this.itemBitstreamsService.getSelectedBitstream(); + + if (hasValue(selectedBitstream) && selectedBitstream.bitstream === bitstream) { + this.itemBitstreamsService.cancelSelection(); + } else { + const selectionObject = this.createBitstreamSelectionObject(bitstream); + + if (hasNoValue(selectionObject)) { + console.warn('Failed to create selection object'); + return; + } + + this.itemBitstreamsService.selectBitstreamEntry(selectionObject); + } + } + + /** + * Creates a {@link SelectedBitstreamTableEntry} from the provided {@link BitstreamTableEntry} so it can be given + * to the {@link ItemBitstreamsService} to select the table entry. + * @param bitstream The table entry to create the selection object from. + * @protected + */ + protected createBitstreamSelectionObject(bitstream: BitstreamTableEntry): SelectedBitstreamTableEntry { + const pageIndex = this.findBitstreamPageIndex(bitstream); + + if (pageIndex === -1) { + return null; } + + const position = this.pageIndexToBundleIndex(pageIndex, this.getCurrentPage()); + + return { + bitstream: bitstream, + bundle: this.bundle, + bundleSize: this.bundleSize, + currentPosition: position, + originalPosition: position, + }; + } + + /** + * Returns the index of the provided {@link BitstreamTableEntry} relative to the current page + * If the current page size is 10, it will return a value from 0 to 9 (inclusive) + * Returns -1 if the provided bitstream could not be found + * @protected + */ + protected findBitstreamPageIndex(bitstream: BitstreamTableEntry): number { + const entries = this.tableEntries$.value; + return entries.findIndex(entry => entry === bitstream); + } + + /** + * Returns the current zero-indexed page + * @protected + */ + protected getCurrentPage(): number { + // The pagination component uses one-based numbering while zero-based numbering is more convenient for calculations + return this.currentPaginationOptions$.value.currentPage - 1; + } + + /** + * Returns the current page size + * @protected + */ + protected getCurrentPageSize(): number { + return this.currentPaginationOptions$.value.pageSize; + } + + /** + * Converts an index relative to the page to an index relative to the bundle + * @param index The index relative to the page + * @param page The zero-indexed page number + * @protected + */ + protected pageIndexToBundleIndex(index: number, page: number) { + return page * this.getCurrentPageSize() + index; + } + + /** + * Calculates the zero-indexed page number from the index relative to the bundle + * @param index The index relative to the bundle + * @protected + */ + protected bundleIndexToPage(index: number) { + return Math.floor(index / this.getCurrentPageSize()); } + /** + * Change the pagination for this bundle to the provided zero-indexed page + * @param page The zero-indexed page to change to + * @protected + */ + protected changeToPage(page: number) { + // Increments page by one because zero-indexing is way easier for calculations but the pagination component + // uses one-indexing. + this.paginationComponent.doPageChange(page + 1); + } } diff --git a/src/app/shared/live-region/live-region.service.stub.ts b/src/app/shared/live-region/live-region.service.stub.ts new file mode 100644 index 00000000000..4f10b46a4c6 --- /dev/null +++ b/src/app/shared/live-region/live-region.service.stub.ts @@ -0,0 +1,30 @@ +import { of } from 'rxjs'; +import { LiveRegionService } from './live-region.service'; + +export function getLiveRegionServiceStub(): LiveRegionService { + return new LiveRegionServiceStub() as unknown as LiveRegionService; +} + +export class LiveRegionServiceStub { + getMessages = jasmine.createSpy('getMessages').and.returnValue( + ['Message One', 'Message Two'] + ); + + getMessages$ = jasmine.createSpy('getMessages$').and.returnValue( + of(['Message One', 'Message Two']) + ); + + addMessage = jasmine.createSpy('addMessage').and.returnValue('messageId'); + + clear = jasmine.createSpy('clear'); + + clearMessageByUUID = jasmine.createSpy('clearMessageByUUID'); + + getLiveRegionVisibility = jasmine.createSpy('getLiveRegionVisibility').and.returnValue(false); + + setLiveRegionVisibility = jasmine.createSpy('setLiveRegionVisibility'); + + getMessageTimeOutMs = jasmine.createSpy('getMessageTimeOutMs').and.returnValue(30000); + + setMessageTimeOutMs = jasmine.createSpy('setMessageTimeOutMs'); +} diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index ab6f3792cac..519189ed691 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1950,9 +1950,13 @@ "item.edit.bitstreams.edit.buttons.undo": "Undo changes", - "item.edit.bitstreams.edit.live.drag": "{{ bitstream }} grabbed", + "item.edit.bitstreams.edit.live.cancel": "{{ bitstream }} was returned to position {{ toIndex }} and is no longer selected.", - "item.edit.bitstreams.edit.live.drop": "{{ bitstream }} dropped", + "item.edit.bitstreams.edit.live.clear": "{{ bitstream }} is no longer selected.", + + "item.edit.bitstreams.edit.live.select": "{{ bitstream }} is selected.", + + "item.edit.bitstreams.edit.live.move": "{{ bitstream }} is now in position {{ toIndex }}.", "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", From 2e1b1489b65c6c6715774ef482242e8f14d990f0 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 4 Oct 2024 09:40:20 +0200 Subject: [PATCH 191/822] 118223: Stop space from scrolling down page --- .../item-bitstreams/item-bitstreams.component.ts | 1 + .../item-edit-bitstream-bundle.component.html | 2 +- .../item-edit-bitstream-bundle.component.ts | 12 ++++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts index 4ced3dd6497..f77eda02fbf 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts @@ -138,6 +138,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme // Otherwise we might clear the selection when a different action was intended, e.g. clicking a button or selecting // a different bitstream. if (event.target instanceof Element && event.target.tagName === 'BODY') { + event.preventDefault(); this.itemBitstreamsService.clearSelection(); } } diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index 06fb571ce46..9afdd2d41c2 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -82,7 +82,7 @@
-
- +
+
{{ entry.name }}
+ (keydown.enter)="select($event, entry)" (keydown.space)="select($event, entry)" (click)="select($event, entry)">
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 7d2a519bafc..e2dff2f0184 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -423,9 +423,17 @@ export class ItemEditBitstreamBundleComponent implements OnInit, OnDestroy { * Handles a select action for the provided bitstream entry. * If the selected bitstream is currently selected, the selection is cleared. * If no, or a different bitstream, is selected, the provided bitstream becomes the selected bitstream. - * @param bitstream + * @param event The event that triggered the select action + * @param bitstream The bitstream that is the target of the select action */ - select(bitstream: BitstreamTableEntry) { + select(event: UIEvent, bitstream: BitstreamTableEntry) { + event.preventDefault(); + + if (event instanceof KeyboardEvent && event.repeat) { + // Don't handle hold events, otherwise it would change rapidly between being selected and unselected + return; + } + const selectedBitstream = this.itemBitstreamsService.getSelectedBitstream(); if (hasValue(selectedBitstream) && selectedBitstream.bitstream === bitstream) { From 0920a218762a4aa547c8b9bf72e795e8321e73ff Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 4 Oct 2024 10:53:42 +0200 Subject: [PATCH 192/822] 118223: Stop sending success notificiations on every move --- .../item-bitstreams.service.ts | 62 +++++++++++++++---- .../item-edit-bitstream-bundle.component.ts | 9 ++- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts index 21dc4151987..f8091d616aa 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts @@ -3,7 +3,7 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes'; import { ResponsiveColumnSizes } from '../../../shared/responsive-table-sizes/responsive-column-sizes'; import { RemoteData } from '../../../core/data/remote-data'; -import { isNotEmpty, hasValue, hasNoValue } from '../../../shared/empty.util'; +import { hasValue, hasNoValue } from '../../../shared/empty.util'; import { Bundle } from '../../../core/shared/bundle.model'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; @@ -25,6 +25,8 @@ import { BundleDataService } from '../../../core/data/bundle-data.service'; import { RequestService } from '../../../core/data/request.service'; import { LiveRegionService } from '../../../shared/live-region/live-region.service'; +export const MOVE_KEY = 'item.edit.bitstreams.notifications.move'; + /** * Interface storing all the information necessary to create a row in the bitstream edit table */ @@ -164,6 +166,10 @@ export class ItemBitstreamsService { if (hasValue(selected)) { this.updateSelectedBitstream(null); this.announceClear(selected.bitstream.name); + + if (selected.currentPosition !== selected.originalPosition) { + this.displaySuccessNotification(MOVE_KEY); + } } } @@ -265,7 +271,7 @@ export class ItemBitstreamsService { this.isPerformingMoveRequest = true; this.bundleService.patch(bundle, [moveOperation]).pipe( getFirstCompletedRemoteData(), - tap((response: RemoteData) => this.displayNotifications('item.edit.bitstreams.notifications.move', [response])), + tap((response: RemoteData) => this.displayFailedResponseNotifications(MOVE_KEY, [response])), switchMap(() => this.requestService.setStaleByHrefSubstring(bundle.self)), take(1), ).subscribe(() => { @@ -321,19 +327,51 @@ export class ItemBitstreamsService { * @param responses The returned responses to display notifications for */ displayNotifications(key: string, responses: RemoteData[]) { - if (isNotEmpty(responses)) { - const failedResponses = responses.filter((response: RemoteData) => hasValue(response) && response.hasFailed); - const successfulResponses = responses.filter((response: RemoteData) => hasValue(response) && response.hasSucceeded); - - failedResponses.forEach((response: RemoteData) => { - this.notificationsService.error(this.translateService.instant(`${key}.failed.title`), response.errorMessage); - }); - if (successfulResponses.length > 0) { - this.notificationsService.success(this.translateService.instant(`${key}.saved.title`), this.translateService.instant(`${key}.saved.content`)); - } + this.displayFailedResponseNotifications(key, responses); + this.displaySuccessFulResponseNotifications(key, responses); + } + + /** + * Display an error notification for each failed response with their message + * @param key The i18n key for the notification messages + * @param responses The returned responses to display notifications for + */ + displayFailedResponseNotifications(key: string, responses: RemoteData[]) { + const failedResponses = responses.filter((response: RemoteData) => hasValue(response) && response.hasFailed); + failedResponses.forEach((response: RemoteData) => { + this.displayErrorNotification(key, response.errorMessage); + }); + } + + /** + * Display an error notification with the provided key and message + * @param key The i18n key for the notification messages + * @param errorMessage The error message to display + */ + displayErrorNotification(key: string, errorMessage: string) { + this.notificationsService.error(this.translateService.instant(`${key}.failed.title`), errorMessage); + } + + /** + * Display a success notification in case there's at least one successful response + * @param key The i18n key for the notification messages + * @param responses The returned responses to display notifications for + */ + displaySuccessFulResponseNotifications(key: string, responses: RemoteData[]) { + const successfulResponses = responses.filter((response: RemoteData) => hasValue(response) && response.hasSucceeded); + if (successfulResponses.length > 0) { + this.displaySuccessNotification(key); } } + /** + * Display a success notification with the provided key + * @param key The i18n key for the notification messages + */ + displaySuccessNotification(key: string) { + this.notificationsService.success(this.translateService.instant(`${key}.saved.title`), this.translateService.instant(`${key}.saved.content`)); + } + /** * Removes the bitstreams marked for deletion from the Bundles emitted by the provided observable. * @param bundles$ diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index e2dff2f0184..4079ad225bd 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -31,7 +31,12 @@ import { FieldUpdate } from '../../../../core/data/object-updates/field-update.m import { PaginationService } from '../../../../core/pagination/pagination.service'; import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; import { RequestService } from '../../../../core/data/request.service'; -import { ItemBitstreamsService, BitstreamTableEntry, SelectedBitstreamTableEntry } from '../item-bitstreams.service'; +import { + ItemBitstreamsService, + BitstreamTableEntry, + SelectedBitstreamTableEntry, + MOVE_KEY +} from '../item-bitstreams.service'; import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { hasValue, hasNoValue } from '../../../../shared/empty.util'; @@ -414,6 +419,8 @@ export class ItemEditBitstreamBundleComponent implements OnInit, OnDestroy { if (dropPage !== this.getCurrentPage()) { this.changeToPage(dropPage); } + + this.itemBitstreamsService.displaySuccessNotification(MOVE_KEY); }; this.itemBitstreamsService.performBitstreamMoveRequest(this.bundle, fromIndex, toIndex, finish); From b158c5c2a275ff64108229c37083da7e7f78720e Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 4 Oct 2024 10:58:52 +0200 Subject: [PATCH 193/822] 118223: Move drag tooltip to center of pagination numbers --- .../item-edit-bitstream-bundle.component.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index 9afdd2d41c2..efbdd8c69bc 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -6,7 +6,9 @@ [hidePaginationDetail]="true" [paginationOptions]="paginationOptions" [collectionSize]="bitstreamsList.totalElements" - [retainScrollPosition]="true"> + [retainScrollPosition]="true" + [ngbTooltip]="'item.edit.bitstreams.bundle.tooltip' | translate" placement="bottom" + [autoClose]="false" triggers="manual" #dragTooltip="ngbTooltip"> - + +
{{'item.edit.bitstreams.bundle.name' | translate:{ name: bundleName } }} From 1dcc5d1ec5a21667e90322fb2a6dc4528d8f5c0b Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 4 Oct 2024 15:16:16 +0200 Subject: [PATCH 194/822] 118223: Add ItemBitstreams service tests --- .../item-bitstreams.service.spec.ts | 443 +++++++++++++++++- .../item-bitstreams.service.ts | 4 +- 2 files changed, 444 insertions(+), 3 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts index e144e81ec7e..94adb5f23a0 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts @@ -1,4 +1,4 @@ -import { ItemBitstreamsService } from './item-bitstreams.service'; +import { ItemBitstreamsService, SelectedBitstreamTableEntry } from './item-bitstreams.service'; import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub'; import { getMockTranslateService } from '../../../shared/mocks/translate.service.mock'; import { ObjectUpdatesServiceStub } from '../../../core/data/object-updates/object-updates.service.stub'; @@ -22,6 +22,9 @@ import { LiveRegionService } from '../../../shared/live-region/live-region.servi import { Bundle } from '../../../core/shared/bundle.model'; import { of } from 'rxjs'; import { getLiveRegionServiceStub } from '../../../shared/live-region/live-region.service.stub'; +import { fakeAsync, tick } from '@angular/core/testing'; +import createSpy = jasmine.createSpy; +import { MoveOperation } from 'fast-json-patch'; describe('ItemBitstreamsService', () => { let service: ItemBitstreamsService; @@ -60,6 +63,444 @@ describe('ItemBitstreamsService', () => { ); }); + const defaultEntry: SelectedBitstreamTableEntry = { + bitstream: { + name: 'bitstream name', + } as any, + bundle: Object.assign(new Bundle(), { + _links: { self: { href: 'self_link' }}, + }), + bundleSize: 10, + currentPosition: 0, + originalPosition: 0, + }; + + describe('selectBitstreamEntry', () => { + it('should correctly make getSelectedBitstream$ emit', fakeAsync(() => { + const emittedEntries = []; + + service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + + expect(emittedEntries.length).toBe(1); + expect(emittedEntries[0]).toBeNull(); + + const entry = Object.assign({}, defaultEntry); + + service.selectBitstreamEntry(entry); + tick(); + + expect(emittedEntries.length).toBe(2); + expect(emittedEntries[1]).toEqual(entry); + })); + + it('should correctly make getSelectedBitstream return the bitstream', () => { + expect(service.getSelectedBitstream()).toBeNull(); + + const entry = Object.assign({}, defaultEntry); + + service.selectBitstreamEntry(entry); + expect(service.getSelectedBitstream()).toEqual(entry); + }); + + it('should correctly make hasSelectedBitstream return', () => { + expect(service.hasSelectedBitstream()).toBeFalse(); + + const entry = Object.assign({}, defaultEntry); + + service.selectBitstreamEntry(entry); + expect(service.hasSelectedBitstream()).toBeTrue(); + }); + + it('should do nothing if no entry was provided', fakeAsync(() => { + const emittedEntries = []; + + service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + + expect(emittedEntries.length).toBe(1); + expect(emittedEntries[0]).toBeNull(); + + const entry = Object.assign({}, defaultEntry); + + service.selectBitstreamEntry(entry); + tick(); + + expect(emittedEntries.length).toBe(2); + expect(emittedEntries[1]).toEqual(entry); + + service.selectBitstreamEntry(null); + tick(); + + expect(emittedEntries.length).toBe(2); + expect(emittedEntries[1]).toEqual(entry); + })); + + it('should announce the selected bitstream', () => { + const entry = Object.assign({}, defaultEntry); + + spyOn(service, 'announceSelect'); + + service.selectBitstreamEntry(entry); + expect(service.announceSelect).toHaveBeenCalledWith(entry.bitstream.name); + }); + }); + + describe('clearSelection', () => { + it('should clear the selected bitstream', fakeAsync(() => { + const emittedEntries = []; + + service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + + expect(emittedEntries.length).toBe(1); + expect(emittedEntries[0]).toBeNull(); + + const entry = Object.assign({}, defaultEntry); + + service.selectBitstreamEntry(entry); + tick(); + + expect(emittedEntries.length).toBe(2); + expect(emittedEntries[1]).toEqual(entry); + + service.clearSelection(); + tick(); + + expect(emittedEntries.length).toBe(3); + expect(emittedEntries[2]).toBeNull(); + })); + + it('should not do anything if there is no selected bitstream', fakeAsync(() => { + const emittedEntries = []; + + service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + + expect(emittedEntries.length).toBe(1); + expect(emittedEntries[0]).toBeNull(); + + service.clearSelection(); + tick(); + + expect(emittedEntries.length).toBe(1); + expect(emittedEntries[0]).toBeNull(); + })); + + it('should announce the cleared bitstream', () => { + const entry = Object.assign({}, defaultEntry); + + spyOn(service, 'announceClear'); + service.selectBitstreamEntry(entry); + service.clearSelection(); + + expect(service.announceClear).toHaveBeenCalledWith(entry.bitstream.name); + }); + + it('should display a notification if the selected bitstream was moved', () => { + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: 7, + } + ); + + spyOn(service, 'displaySuccessNotification'); + service.selectBitstreamEntry(entry); + service.clearSelection(); + + expect(service.displaySuccessNotification).toHaveBeenCalled(); + }); + + it('should not display a notification if the selected bitstream is in its original position', () => { + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 7, + currentPosition: 7, + } + ); + + spyOn(service, 'displaySuccessNotification'); + service.selectBitstreamEntry(entry); + service.clearSelection(); + + expect(service.displaySuccessNotification).not.toHaveBeenCalled(); + }); + }); + + describe('cancelSelection', () => { + it('should clear the selected bitstream', fakeAsync(() => { + const emittedEntries = []; + + service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + + expect(emittedEntries.length).toBe(1); + expect(emittedEntries[0]).toBeNull(); + + const entry = Object.assign({}, defaultEntry); + + service.selectBitstreamEntry(entry); + tick(); + + expect(emittedEntries.length).toBe(2); + expect(emittedEntries[1]).toEqual(entry); + + service.cancelSelection(); + tick(); + + expect(emittedEntries.length).toBe(3); + expect(emittedEntries[2]).toBeNull(); + })); + + it('should announce a clear if the bitstream has not moved', () => { + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 7, + currentPosition: 7, + } + ); + + spyOn(service, 'announceClear'); + spyOn(service, 'announceCancel'); + + service.selectBitstreamEntry(entry); + service.cancelSelection(); + + expect(service.announceClear).toHaveBeenCalledWith(entry.bitstream.name); + expect(service.announceCancel).not.toHaveBeenCalled(); + }); + + it('should announce a cancel if the bitstream has moved', () => { + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: 7, + } + ); + + spyOn(service, 'announceClear'); + spyOn(service, 'announceCancel'); + + service.selectBitstreamEntry(entry); + service.cancelSelection(); + + expect(service.announceClear).not.toHaveBeenCalled(); + expect(service.announceCancel).toHaveBeenCalledWith(entry.bitstream.name, entry.originalPosition); + }); + + it('should return the bitstream to its original position if it has moved', () => { + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: 7, + } + ); + + spyOn(service, 'performBitstreamMoveRequest'); + + service.selectBitstreamEntry(entry); + service.cancelSelection(); + + expect(service.performBitstreamMoveRequest).toHaveBeenCalledWith(entry.bundle, entry.currentPosition, entry.originalPosition); + }); + + it('should not move the bitstream if it has not moved', () => { + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 7, + currentPosition: 7, + } + ); + + spyOn(service, 'performBitstreamMoveRequest'); + + service.selectBitstreamEntry(entry); + service.cancelSelection(); + + expect(service.performBitstreamMoveRequest).not.toHaveBeenCalled(); + }); + + it('should not do anything if there is no selected bitstream', () => { + spyOn(service, 'announceClear'); + spyOn(service, 'announceCancel'); + spyOn(service, 'performBitstreamMoveRequest'); + + service.cancelSelection(); + + expect(service.announceClear).not.toHaveBeenCalled(); + expect(service.announceCancel).not.toHaveBeenCalled(); + expect(service.performBitstreamMoveRequest).not.toHaveBeenCalled(); + }); + }); + + describe('moveSelectedBitstream', () => { + beforeEach(() => { + spyOn(service, 'performBitstreamMoveRequest').and.callThrough(); + }); + + describe('up', () => { + it('should move the selected bitstream one position up', () => { + const startPosition = 7; + const endPosition = startPosition - 1; + + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: startPosition, + } + ); + + const movedEntry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: endPosition, + } + ); + + service.selectBitstreamEntry(entry); + service.moveSelectedBitstreamUp(); + expect(service.performBitstreamMoveRequest).toHaveBeenCalledWith(entry.bundle, startPosition, endPosition, jasmine.any(Function)); + expect(service.getSelectedBitstream()).toEqual(movedEntry); + }); + + it('should announce the move', () => { + const startPosition = 7; + const endPosition = startPosition - 1; + + spyOn(service, 'announceMove'); + + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: startPosition, + } + ); + + service.selectBitstreamEntry(entry); + service.moveSelectedBitstreamUp(); + + expect(service.announceMove).toHaveBeenCalledWith(entry.bitstream.name, endPosition); + }); + + it('should not do anything if the bitstream is already at the top', () => { + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: 0, + } + ); + + service.selectBitstreamEntry(entry); + service.moveSelectedBitstreamUp(); + + expect(service.performBitstreamMoveRequest).not.toHaveBeenCalled(); + }); + + it('should not do anything if there is no selected bitstream', () => { + service.moveSelectedBitstreamUp(); + + expect(service.performBitstreamMoveRequest).not.toHaveBeenCalled(); + }); + }); + + describe('down', () => { + it('should move the selected bitstream one position down', () => { + const startPosition = 7; + const endPosition = startPosition + 1; + + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: startPosition, + } + ); + + const movedEntry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: endPosition, + } + ); + + service.selectBitstreamEntry(entry); + service.moveSelectedBitstreamDown(); + expect(service.performBitstreamMoveRequest).toHaveBeenCalledWith(entry.bundle, startPosition, endPosition, jasmine.any(Function)); + expect(service.getSelectedBitstream()).toEqual(movedEntry); + }); + + it('should announce the move', () => { + const startPosition = 7; + const endPosition = startPosition + 1; + + spyOn(service, 'announceMove'); + + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: startPosition, + } + ); + + service.selectBitstreamEntry(entry); + service.moveSelectedBitstreamDown(); + + expect(service.announceMove).toHaveBeenCalledWith(entry.bitstream.name, endPosition); + }); + + it('should not do anything if the bitstream is already at the bottom of the bundle', () => { + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: 9, + } + ); + + service.selectBitstreamEntry(entry); + service.moveSelectedBitstreamDown(); + + expect(service.performBitstreamMoveRequest).not.toHaveBeenCalled(); + }); + + it('should not do anything if there is no selected bitstream', () => { + service.moveSelectedBitstreamDown(); + + expect(service.performBitstreamMoveRequest).not.toHaveBeenCalled(); + }); + }); + }); + + describe('performBitstreamMoveRequest', () => { + const bundle: Bundle = defaultEntry.bundle; + const from = 5; + const to = 7; + const callback = createSpy('callbackFunction'); + + console.log('bundle:', bundle); + + it('should correctly create the Move request', () => { + const expectedOperation: MoveOperation = { + op: 'move', + from: `/_links/bitstreams/${from}/href`, + path: `/_links/bitstreams/${to}/href`, + }; + + service.performBitstreamMoveRequest(bundle, from, to, callback); + expect(bundleDataService.patch).toHaveBeenCalledWith(bundle, [expectedOperation]); + }); + + it('should correctly make the bundle\'s self link stale', () => { + service.performBitstreamMoveRequest(bundle, from, to, callback); + expect(requestService.setStaleByHrefSubstring).toHaveBeenCalledWith(bundle._links.self.href); + }); + + it('should attempt to show a message should the request have failed', () => { + spyOn(service, 'displayFailedResponseNotifications'); + service.performBitstreamMoveRequest(bundle, from, to, callback); + expect(service.displayFailedResponseNotifications).toHaveBeenCalled(); + }); + + it('should correctly call the provided function once the request has finished', () => { + service.performBitstreamMoveRequest(bundle, from, to, callback); + expect(callback).toHaveBeenCalled(); + }); + }); + describe('displayNotifications', () => { it('should display an error notification if a response failed', () => { const responses = [ diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts index f8091d616aa..5b5fb7d63c0 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts @@ -143,7 +143,7 @@ export class ItemBitstreamsService { * Select the provided entry */ selectBitstreamEntry(entry: SelectedBitstreamTableEntry) { - if (entry !== this.selectedBitstream$.getValue()) { + if (hasValue(entry) && entry !== this.selectedBitstream$.getValue()) { this.announceSelect(entry.bitstream.name); this.updateSelectedBitstream(entry); } @@ -184,7 +184,7 @@ export class ItemBitstreamsService { return; } - this.selectedBitstream$.next(null); + this.updateSelectedBitstream(null); const originalPosition = selected.originalPosition; const currentPosition = selected.currentPosition; From 0bdb5742e064ca35325aa03530506012e36b1dc4 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 4 Oct 2024 15:22:43 +0200 Subject: [PATCH 195/822] 118223: Remove unused item-edit-bitstream component --- .../edit-item-page/edit-item-page.module.ts | 2 - .../item-edit-bitstream.component.html | 51 ------ .../item-edit-bitstream.component.spec.ts | 145 ------------------ .../item-edit-bitstream.component.ts | 117 -------------- 4 files changed, 315 deletions(-) delete mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.html delete mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.spec.ts delete mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts diff --git a/src/app/item-page/edit-item-page/edit-item-page.module.ts b/src/app/item-page/edit-item-page/edit-item-page.module.ts index 4ae5ebe6667..c38b480622e 100644 --- a/src/app/item-page/edit-item-page/edit-item-page.module.ts +++ b/src/app/item-page/edit-item-page/edit-item-page.module.ts @@ -15,7 +15,6 @@ import { ItemPrivateComponent } from './item-private/item-private.component'; import { ItemPublicComponent } from './item-public/item-public.component'; import { ItemDeleteComponent } from './item-delete/item-delete.component'; import { ItemBitstreamsComponent } from './item-bitstreams/item-bitstreams.component'; -import { ItemEditBitstreamComponent } from './item-bitstreams/item-edit-bitstream/item-edit-bitstream.component'; import { SearchPageModule } from '../../search-page/search-page.module'; import { ItemCollectionMapperComponent } from './item-collection-mapper/item-collection-mapper.component'; import { ItemRelationshipsComponent } from './item-relationships/item-relationships.component'; @@ -78,7 +77,6 @@ import { ItemRelationshipsComponent, ItemBitstreamsComponent, ItemVersionHistoryComponent, - ItemEditBitstreamComponent, ItemEditBitstreamBundleComponent, EditRelationshipComponent, EditRelationshipListComponent, diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.html deleted file mode 100644 index 0f0fad21993..00000000000 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.html +++ /dev/null @@ -1,51 +0,0 @@ - -
- -
- - {{ bitstreamName }} - -
-
-
-
-
- {{ bitstream?.firstMetadataValue('dc.description') }} -
-
-
-
-
- - {{ (format$ | async)?.shortDescription }} - -
-
-
-
-
- - - - - - -
-
-
-
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.spec.ts deleted file mode 100644 index aafa5a4fe45..00000000000 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.spec.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { ItemEditBitstreamComponent } from './item-edit-bitstream.component'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; -import { of as observableOf } from 'rxjs'; -import { Bitstream } from '../../../../core/shared/bitstream.model'; -import { TranslateModule } from '@ngx-translate/core'; -import { VarDirective } from '../../../../shared/utils/var.directive'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model'; -import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes'; -import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes/responsive-column-sizes'; -import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils'; -import { getBitstreamDownloadRoute } from '../../../../app-routing-paths'; -import { By } from '@angular/platform-browser'; -import { BrowserOnlyMockPipe } from '../../../../shared/testing/browser-only-mock.pipe'; - -let comp: ItemEditBitstreamComponent; -let fixture: ComponentFixture; - -const columnSizes = new ResponsiveTableSizes([ - new ResponsiveColumnSizes(2, 2, 3, 4, 4), - new ResponsiveColumnSizes(2, 3, 3, 3, 3), - new ResponsiveColumnSizes(2, 2, 2, 2, 2), - new ResponsiveColumnSizes(6, 5, 4, 3, 3) -]); - -const format = Object.assign(new BitstreamFormat(), { - shortDescription: 'PDF' -}); -const bitstream = Object.assign(new Bitstream(), { - uuid: 'bitstreamUUID', - name: 'Fake Bitstream', - bundleName: 'ORIGINAL', - description: 'Description', - _links: { - content: { href: 'content-link' } - }, - - format: createSuccessfulRemoteDataObject$(format) -}); -const fieldUpdate = { - field: bitstream, - changeType: undefined -}; -const date = new Date(); -const url = 'thisUrl'; - -let objectUpdatesService: ObjectUpdatesService; - -describe('ItemEditBitstreamComponent', () => { - beforeEach(waitForAsync(() => { - objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', - { - getFieldUpdates: observableOf({ - [bitstream.uuid]: fieldUpdate, - }), - getFieldUpdatesExclusive: observableOf({ - [bitstream.uuid]: fieldUpdate, - }), - saveRemoveFieldUpdate: {}, - removeSingleFieldUpdate: {}, - saveAddFieldUpdate: {}, - discardFieldUpdates: {}, - reinstateFieldUpdates: observableOf(true), - initialize: {}, - getUpdatedFields: observableOf([bitstream]), - getLastModified: observableOf(date), - hasUpdates: observableOf(true), - isReinstatable: observableOf(false), - isValidPage: observableOf(true) - } - ); - - TestBed.configureTestingModule({ - imports: [TranslateModule.forRoot()], - declarations: [ - ItemEditBitstreamComponent, - VarDirective, - BrowserOnlyMockPipe, - ], - providers: [ - { provide: ObjectUpdatesService, useValue: objectUpdatesService } - ], schemas: [ - NO_ERRORS_SCHEMA - ] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(ItemEditBitstreamComponent); - comp = fixture.componentInstance; - comp.fieldUpdate = fieldUpdate; - comp.bundleUrl = url; - comp.columnSizes = columnSizes; - comp.ngOnChanges(undefined); - fixture.detectChanges(); - }); - - describe('when remove is called', () => { - beforeEach(() => { - comp.remove(); - }); - - it('should call saveRemoveFieldUpdate on objectUpdatesService', () => { - expect(objectUpdatesService.saveRemoveFieldUpdate).toHaveBeenCalledWith(url, bitstream); - }); - }); - - describe('when undo is called', () => { - beforeEach(() => { - comp.undo(); - }); - - it('should call removeSingleFieldUpdate on objectUpdatesService', () => { - expect(objectUpdatesService.removeSingleFieldUpdate).toHaveBeenCalledWith(url, bitstream.uuid); - }); - }); - - describe('when canRemove is called', () => { - it('should return true', () => { - expect(comp.canRemove()).toEqual(true); - }); - }); - - describe('when canUndo is called', () => { - it('should return false', () => { - expect(comp.canUndo()).toEqual(false); - }); - }); - - describe('when the component loads', () => { - it('should contain download button with a valid link to the bitstreams download page', () => { - fixture.detectChanges(); - const downloadBtnHref = fixture.debugElement.query(By.css('[data-test="download-button"]')).nativeElement.getAttribute('href'); - expect(downloadBtnHref).toEqual(comp.bitstreamDownloadUrl); - }); - }); - - describe('when the bitstreamDownloadUrl property gets populated', () => { - it('should contain the bitstream download page route', () => { - expect(comp.bitstreamDownloadUrl).not.toEqual(bitstream._links.content.href); - expect(comp.bitstreamDownloadUrl).toEqual(getBitstreamDownloadRoute(bitstream)); - }); - }); -}); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts deleted file mode 100644 index fcb5c706ac7..00000000000 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream/item-edit-bitstream.component.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core'; -import { Bitstream } from '../../../../core/shared/bitstream.model'; -import cloneDeep from 'lodash/cloneDeep'; -import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; -import { Observable } from 'rxjs'; -import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model'; -import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../../core/shared/operators'; -import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes'; -import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; -import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; -import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; -import { getBitstreamDownloadRoute } from '../../../../app-routing-paths'; - -@Component({ - selector: 'ds-item-edit-bitstream', - styleUrls: ['../item-bitstreams.component.scss'], - templateUrl: './item-edit-bitstream.component.html', -}) -/** - * Component that displays a single bitstream of an item on the edit page - * Creates an embedded view of the contents - * (which means it'll be added to the parents html without a wrapping ds-item-edit-bitstream element) - */ -export class ItemEditBitstreamComponent implements OnChanges, OnInit { - - /** - * The view on the bitstream - */ - @ViewChild('bitstreamView', {static: true}) bitstreamView; - - /** - * The current field, value and state of the bitstream - */ - @Input() fieldUpdate: FieldUpdate; - - /** - * The url of the bundle - */ - @Input() bundleUrl: string; - - /** - * The bootstrap sizes used for the columns within this table - */ - @Input() columnSizes: ResponsiveTableSizes; - - /** - * The bitstream of this field - */ - bitstream: Bitstream; - - /** - * The bitstream's name - */ - bitstreamName: string; - - /** - * The bitstream's download url - */ - bitstreamDownloadUrl: string; - - /** - * The format of the bitstream - */ - format$: Observable; - - constructor(private objectUpdatesService: ObjectUpdatesService, - private dsoNameService: DSONameService, - private viewContainerRef: ViewContainerRef) { - } - - ngOnInit(): void { - this.viewContainerRef.createEmbeddedView(this.bitstreamView); - } - - /** - * Update the current bitstream and its format on changes - * @param changes - */ - ngOnChanges(changes: SimpleChanges): void { - this.bitstream = cloneDeep(this.fieldUpdate.field) as Bitstream; - this.bitstreamName = this.dsoNameService.getName(this.bitstream); - this.bitstreamDownloadUrl = getBitstreamDownloadRoute(this.bitstream); - this.format$ = this.bitstream.format.pipe( - getFirstSucceededRemoteData(), - getRemoteDataPayload() - ); - } - - /** - * Sends a new remove update for this field to the object updates service - */ - remove(): void { - this.objectUpdatesService.saveRemoveFieldUpdate(this.bundleUrl, this.bitstream); - } - - /** - * Cancels the current update for this field in the object updates service - */ - undo(): void { - this.objectUpdatesService.removeSingleFieldUpdate(this.bundleUrl, this.bitstream.uuid); - } - - /** - * Check if a user should be allowed to remove this field - */ - canRemove(): boolean { - return this.fieldUpdate.changeType !== FieldChangeType.REMOVE; - } - - /** - * Check if a user should be allowed to cancel the update to this field - */ - canUndo(): boolean { - return this.fieldUpdate.changeType >= 0; - } - -} From e8379db987317c5cb892989a21297ab5edce8669 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Mon, 7 Oct 2024 11:49:54 +0200 Subject: [PATCH 196/822] 118223: Add item-bitstreams component tests --- .../item-bitstreams.component.spec.ts | 129 +++++++++++++++--- .../item-bitstreams.component.ts | 6 +- .../item-bitstreams.service.stub.ts | 74 ++++++++++ 3 files changed, 192 insertions(+), 17 deletions(-) create mode 100644 src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts index a5549a6ba0a..d26f8153168 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.spec.ts @@ -26,9 +26,7 @@ import { createPaginatedList } from '../../../shared/testing/utils.test'; import { FieldChangeType } from '../../../core/data/object-updates/field-change-type.model'; import { BitstreamDataServiceStub } from '../../../shared/testing/bitstream-data-service.stub'; import { ItemBitstreamsService } from './item-bitstreams.service'; -import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes'; -import { ResponsiveColumnSizes } from '../../../shared/responsive-table-sizes/responsive-column-sizes'; -import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; +import { getItemBitstreamsServiceStub, ItemBitstreamsServiceStub } from './item-bitstreams.service.stub'; let comp: ItemBitstreamsComponent; let fixture: ComponentFixture; @@ -80,7 +78,7 @@ let objectCache: ObjectCacheService; let requestService: RequestService; let searchConfig: SearchConfigurationService; let bundleService: BundleDataService; -let itemBitstreamsService: ItemBitstreamsService; +let itemBitstreamsService: ItemBitstreamsServiceStub; describe('ItemBitstreamsComponent', () => { beforeEach(waitForAsync(() => { @@ -152,18 +150,7 @@ describe('ItemBitstreamsComponent', () => { patch: createSuccessfulRemoteDataObject$({}), }); - itemBitstreamsService = jasmine.createSpyObj('itemBitstreamsService', { - getColumnSizes: new ResponsiveTableSizes([ - new ResponsiveColumnSizes(2, 2, 3, 4, 4), - new ResponsiveColumnSizes(2, 3, 3, 3, 3), - new ResponsiveColumnSizes(2, 2, 2, 2, 2), - new ResponsiveColumnSizes(6, 5, 4, 3, 3) - ]), - getSelectedBitstream$: observableOf({}), - getInitialBundlesPaginationOptions: new PaginationComponentOptions(), - removeMarkedBitstreams: createSuccessfulRemoteDataObject$({}), - displayNotifications: undefined, - }); + itemBitstreamsService = getItemBitstreamsServiceStub(); TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], @@ -218,4 +205,114 @@ describe('ItemBitstreamsComponent', () => { expect(objectUpdatesService.reinstateFieldUpdates).toHaveBeenCalledWith(bundle.self); }); }); + + describe('moveUp', () => { + it('should move the selected bitstream up', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(true); + + const event = { + preventDefault: () => {/* Intentionally empty */}, + } as KeyboardEvent; + comp.moveUp(event); + + expect(itemBitstreamsService.moveSelectedBitstreamUp).toHaveBeenCalled(); + }); + + it('should not do anything if no bitstream is selected', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(false); + + const event = { + preventDefault: () => {/* Intentionally empty */}, + } as KeyboardEvent; + comp.moveUp(event); + + expect(itemBitstreamsService.moveSelectedBitstreamUp).not.toHaveBeenCalled(); + }); + }); + + describe('moveDown', () => { + it('should move the selected bitstream down', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(true); + + const event = { + preventDefault: () => {/* Intentionally empty */}, + } as KeyboardEvent; + comp.moveDown(event); + + expect(itemBitstreamsService.moveSelectedBitstreamDown).toHaveBeenCalled(); + }); + + it('should not do anything if no bitstream is selected', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(false); + + const event = { + preventDefault: () => {/* Intentionally empty */}, + } as KeyboardEvent; + comp.moveDown(event); + + expect(itemBitstreamsService.moveSelectedBitstreamDown).not.toHaveBeenCalled(); + }); + }); + + describe('cancelSelection', () => { + it('should cancel the selection', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(true); + + const event = { + preventDefault: () => {/* Intentionally empty */}, + } as KeyboardEvent; + comp.cancelSelection(event); + + expect(itemBitstreamsService.cancelSelection).toHaveBeenCalled(); + }); + + it('should not do anything if no bitstream is selected', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(false); + + const event = { + preventDefault: () => {/* Intentionally empty */}, + } as KeyboardEvent; + comp.cancelSelection(event); + + expect(itemBitstreamsService.cancelSelection).not.toHaveBeenCalled(); + }); + }); + + describe('clearSelection', () => { + it('should clear the selection', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(true); + + const event = { + target: document.createElement('BODY'), + preventDefault: () => {/* Intentionally empty */}, + } as unknown as KeyboardEvent; + comp.clearSelection(event); + + expect(itemBitstreamsService.clearSelection).toHaveBeenCalled(); + }); + + it('should not do anything if no bitstream is selected', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(false); + + const event = { + target: document.createElement('BODY'), + preventDefault: () => {/* Intentionally empty */}, + } as unknown as KeyboardEvent; + comp.clearSelection(event); + + expect(itemBitstreamsService.clearSelection).not.toHaveBeenCalled(); + }); + + it('should not do anything if the event target is not \'BODY\'', () => { + itemBitstreamsService.hasSelectedBitstream.and.returnValue(true); + + const event = { + target: document.createElement('NOT-BODY'), + preventDefault: () => {/* Intentionally empty */}, + } as unknown as KeyboardEvent; + comp.clearSelection(event); + + expect(itemBitstreamsService.clearSelection).not.toHaveBeenCalled(); + }); + }); }); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts index f77eda02fbf..6ee5dcb545f 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts @@ -137,7 +137,11 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme // Only when no specific element is in focus do we want to clear the currently selected bitstream // Otherwise we might clear the selection when a different action was intended, e.g. clicking a button or selecting // a different bitstream. - if (event.target instanceof Element && event.target.tagName === 'BODY') { + if ( + this.itemBitstreamsService.hasSelectedBitstream() && + event.target instanceof Element && + event.target.tagName === 'BODY' + ) { event.preventDefault(); this.itemBitstreamsService.clearSelection(); } diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts new file mode 100644 index 00000000000..0521bf47f64 --- /dev/null +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts @@ -0,0 +1,74 @@ +import { of } from 'rxjs'; +import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; +import { ResponsiveTableSizes } from '../../../shared/responsive-table-sizes/responsive-table-sizes'; +import { ResponsiveColumnSizes } from '../../../shared/responsive-table-sizes/responsive-column-sizes'; +import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; + +export function getItemBitstreamsServiceStub(): ItemBitstreamsServiceStub { + return new ItemBitstreamsServiceStub(); +} + +export class ItemBitstreamsServiceStub { + getSelectedBitstream$ = jasmine.createSpy('getSelectedBitstream$').and + .returnValue(of(null)); + + getSelectedBitstream = jasmine.createSpy('getSelectedBitstream').and + .returnValue(null); + + hasSelectedBitstream = jasmine.createSpy('hasSelectedBitstream').and + .returnValue(false); + + selectBitstreamEntry = jasmine.createSpy('selectBitstreamEntry'); + + clearSelection = jasmine.createSpy('clearSelection'); + + cancelSelection = jasmine.createSpy('cancelSelection'); + + moveSelectedBitstreamUp = jasmine.createSpy('moveSelectedBitstreamUp'); + + moveSelectedBitstreamDown = jasmine.createSpy('moveSelectedBitstreamDown'); + + performBitstreamMoveRequest = jasmine.createSpy('performBitstreamMoveRequest'); + + getInitialBundlesPaginationOptions = jasmine.createSpy('getInitialBundlesPaginationOptions').and + .returnValue(new PaginationComponentOptions()); + + getInitialBitstreamsPaginationOptions = jasmine.createSpy('getInitialBitstreamsPaginationOptions').and + .returnValue(new PaginationComponentOptions()); + + getColumnSizes = jasmine.createSpy('getColumnSizes').and + .returnValue( + new ResponsiveTableSizes([ + new ResponsiveColumnSizes(2, 2, 3, 4, 4), + new ResponsiveColumnSizes(2, 3, 3, 3, 3), + new ResponsiveColumnSizes(2, 2, 2, 2, 2), + new ResponsiveColumnSizes(6, 5, 4, 3, 3) + ]) + ); + + displayNotifications = jasmine.createSpy('displayNotifications'); + + displayFailedResponseNotifications = jasmine.createSpy('displayFailedResponseNotifications'); + + displayErrorNotification = jasmine.createSpy('displayErrorNotification'); + + displaySuccessFulResponseNotifications = jasmine.createSpy('displaySuccessFulResponseNotifications'); + + displaySuccessNotification = jasmine.createSpy('displaySuccessNotification'); + + removeMarkedBitstreams = jasmine.createSpy('removeMarkedBitstreams').and + .returnValue(createSuccessfulRemoteDataObject$({})); + + mapBitstreamsToTableEntries = jasmine.createSpy('mapBitstreamsToTableEntries').and + .returnValue([]); + + nameToHeader = jasmine.createSpy('nameToHeader').and.returnValue('header'); + + stripWhiteSpace = jasmine.createSpy('stripWhiteSpace').and.returnValue('string'); + + announceSelect = jasmine.createSpy('announceSelect'); + + announceMove = jasmine.createSpy('announceMove'); + + announceCancel = jasmine.createSpy('announceCancel'); +} From 7fb4755abaa1759f175ea2d2cff6d93af00d946e Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 8 Oct 2024 15:51:00 +0200 Subject: [PATCH 197/822] 118223: Add item-edit-bitstream-bundle component tests --- ...em-edit-bitstream-bundle.component.spec.ts | 302 ++++++++++++++++-- .../item-edit-bitstream-bundle.component.ts | 3 +- 2 files changed, 285 insertions(+), 20 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts index 25274b89415..6008b5431f9 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts @@ -7,14 +7,19 @@ import { Bundle } from '../../../../core/shared/bundle.model'; import { ResponsiveTableSizes } from '../../../../shared/responsive-table-sizes/responsive-table-sizes'; import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes/responsive-column-sizes'; import { BundleDataService } from '../../../../core/data/bundle-data.service'; -import { of as observableOf } from 'rxjs'; +import { of as observableOf, of, Subject } from 'rxjs'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { PaginationServiceStub } from '../../../../shared/testing/pagination-service.stub'; import { RequestService } from '../../../../core/data/request.service'; import { getMockRequestService } from '../../../../shared/mocks/request.service.mock'; -import { ItemBitstreamsService } from '../item-bitstreams.service'; +import { ItemBitstreamsService, BitstreamTableEntry, SelectedBitstreamTableEntry } from '../item-bitstreams.service'; import { PaginationService } from '../../../../core/pagination/pagination.service'; -import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; +import { getItemBitstreamsServiceStub, ItemBitstreamsServiceStub } from '../item-bitstreams.service.stub'; +import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; +import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; +import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils'; +import { createPaginatedList } from '../../../../shared/testing/utils.test'; +import { CdkDragDrop } from '@angular/cdk/drag-drop'; describe('ItemEditBitstreamBundleComponent', () => { let comp: ItemEditBitstreamBundleComponent; @@ -43,25 +48,20 @@ describe('ItemEditBitstreamBundleComponent', () => { const restEndpoint = 'fake-rest-endpoint'; const bundleService = jasmine.createSpyObj('bundleService', { getBitstreamsEndpoint: observableOf(restEndpoint), - getBitstreams: null, + getBitstreams: createSuccessfulRemoteDataObject$(createPaginatedList([])), }); - const objectUpdatesService = { - initialize: () => { - // do nothing - }, - }; - - const itemBitstreamsService = jasmine.createSpyObj('itemBitstreamsService', { - getInitialBitstreamsPaginationOptions: Object.assign(new PaginationComponentOptions(), { - id: 'bundles-pagination-options', - currentPage: 1, - pageSize: 9999 - }), - getSelectedBitstream$: observableOf({}), - }); + let objectUpdatesService: any; + let itemBitstreamsService: ItemBitstreamsServiceStub; beforeEach(waitForAsync(() => { + objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', { + initialize: undefined, + getFieldUpdatesExclusive: of(null), + }); + + itemBitstreamsService = getItemBitstreamsServiceStub(); + TestBed.configureTestingModule({ imports: [TranslateModule.forRoot()], declarations: [ItemEditBitstreamBundleComponent], @@ -92,4 +92,270 @@ describe('ItemEditBitstreamBundleComponent', () => { it('should create an embedded view of the component', () => { expect(viewContainerRef.createEmbeddedView).toHaveBeenCalled(); }); + + describe('on selected entry change', () => { + let paginationComponent: any; + let testSubject: Subject = new Subject(); + + beforeEach(() => { + paginationComponent = jasmine.createSpyObj('paginationComponent', { + doPageChange: undefined, + }); + comp.paginationComponent = paginationComponent; + + spyOn(comp, 'getCurrentPageSize').and.returnValue(2); + }); + + it('should move to the page the selected entry is on if were not on that page', () => { + const selectedA: SelectedBitstreamTableEntry = { + bitstream: null, + bundle: bundle, + bundleSize: 5, + originalPosition: 1, + currentPosition: 1, + }; + + const selectedB: SelectedBitstreamTableEntry = { + bitstream: null, + bundle: bundle, + bundleSize: 5, + originalPosition: 1, + currentPosition: 2, + }; + + comp.handleSelectedEntryChange(selectedA, selectedB); + expect(paginationComponent.doPageChange).toHaveBeenCalledWith(2); + }); + + it('should not change page when we are already on the correct page', () => { + const selectedA: SelectedBitstreamTableEntry = { + bitstream: null, + bundle: bundle, + bundleSize: 5, + originalPosition: 0, + currentPosition: 0, + }; + + const selectedB: SelectedBitstreamTableEntry = { + bitstream: null, + bundle: bundle, + bundleSize: 5, + originalPosition: 0, + currentPosition: 1, + }; + + comp.handleSelectedEntryChange(selectedA, selectedB); + expect(paginationComponent.doPageChange).not.toHaveBeenCalled(); + }); + + it('should change to the original page when cancelling', () => { + const selectedA: SelectedBitstreamTableEntry = { + bitstream: null, + bundle: bundle, + bundleSize: 5, + originalPosition: 3, + currentPosition: 0, + }; + + const selectedB = null; + + comp.handleSelectedEntryChange(selectedA, selectedB); + expect(paginationComponent.doPageChange).toHaveBeenCalledWith(2); + }); + + it('should not change page when we are already on the correct page when cancelling', () => { + const selectedA: SelectedBitstreamTableEntry = { + bitstream: null, + bundle: bundle, + bundleSize: 5, + originalPosition: 0, + currentPosition: 3, + }; + + const selectedB = null; + + comp.handleSelectedEntryChange(selectedA, selectedB); + expect(paginationComponent.doPageChange).not.toHaveBeenCalled(); + }); + }); + + describe('getRowClass', () => { + it('should return \'table-info\' when the bitstream is the selected bitstream', () => { + itemBitstreamsService.getSelectedBitstream.and.returnValue({ + bitstream: { id: 'bitstream-id'} + }); + + const bitstreamEntry = { + id: 'bitstream-id', + } as BitstreamTableEntry; + + expect(comp.getRowClass(undefined, bitstreamEntry)).toEqual('table-info'); + }); + + it('should return \'table-warning\' when the update is of type \'UPDATE\'', () => { + const update = { + changeType: FieldChangeType.UPDATE, + } as FieldUpdate; + + expect(comp.getRowClass(update, undefined)).toEqual('table-warning'); + }); + + it('should return \'table-success\' when the update is of type \'ADD\'', () => { + const update = { + changeType: FieldChangeType.ADD, + } as FieldUpdate; + + expect(comp.getRowClass(update, undefined)).toEqual('table-success'); + }); + + it('should return \'table-danger\' when the update is of type \'REMOVE\'', () => { + const update = { + changeType: FieldChangeType.REMOVE, + } as FieldUpdate; + + expect(comp.getRowClass(update, undefined)).toEqual('table-danger'); + }); + + it('should return \'bg-white\' in any other case', () => { + const update = { + changeType: undefined, + } as FieldUpdate; + + expect(comp.getRowClass(update, undefined)).toEqual('bg-white'); + }); + }); + + describe('drag', () => { + let dragTooltip; + let paginationComponent; + + beforeEach(() => { + dragTooltip = jasmine.createSpyObj('dragTooltip', { + open: undefined, + close: undefined, + }); + comp.dragTooltip = dragTooltip; + }); + + describe('Start', () => { + it('should open the tooltip when there are multiple pages', () => { + paginationComponent = jasmine.createSpyObj('paginationComponent', { + doPageChange: undefined, + }, { + shouldShowBottomPager: of(true), + }); + comp.paginationComponent = paginationComponent; + + comp.dragStart(); + expect(dragTooltip.open).toHaveBeenCalled(); + }); + + it('should not open the tooltip when there is only a single page', () => { + paginationComponent = jasmine.createSpyObj('paginationComponent', { + doPageChange: undefined, + }, { + shouldShowBottomPager: of(false), + }); + comp.paginationComponent = paginationComponent; + + comp.dragStart(); + expect(dragTooltip.open).not.toHaveBeenCalled(); + }); + }); + + describe('end', () => { + it('should always close the tooltip', () => { + paginationComponent = jasmine.createSpyObj('paginationComponent', { + doPageChange: undefined, + }, { + shouldShowBottomPager: of(false), + }); + comp.paginationComponent = paginationComponent; + + comp.dragEnd(); + expect(dragTooltip.close).toHaveBeenCalled(); + }); + }); + }); + + describe('drop', () => { + it('should correctly move the bitstream on drop', () => { + const event = { + previousIndex: 1, + currentIndex: 8, + dropPoint: { x: 100, y: 200 }, + } as CdkDragDrop; + + comp.drop(event); + expect(itemBitstreamsService.performBitstreamMoveRequest).toHaveBeenCalledWith(jasmine.any(Bundle), 1, 8, jasmine.any(Function)); + }); + + it('should not move the bitstream if dropped in the same place', () => { + const event = { + previousIndex: 1, + currentIndex: 1, + dropPoint: { x: 100, y: 200 }, + } as CdkDragDrop; + + comp.drop(event); + expect(itemBitstreamsService.performBitstreamMoveRequest).not.toHaveBeenCalled(); + }); + + it('should move to a different page if dropped on a page number', () => { + spyOn(document, 'elementFromPoint').and.returnValue({ + textContent: '2', + classList: { contains: (token: string) => true }, + } as Element); + + const event = { + previousIndex: 1, + currentIndex: 1, + dropPoint: { x: 100, y: 200 }, + } as CdkDragDrop; + + comp.drop(event); + expect(itemBitstreamsService.performBitstreamMoveRequest).toHaveBeenCalledWith(jasmine.any(Bundle), 1, 20, jasmine.any(Function)); + }); + }); + + describe('select', () => { + it('should select the bitstream', () => { + const event = new KeyboardEvent('keydown'); + spyOnProperty(event, 'repeat', 'get').and.returnValue(false); + + const entry = { } as BitstreamTableEntry; + comp.tableEntries$.next([entry]); + + comp.select(event, entry); + expect(itemBitstreamsService.selectBitstreamEntry).toHaveBeenCalledWith(jasmine.objectContaining({ bitstream: entry })); + }); + + it('should cancel the selection if the bitstream already is selected', () => { + const event = new KeyboardEvent('keydown'); + spyOnProperty(event, 'repeat', 'get').and.returnValue(false); + + const entry = { } as BitstreamTableEntry; + comp.tableEntries$.next([entry]); + + itemBitstreamsService.getSelectedBitstream.and.returnValue({ bitstream: entry }); + + comp.select(event, entry); + expect(itemBitstreamsService.selectBitstreamEntry).not.toHaveBeenCalled(); + expect(itemBitstreamsService.cancelSelection).toHaveBeenCalled(); + }); + + it('should not do anything if the user is holding down the select key', () => { + const event = new KeyboardEvent('keydown'); + spyOnProperty(event, 'repeat', 'get').and.returnValue(true); + + const entry = { } as BitstreamTableEntry; + comp.tableEntries$.next([entry]); + + itemBitstreamsService.getSelectedBitstream.and.returnValue({ bitstream: entry }); + + comp.select(event, entry); + expect(itemBitstreamsService.selectBitstreamEntry).not.toHaveBeenCalled(); + expect(itemBitstreamsService.cancelSelection).not.toHaveBeenCalled(); + }); + }); }); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 4079ad225bd..7a70ba80dd8 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -243,9 +243,8 @@ export class ItemEditBitstreamBundleComponent implements OnInit, OnDestroy { * Handles a change in selected bitstream by changing the pagination if the change happened on a different page * @param previousSelectedEntry The previously selected entry * @param currentSelectedEntry The currently selected entry - * @protected */ - protected handleSelectedEntryChange( + handleSelectedEntryChange( previousSelectedEntry: SelectedBitstreamTableEntry, currentSelectedEntry: SelectedBitstreamTableEntry ) { From 2b1b9d83d7d2e58a8f26b9843202f1705110fea5 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 9 Oct 2024 11:14:28 +0200 Subject: [PATCH 198/822] 118223: Include selection action with selection --- .../item-bitstreams.service.spec.ts | 176 ++++++++++++++---- .../item-bitstreams.service.stub.ts | 2 +- .../item-bitstreams.service.ts | 82 ++++++-- ...em-edit-bitstream-bundle.component.spec.ts | 35 +--- .../item-edit-bitstream-bundle.component.ts | 40 ++-- 5 files changed, 233 insertions(+), 102 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts index 94adb5f23a0..f2af25f22f7 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts @@ -77,20 +77,20 @@ describe('ItemBitstreamsService', () => { describe('selectBitstreamEntry', () => { it('should correctly make getSelectedBitstream$ emit', fakeAsync(() => { - const emittedEntries = []; + const emittedActions = []; - service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + service.getSelectionAction$().subscribe(selected => emittedActions.push(selected)); - expect(emittedEntries.length).toBe(1); - expect(emittedEntries[0]).toBeNull(); + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); const entry = Object.assign({}, defaultEntry); service.selectBitstreamEntry(entry); tick(); - expect(emittedEntries.length).toBe(2); - expect(emittedEntries[1]).toEqual(entry); + expect(emittedActions.length).toBe(2); + expect(emittedActions[1]).toEqual({ action: 'Selected', selectedEntry: entry }); })); it('should correctly make getSelectedBitstream return the bitstream', () => { @@ -112,26 +112,26 @@ describe('ItemBitstreamsService', () => { }); it('should do nothing if no entry was provided', fakeAsync(() => { - const emittedEntries = []; + const emittedActions = []; - service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + service.getSelectionAction$().subscribe(selected => emittedActions.push(selected)); - expect(emittedEntries.length).toBe(1); - expect(emittedEntries[0]).toBeNull(); + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); const entry = Object.assign({}, defaultEntry); service.selectBitstreamEntry(entry); tick(); - expect(emittedEntries.length).toBe(2); - expect(emittedEntries[1]).toEqual(entry); + expect(emittedActions.length).toBe(2); + expect(emittedActions[1]).toEqual({ action: 'Selected', selectedEntry: entry }); service.selectBitstreamEntry(null); tick(); - expect(emittedEntries.length).toBe(2); - expect(emittedEntries[1]).toEqual(entry); + expect(emittedActions.length).toBe(2); + expect(emittedActions[1]).toEqual({ action: 'Selected', selectedEntry: entry }); })); it('should announce the selected bitstream', () => { @@ -146,41 +146,41 @@ describe('ItemBitstreamsService', () => { describe('clearSelection', () => { it('should clear the selected bitstream', fakeAsync(() => { - const emittedEntries = []; + const emittedActions = []; - service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + service.getSelectionAction$().subscribe(selected => emittedActions.push(selected)); - expect(emittedEntries.length).toBe(1); - expect(emittedEntries[0]).toBeNull(); + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); const entry = Object.assign({}, defaultEntry); service.selectBitstreamEntry(entry); tick(); - expect(emittedEntries.length).toBe(2); - expect(emittedEntries[1]).toEqual(entry); + expect(emittedActions.length).toBe(2); + expect(emittedActions[1]).toEqual({ action: 'Selected', selectedEntry: entry }); service.clearSelection(); tick(); - expect(emittedEntries.length).toBe(3); - expect(emittedEntries[2]).toBeNull(); + expect(emittedActions.length).toBe(3); + expect(emittedActions[2]).toEqual({ action: 'Cleared', selectedEntry: entry }); })); it('should not do anything if there is no selected bitstream', fakeAsync(() => { - const emittedEntries = []; + const emittedActions = []; - service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + service.getSelectionAction$().subscribe(selected => emittedActions.push(selected)); - expect(emittedEntries.length).toBe(1); - expect(emittedEntries[0]).toBeNull(); + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); service.clearSelection(); tick(); - expect(emittedEntries.length).toBe(1); - expect(emittedEntries[0]).toBeNull(); + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); })); it('should announce the cleared bitstream', () => { @@ -225,27 +225,53 @@ describe('ItemBitstreamsService', () => { }); describe('cancelSelection', () => { - it('should clear the selected bitstream', fakeAsync(() => { - const emittedEntries = []; + it('should clear the selected bitstream if it has not moved', fakeAsync(() => { + const emittedActions = []; - service.getSelectedBitstream$().subscribe(selected => emittedEntries.push(selected)); + service.getSelectionAction$().subscribe(selected => emittedActions.push(selected)); - expect(emittedEntries.length).toBe(1); - expect(emittedEntries[0]).toBeNull(); + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); const entry = Object.assign({}, defaultEntry); service.selectBitstreamEntry(entry); tick(); - expect(emittedEntries.length).toBe(2); - expect(emittedEntries[1]).toEqual(entry); + expect(emittedActions.length).toBe(2); + expect(emittedActions[1]).toEqual({ action: 'Selected', selectedEntry: entry }); service.cancelSelection(); tick(); - expect(emittedEntries.length).toBe(3); - expect(emittedEntries[2]).toBeNull(); + expect(emittedActions.length).toBe(3); + expect(emittedActions[2]).toEqual({ action: 'Cleared', selectedEntry: entry }); + })); + + it('should cancel the selected bitstream if it has moved', fakeAsync(() => { + const emittedActions = []; + + service.getSelectionAction$().subscribe(selected => emittedActions.push(selected)); + + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); + + const entry = Object.assign({}, defaultEntry, { + originalPosition: 0, + currentPosition: 3, + }); + + service.selectBitstreamEntry(entry); + tick(); + + expect(emittedActions.length).toBe(2); + expect(emittedActions[1]).toEqual({ action: 'Selected', selectedEntry: entry }); + + service.cancelSelection(); + tick(); + + expect(emittedActions.length).toBe(3); + expect(emittedActions[2]).toEqual({ action: 'Cancelled', selectedEntry: entry }); })); it('should announce a clear if the bitstream has not moved', () => { @@ -359,6 +385,44 @@ describe('ItemBitstreamsService', () => { expect(service.getSelectedBitstream()).toEqual(movedEntry); }); + it('should emit the move', fakeAsync(() => { + const emittedActions = []; + + service.getSelectionAction$().subscribe(selected => emittedActions.push(selected)); + + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); + + const startPosition = 7; + const endPosition = startPosition - 1; + + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: startPosition, + } + ); + + const movedEntry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: endPosition, + } + ); + + service.selectBitstreamEntry(entry); + tick(); + + expect(emittedActions.length).toBe(2); + expect(emittedActions[1]).toEqual({ action: 'Selected', selectedEntry: entry }); + + service.moveSelectedBitstreamUp(); + tick(); + + expect(emittedActions.length).toBe(3); + expect(emittedActions[2]).toEqual({ action: 'Moved', selectedEntry: movedEntry }); + })); + it('should announce the move', () => { const startPosition = 7; const endPosition = startPosition - 1; @@ -424,6 +488,44 @@ describe('ItemBitstreamsService', () => { expect(service.getSelectedBitstream()).toEqual(movedEntry); }); + it('should emit the move', fakeAsync(() => { + const emittedActions = []; + + service.getSelectionAction$().subscribe(selected => emittedActions.push(selected)); + + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeNull(); + + const startPosition = 7; + const endPosition = startPosition + 1; + + const entry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: startPosition, + } + ); + + const movedEntry = Object.assign({}, defaultEntry, + { + originalPosition: 5, + currentPosition: endPosition, + } + ); + + service.selectBitstreamEntry(entry); + tick(); + + expect(emittedActions.length).toBe(2); + expect(emittedActions[1]).toEqual({ action: 'Selected', selectedEntry: entry }); + + service.moveSelectedBitstreamDown(); + tick(); + + expect(emittedActions.length).toBe(3); + expect(emittedActions[2]).toEqual({ action: 'Moved', selectedEntry: movedEntry }); + })); + it('should announce the move', () => { const startPosition = 7; const endPosition = startPosition + 1; diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts index 0521bf47f64..7aac79fe695 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts @@ -9,7 +9,7 @@ export function getItemBitstreamsServiceStub(): ItemBitstreamsServiceStub { } export class ItemBitstreamsServiceStub { - getSelectedBitstream$ = jasmine.createSpy('getSelectedBitstream$').and + getSelectionAction$ = jasmine.createSpy('getSelectedBitstream$').and .returnValue(of(null)); getSelectedBitstream = jasmine.createSpy('getSelectedBitstream').and diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts index 5b5fb7d63c0..2329107c29d 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts @@ -87,6 +87,24 @@ export interface SelectedBitstreamTableEntry { currentPosition: number, } +/** + * Interface storing data regarding a change in selected bitstream + */ +export interface SelectionAction { + /** + * The different types of actions: + * - Selected: Bitstream was selected + * - Moved: Bitstream was moved + * - Cleared: Selection was cleared, bitstream remains at its current position + * - Cancelled: Selection was cancelled, bitstream returns to its original position + */ + action: 'Selected' | 'Moved' | 'Cleared' | 'Cancelled' + /** + * The table entry to which the selection action applies + */ + selectedEntry: SelectedBitstreamTableEntry, +} + /** * This service handles the selection and updating of the bitstreams and their order on the * 'Edit Item' -> 'Bitstreams' page. @@ -99,7 +117,7 @@ export class ItemBitstreamsService { /** * BehaviorSubject which emits every time the selected bitstream changes. */ - protected selectedBitstream$: BehaviorSubject = new BehaviorSubject(null); + protected selectionAction$: BehaviorSubject = new BehaviorSubject(null); protected isPerformingMoveRequest = false; @@ -116,45 +134,68 @@ export class ItemBitstreamsService { } /** - * Returns the observable emitting the currently selected bitstream + * Returns the observable emitting the selection actions */ - getSelectedBitstream$(): Observable { - return this.selectedBitstream$; + getSelectionAction$(): Observable { + return this.selectionAction$; } /** - * Returns a copy of the currently selected bitstream + * Returns the latest selection action */ - getSelectedBitstream(): SelectedBitstreamTableEntry { - const selected = this.selectedBitstream$.getValue(); + getSelectionAction(): SelectionAction { + const action = this.selectionAction$.value; - if (hasNoValue(selected)) { - return selected; + if (hasNoValue(action)) { + return null; } - return Object.assign({}, selected); + return Object.assign({}, action); } + /** + * Returns true if there currently is a selected bitstream + */ hasSelectedBitstream(): boolean { - return hasValue(this.getSelectedBitstream()); + const selectionAction = this.getSelectionAction(); + + if (hasNoValue(selectionAction)) { + return false; + } + + const action = selectionAction.action; + + return action === 'Selected' || action === 'Moved'; + } + + /** + * Returns a copy of the currently selected bitstream + */ + getSelectedBitstream(): SelectedBitstreamTableEntry { + if (!this.hasSelectedBitstream()) { + return null; + } + + const selectionAction = this.getSelectionAction(); + return Object.assign({}, selectionAction.selectedEntry); } /** * Select the provided entry */ selectBitstreamEntry(entry: SelectedBitstreamTableEntry) { - if (hasValue(entry) && entry !== this.selectedBitstream$.getValue()) { + if (hasValue(entry) && entry.bitstream !== this.getSelectedBitstream()?.bitstream) { this.announceSelect(entry.bitstream.name); - this.updateSelectedBitstream(entry); + this.updateSelectionAction({ action: 'Selected', selectedEntry: entry }); } } /** - * Makes the {@link selectedBitstream$} observable emit the provided {@link SelectedBitstreamTableEntry}. + * Makes the {@link selectionAction$} observable emit the provided {@link SelectedBitstreamTableEntry}. * @protected */ - protected updateSelectedBitstream(entry: SelectedBitstreamTableEntry) { - this.selectedBitstream$.next(entry); + protected updateSelectionAction(action: SelectionAction) { + this.selectionAction$.next(action); } /** @@ -164,7 +205,7 @@ export class ItemBitstreamsService { const selected = this.getSelectedBitstream(); if (hasValue(selected)) { - this.updateSelectedBitstream(null); + this.updateSelectionAction({ action: 'Cleared', selectedEntry: selected }); this.announceClear(selected.bitstream.name); if (selected.currentPosition !== selected.originalPosition) { @@ -184,7 +225,6 @@ export class ItemBitstreamsService { return; } - this.updateSelectedBitstream(null); const originalPosition = selected.originalPosition; const currentPosition = selected.currentPosition; @@ -192,9 +232,11 @@ export class ItemBitstreamsService { // If the selected bitstream has not moved, there is no need to return it to its original position if (currentPosition === originalPosition) { this.announceClear(selected.bitstream.name); + this.updateSelectionAction({ action: 'Cleared', selectedEntry: selected }); } else { this.announceCancel(selected.bitstream.name, originalPosition); this.performBitstreamMoveRequest(selected.bundle, currentPosition, originalPosition); + this.updateSelectionAction({ action: 'Cancelled', selectedEntry: selected }); } } @@ -219,7 +261,7 @@ export class ItemBitstreamsService { }; this.performBitstreamMoveRequest(selected.bundle, originalPosition, newPosition, onRequestCompleted); - this.updateSelectedBitstream(selected); + this.updateSelectionAction({ action: 'Moved', selectedEntry: selected }); } } @@ -244,7 +286,7 @@ export class ItemBitstreamsService { }; this.performBitstreamMoveRequest(selected.bundle, originalPosition, newPosition, onRequestCompleted); - this.updateSelectedBitstream(selected); + this.updateSelectionAction({ action: 'Moved', selectedEntry: selected }); } } diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts index 6008b5431f9..26a1b0e9139 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.spec.ts @@ -107,15 +107,8 @@ describe('ItemEditBitstreamBundleComponent', () => { }); it('should move to the page the selected entry is on if were not on that page', () => { - const selectedA: SelectedBitstreamTableEntry = { - bitstream: null, - bundle: bundle, - bundleSize: 5, - originalPosition: 1, - currentPosition: 1, - }; - const selectedB: SelectedBitstreamTableEntry = { + const entry: SelectedBitstreamTableEntry = { bitstream: null, bundle: bundle, bundleSize: 5, @@ -123,20 +116,12 @@ describe('ItemEditBitstreamBundleComponent', () => { currentPosition: 2, }; - comp.handleSelectedEntryChange(selectedA, selectedB); + comp.handleSelectionAction({ action: 'Moved', selectedEntry: entry }); expect(paginationComponent.doPageChange).toHaveBeenCalledWith(2); }); it('should not change page when we are already on the correct page', () => { - const selectedA: SelectedBitstreamTableEntry = { - bitstream: null, - bundle: bundle, - bundleSize: 5, - originalPosition: 0, - currentPosition: 0, - }; - - const selectedB: SelectedBitstreamTableEntry = { + const entry: SelectedBitstreamTableEntry = { bitstream: null, bundle: bundle, bundleSize: 5, @@ -144,12 +129,12 @@ describe('ItemEditBitstreamBundleComponent', () => { currentPosition: 1, }; - comp.handleSelectedEntryChange(selectedA, selectedB); + comp.handleSelectionAction({ action: 'Moved', selectedEntry: entry }); expect(paginationComponent.doPageChange).not.toHaveBeenCalled(); }); it('should change to the original page when cancelling', () => { - const selectedA: SelectedBitstreamTableEntry = { + const entry: SelectedBitstreamTableEntry = { bitstream: null, bundle: bundle, bundleSize: 5, @@ -157,14 +142,12 @@ describe('ItemEditBitstreamBundleComponent', () => { currentPosition: 0, }; - const selectedB = null; - - comp.handleSelectedEntryChange(selectedA, selectedB); + comp.handleSelectionAction({ action: 'Cancelled', selectedEntry: entry }); expect(paginationComponent.doPageChange).toHaveBeenCalledWith(2); }); it('should not change page when we are already on the correct page when cancelling', () => { - const selectedA: SelectedBitstreamTableEntry = { + const entry: SelectedBitstreamTableEntry = { bitstream: null, bundle: bundle, bundleSize: 5, @@ -172,9 +155,7 @@ describe('ItemEditBitstreamBundleComponent', () => { currentPosition: 3, }; - const selectedB = null; - - comp.handleSelectedEntryChange(selectedA, selectedB); + comp.handleSelectionAction({ action: 'Cancelled', selectedEntry: entry }); expect(paginationComponent.doPageChange).not.toHaveBeenCalled(); }); }); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index 7a70ba80dd8..2c7d8ca60f4 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -25,7 +25,7 @@ import { paginatedListToArray, } from '../../../../core/shared/operators'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; -import { map, take, filter, tap, pairwise } from 'rxjs/operators'; +import { map, take, filter, tap } from 'rxjs/operators'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; import { PaginationService } from '../../../../core/pagination/pagination.service'; @@ -35,7 +35,7 @@ import { ItemBitstreamsService, BitstreamTableEntry, SelectedBitstreamTableEntry, - MOVE_KEY + MOVE_KEY, SelectionAction } from '../item-bitstreams.service'; import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { hasValue, hasNoValue } from '../../../../shared/empty.util'; @@ -233,31 +233,37 @@ export class ItemEditBitstreamBundleComponent implements OnInit, OnDestroy { protected initializeSelectionActions() { this.subscriptions.push( - this.itemBitstreamsService.getSelectedBitstream$().pipe(pairwise()).subscribe( - ([previousSelection, currentSelection]) => - this.handleSelectedEntryChange(previousSelection, currentSelection)) + this.itemBitstreamsService.getSelectionAction$().subscribe( + selectionAction => this.handleSelectionAction(selectionAction)) ); } /** * Handles a change in selected bitstream by changing the pagination if the change happened on a different page - * @param previousSelectedEntry The previously selected entry - * @param currentSelectedEntry The currently selected entry + * @param selectionAction */ - handleSelectedEntryChange( - previousSelectedEntry: SelectedBitstreamTableEntry, - currentSelectedEntry: SelectedBitstreamTableEntry - ) { - if (hasValue(currentSelectedEntry) && currentSelectedEntry.bundle === this.bundle) { + handleSelectionAction(selectionAction: SelectionAction) { + if (hasNoValue(selectionAction) || selectionAction.selectedEntry.bundle !== this.bundle) { + return; + } + + if (selectionAction.action === 'Moved') { // If the currently selected bitstream belongs to this bundle, it has possibly moved to a different page. // In that case we want to change the pagination to the new page. - this.redirectToCurrentPage(currentSelectedEntry); + this.redirectToCurrentPage(selectionAction.selectedEntry); + } + + if (selectionAction.action === 'Cancelled') { + // If the selection is cancelled (and returned to its original position), it is possible the previously selected + // bitstream is returned to a different page. In that case we want to change the pagination to the place where + // the bitstream was returned to. + this.redirectToOriginalPage(selectionAction.selectedEntry); } - // If the selection is cancelled or cleared, it is possible the selected bitstream is currently on a different page - // In that case we want to change the pagination to the place where the bitstream was returned to - if (hasNoValue(currentSelectedEntry) && hasValue(previousSelectedEntry) && previousSelectedEntry.bundle === this.bundle) { - this.redirectToOriginalPage(previousSelectedEntry); + if (selectionAction.action === 'Cleared') { + // If the selection is cleared, it is possible the previously selected bitstream is on a different page. In that + // case we want to change the pagination to the place where the bitstream is. + this.redirectToCurrentPage(selectionAction.selectedEntry); } } From 8d93f22767edbf18396edc49b16629967f04c287 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 9 Oct 2024 12:01:33 +0200 Subject: [PATCH 199/822] 119176: Make table horizontally scrollable For most screen sizes, the ResponsiveTableSizes is enough to resize the table columns. On very small screens, or when zoomed in a lot, even the smallest column sizes are too big. To make it possible to view the rest of the content even in these situations, the ability to scroll horizontally is added. --- .../item-bitstreams/item-bitstreams.component.html | 2 +- .../item-bitstreams/item-bitstreams.component.scss | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index b9af2a7d18c..7789b682783 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -27,7 +27,7 @@ -
+
Date: Mon, 14 Oct 2024 11:30:48 +0200 Subject: [PATCH 200/822] 119176: Announce notification content in live region --- .../models/notification-options.model.ts | 12 +++- .../notifications-board.component.spec.ts | 49 ++++++++++++++- .../notifications-board.component.ts | 60 +++++++++++++------ 3 files changed, 97 insertions(+), 24 deletions(-) diff --git a/src/app/shared/notifications/models/notification-options.model.ts b/src/app/shared/notifications/models/notification-options.model.ts index 65011496b3f..c891781d9d0 100644 --- a/src/app/shared/notifications/models/notification-options.model.ts +++ b/src/app/shared/notifications/models/notification-options.model.ts @@ -4,19 +4,25 @@ export interface INotificationOptions { timeOut: number; clickToClose: boolean; animate: NotificationAnimationsType | string; + announceContentInLiveRegion: boolean; } export class NotificationOptions implements INotificationOptions { public timeOut: number; public clickToClose: boolean; public animate: any; + public announceContentInLiveRegion: boolean; - constructor(timeOut = 5000, - clickToClose = true, - animate: NotificationAnimationsType | string = NotificationAnimationsType.Scale) { + constructor( + timeOut = 5000, + clickToClose = true, + animate: NotificationAnimationsType | string = NotificationAnimationsType.Scale, + announceContentInLiveRegion: boolean = true, + ) { this.timeOut = timeOut; this.clickToClose = clickToClose; this.animate = animate; + this.announceContentInLiveRegion = announceContentInLiveRegion; } } diff --git a/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts b/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts index 08b9585a8c7..73f4e6b1b1f 100644 --- a/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts +++ b/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts @@ -1,4 +1,4 @@ -import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, inject, TestBed, waitForAsync, fakeAsync, flush } from '@angular/core/testing'; import { BrowserModule, By } from '@angular/platform-browser'; import { ChangeDetectorRef } from '@angular/core'; @@ -15,14 +15,20 @@ import uniqueId from 'lodash/uniqueId'; import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces'; import { NotificationsServiceStub } from '../../testing/notifications-service.stub'; import { cold } from 'jasmine-marbles'; +import { LiveRegionService } from '../../live-region/live-region.service'; +import { LiveRegionServiceStub } from '../../live-region/live-region.service.stub'; +import { NotificationOptions } from '../models/notification-options.model'; export const bools = { f: false, t: true }; describe('NotificationsBoardComponent', () => { let comp: NotificationsBoardComponent; let fixture: ComponentFixture; + let liveRegionService: LiveRegionServiceStub; beforeEach(waitForAsync(() => { + liveRegionService = new LiveRegionServiceStub(); + TestBed.configureTestingModule({ imports: [ BrowserModule, @@ -36,7 +42,9 @@ describe('NotificationsBoardComponent', () => { declarations: [NotificationsBoardComponent, NotificationComponent], // declare the test component providers: [ { provide: NotificationsService, useClass: NotificationsServiceStub }, - ChangeDetectorRef] + { provide: LiveRegionService, useValue: liveRegionService }, + ChangeDetectorRef, + ] }).compileComponents(); // compile template and css })); @@ -106,5 +114,42 @@ describe('NotificationsBoardComponent', () => { }); }); + describe('add', () => { + beforeEach(() => { + liveRegionService.addMessage.calls.reset(); + }); + + it('should announce content to the live region', fakeAsync(() => { + const notification = new Notification('id', NotificationType.Info, 'title', 'content'); + comp.add(notification); + + flush(); + + expect(liveRegionService.addMessage).toHaveBeenCalledWith('content'); + })); + + it('should not announce anything if there is no content', fakeAsync(() => { + const notification = new Notification('id', NotificationType.Info, 'title'); + comp.add(notification); + + flush(); + + expect(liveRegionService.addMessage).not.toHaveBeenCalled(); + })); + + it('should not announce the content if disabled', fakeAsync(() => { + const options = new NotificationOptions(); + options.announceContentInLiveRegion = false; + + const notification = new Notification('id', NotificationType.Info, 'title', 'content'); + notification.options = options; + comp.add(notification); + + flush(); + + expect(liveRegionService.addMessage).not.toHaveBeenCalled(); + })); + }); + }) ; diff --git a/src/app/shared/notifications/notifications-board/notifications-board.component.ts b/src/app/shared/notifications/notifications-board/notifications-board.component.ts index 97ae09c1a67..eaba6596786 100644 --- a/src/app/shared/notifications/notifications-board/notifications-board.component.ts +++ b/src/app/shared/notifications/notifications-board/notifications-board.component.ts @@ -9,7 +9,7 @@ import { } from '@angular/core'; import { select, Store } from '@ngrx/store'; -import { BehaviorSubject, Subscription } from 'rxjs'; +import { BehaviorSubject, Subscription, of as observableOf } from 'rxjs'; import difference from 'lodash/difference'; import { NotificationsService } from '../notifications.service'; @@ -18,6 +18,9 @@ import { notificationsStateSelector } from '../selectors'; import { INotification } from '../models/notification.model'; import { NotificationsState } from '../notifications.reducers'; import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces'; +import { LiveRegionService } from '../../live-region/live-region.service'; +import { hasNoValue, isNotEmptyOperator } from '../../empty.util'; +import { take } from 'rxjs/operators'; @Component({ selector: 'ds-notifications-board', @@ -49,9 +52,12 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy { */ public isPaused$: BehaviorSubject = new BehaviorSubject(false); - constructor(private service: NotificationsService, - private store: Store, - private cdr: ChangeDetectorRef) { + constructor( + private service: NotificationsService, + private store: Store, + private cdr: ChangeDetectorRef, + protected liveRegionService: LiveRegionService, + ) { } ngOnInit(): void { @@ -85,6 +91,7 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy { this.notifications.splice(this.notifications.length - 1, 1); } this.notifications.splice(0, 0, item); + this.addContentToLiveRegion(item); } else { // Remove the notification from the store // This notification was in the store, but not in this.notifications @@ -93,29 +100,44 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy { } } + /** + * Adds the content of the notification (if any) to the live region, so it can be announced by screen readers. + */ + private addContentToLiveRegion(item: INotification) { + let content = item.content; + + if (!item.options.announceContentInLiveRegion || hasNoValue(content)) { + return; + } + + if (typeof content === 'string') { + content = observableOf(content); + } + + content.pipe( + isNotEmptyOperator(), + take(1), + ).subscribe(contentStr => this.liveRegionService.addMessage(contentStr)); + } + + /** + * Whether to block the provided item because a duplicate notification with the exact same information already + * exists within the notifications array. + * @param item The item to check + * @return true if the notifications array already contains a notification with the exact same information as the + * provided item. false otherwise. + * @private + */ private block(item: INotification): boolean { const toCheck = item.html ? this.checkHtml : this.checkStandard; + this.notifications.forEach((notification) => { if (toCheck(notification, item)) { return true; } }); - if (this.notifications.length > 0) { - this.notifications.forEach((notification) => { - if (toCheck(notification, item)) { - return true; - } - }); - } - - let comp: INotification; - if (this.notifications.length > 0) { - comp = this.notifications[0]; - } else { - return false; - } - return toCheck(comp, item); + return false; } private checkStandard(checker: INotification, item: INotification): boolean { From 93f9341387755efc14d3272f7f9cca452ab91996 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 16 Oct 2024 14:11:01 +0200 Subject: [PATCH 201/822] 119176: Add aria-labels to buttons --- .../item-edit-bitstream-bundle.component.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html index efbdd8c69bc..06201b1cbe7 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.html @@ -40,6 +40,7 @@
-
+
+ + diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss index 985516ab121..7fd1f4b31e7 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss @@ -43,3 +43,13 @@ .scrollable-table { overflow-x: auto; } + +.disabled-overlay { + opacity: 0.6; +} + +.loading-overlay { + position: fixed; + top: 50%; + left: 50%; +} diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts index 6ee5dcb545f..72f85675c93 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts @@ -59,6 +59,11 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme */ itemUpdateSubscription: Subscription; + /** + * An observable which emits a boolean which represents whether the service is currently handling a 'move' request + */ + isProcessingMoveRequest: Observable; + constructor( public itemService: ItemDataService, public objectUpdatesService: ObjectUpdatesService, @@ -84,6 +89,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme */ postItemInit(): void { const bundlesOptions = this.itemBitstreamsService.getInitialBundlesPaginationOptions(); + this.isProcessingMoveRequest = this.itemBitstreamsService.getPerformingMoveRequest$(); this.bundles$ = this.itemService.getBundles(this.item.id, new PaginatedSearchOptions({pagination: bundlesOptions})).pipe( getFirstSucceededRemoteData(), diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts index f2af25f22f7..a0277ef064b 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts @@ -573,8 +573,6 @@ describe('ItemBitstreamsService', () => { const to = 7; const callback = createSpy('callbackFunction'); - console.log('bundle:', bundle); - it('should correctly create the Move request', () => { const expectedOperation: MoveOperation = { op: 'move', @@ -601,6 +599,22 @@ describe('ItemBitstreamsService', () => { service.performBitstreamMoveRequest(bundle, from, to, callback); expect(callback).toHaveBeenCalled(); }); + + it('should emit at the start and end of the request', fakeAsync(() => { + const emittedActions = []; + + service.getPerformingMoveRequest$().subscribe(selected => emittedActions.push(selected)); + + expect(emittedActions.length).toBe(1); + expect(emittedActions[0]).toBeFalse(); + + service.performBitstreamMoveRequest(bundle, from, to, callback); + tick(); + + expect(emittedActions.length).toBe(3); + expect(emittedActions[1]).toBeTrue(); + expect(emittedActions[2]).toBeFalse(); + })); }); describe('displayNotifications', () => { diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts index 7aac79fe695..f60693f7263 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts @@ -30,6 +30,10 @@ export class ItemBitstreamsServiceStub { performBitstreamMoveRequest = jasmine.createSpy('performBitstreamMoveRequest'); + getPerformingMoveRequest = jasmine.createSpy('getPerformingMoveRequest').and.returnValue(false); + + getPerformingMoveRequest$ = jasmine.createSpy('getPerformingMoveRequest$').and.returnValue(of(false)); + getInitialBundlesPaginationOptions = jasmine.createSpy('getInitialBundlesPaginationOptions').and .returnValue(new PaginationComponentOptions()); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts index 2329107c29d..9bbf3804873 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts @@ -119,7 +119,7 @@ export class ItemBitstreamsService { */ protected selectionAction$: BehaviorSubject = new BehaviorSubject(null); - protected isPerformingMoveRequest = false; + protected isPerformingMoveRequest: BehaviorSubject = new BehaviorSubject(false); constructor( protected notificationsService: NotificationsService, @@ -221,7 +221,7 @@ export class ItemBitstreamsService { cancelSelection() { const selected = this.getSelectedBitstream(); - if (hasNoValue(selected) || this.isPerformingMoveRequest) { + if (hasNoValue(selected) || this.getPerformingMoveRequest()) { return; } @@ -247,7 +247,7 @@ export class ItemBitstreamsService { moveSelectedBitstreamUp() { const selected = this.getSelectedBitstream(); - if (hasNoValue(selected) || this.isPerformingMoveRequest) { + if (hasNoValue(selected) || this.getPerformingMoveRequest()) { return; } @@ -272,7 +272,7 @@ export class ItemBitstreamsService { moveSelectedBitstreamDown() { const selected = this.getSelectedBitstream(); - if (hasNoValue(selected) || this.isPerformingMoveRequest) { + if (hasNoValue(selected) || this.getPerformingMoveRequest()) { return; } @@ -299,7 +299,7 @@ export class ItemBitstreamsService { * @param finish Optional: Function to execute once the response has been received */ performBitstreamMoveRequest(bundle: Bundle, fromIndex: number, toIndex: number, finish?: () => void) { - if (this.isPerformingMoveRequest) { + if (this.getPerformingMoveRequest()) { console.warn('Attempted to perform move request while previous request has not completed yet'); return; } @@ -310,18 +310,34 @@ export class ItemBitstreamsService { path: `/_links/bitstreams/${toIndex}/href`, }; - this.isPerformingMoveRequest = true; + this.announceLoading(); + this.isPerformingMoveRequest.next(true); this.bundleService.patch(bundle, [moveOperation]).pipe( getFirstCompletedRemoteData(), tap((response: RemoteData) => this.displayFailedResponseNotifications(MOVE_KEY, [response])), switchMap(() => this.requestService.setStaleByHrefSubstring(bundle.self)), take(1), ).subscribe(() => { - this.isPerformingMoveRequest = false; + console.log('got here!'); + this.isPerformingMoveRequest.next(false); finish?.(); }); } + /** + * Whether the service currently is processing a 'move' request + */ + getPerformingMoveRequest(): boolean { + return this.isPerformingMoveRequest.value; + } + + /** + * Returns an observable which emits when the service starts, or ends, processing a 'move' request + */ + getPerformingMoveRequest$(): Observable { + return this.isPerformingMoveRequest; + } + /** * Returns the pagination options to use when fetching the bundles */ @@ -526,4 +542,12 @@ export class ItemBitstreamsService { { bitstream: bitstreamName }); this.liveRegionService.addMessage(message); } + + /** + * Adds a message to the live region mentioning that the + */ + announceLoading() { + const message = this.translateService.instant('item.edit.bitstreams.edit.live.loading'); + this.liveRegionService.addMessage(message); + } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 519189ed691..9007982a728 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1954,6 +1954,8 @@ "item.edit.bitstreams.edit.live.clear": "{{ bitstream }} is no longer selected.", + "item.edit.bitstreams.edit.live.loading": "Waiting for move to complete.", + "item.edit.bitstreams.edit.live.select": "{{ bitstream }} is selected.", "item.edit.bitstreams.edit.live.move": "{{ bitstream }} is now in position {{ toIndex }}.", From 207e2ac9aee7fbc7958ae4aba332fa84c21bbea2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:08:36 +0000 Subject: [PATCH 254/822] Bump typescript from 5.3.3 to 5.4.5 Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.3.3 to 5.4.5. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.3.3...v5.4.5) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 654548a5282..0a15a4538e6 100644 --- a/package.json +++ b/package.json @@ -208,7 +208,7 @@ "sass-loader": "^12.6.0", "sass-resources-loader": "^2.2.5", "ts-node": "^8.10.2", - "typescript": "~5.3.3", + "typescript": "~5.4.5", "webpack": "5.95.0", "webpack-bundle-analyzer": "^4.8.0", "webpack-cli": "^5.1.4", diff --git a/yarn.lock b/yarn.lock index 8aecb589a8b..48a66bae419 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11332,10 +11332,10 @@ typescript@^2.5.0: resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w== -typescript@~5.3.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" - integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== +typescript@~5.4.5: + version "5.4.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" + integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== ua-parser-js@^0.7.30: version "0.7.38" From 9486ab5fa1d3d0fc11ceb9f5063bbda61a078924 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 18 Oct 2024 14:26:48 -0500 Subject: [PATCH 255/822] Fix code scanning alert no. 6: Incomplete string escaping or encoding Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> (cherry picked from commit 372444c50ac28a6c7f68b20695bea616a3ab8b7f) --- src/app/core/shared/metadata.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/core/shared/metadata.utils.ts b/src/app/core/shared/metadata.utils.ts index 87a90b53a31..e48b2b0c442 100644 --- a/src/app/core/shared/metadata.utils.ts +++ b/src/app/core/shared/metadata.utils.ts @@ -157,7 +157,7 @@ export class Metadata { const outputKeys: string[] = []; for (const inputKey of inputKeys) { if (inputKey.includes('*')) { - const inputKeyRegex = new RegExp('^' + inputKey.replace(/\./g, '\\.').replace(/\*/g, '.*') + '$'); + const inputKeyRegex = new RegExp('^' + inputKey.replace(/\\/g, '\\\\').replace(/\./g, '\\.').replace(/\*/g, '.*') + '$'); for (const mapKey of Object.keys(mdMap)) { if (!outputKeys.includes(mapKey) && inputKeyRegex.test(mapKey)) { outputKeys.push(mapKey); From bb84d86cf521fe6c25f12c3d07390289db87f96b Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 18 Oct 2024 14:26:48 -0500 Subject: [PATCH 256/822] Fix code scanning alert no. 6: Incomplete string escaping or encoding Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> (cherry picked from commit 372444c50ac28a6c7f68b20695bea616a3ab8b7f) --- src/app/core/shared/metadata.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/core/shared/metadata.utils.ts b/src/app/core/shared/metadata.utils.ts index 1ad10356fb5..f0290eac398 100644 --- a/src/app/core/shared/metadata.utils.ts +++ b/src/app/core/shared/metadata.utils.ts @@ -163,7 +163,7 @@ export class Metadata { const outputKeys: string[] = []; for (const inputKey of inputKeys) { if (inputKey.includes('*')) { - const inputKeyRegex = new RegExp('^' + inputKey.replace(/\./g, '\\.').replace(/\*/g, '.*') + '$'); + const inputKeyRegex = new RegExp('^' + inputKey.replace(/\\/g, '\\\\').replace(/\./g, '\\.').replace(/\*/g, '.*') + '$'); for (const mapKey of Object.keys(mdMap)) { if (!outputKeys.includes(mapKey) && inputKeyRegex.test(mapKey)) { outputKeys.push(mapKey); From 04410485a5e08f125b6a595115921a45d6982860 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 23 Oct 2024 13:55:36 -0500 Subject: [PATCH 257/822] Remove unused/unmaintained postcss-apply --- package.json | 1 - postcss.config.js | 1 - yarn.lock | 23 ++--------------------- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index c48d1e31545..65a03efe6c9 100644 --- a/package.json +++ b/package.json @@ -195,7 +195,6 @@ "ngx-mask": "14.2.4", "nodemon": "^2.0.22", "postcss": "^8.4", - "postcss-apply": "0.12.0", "postcss-import": "^14.0.0", "postcss-loader": "^4.0.3", "postcss-preset-env": "^7.4.2", diff --git a/postcss.config.js b/postcss.config.js index df092d1d39f..14013bd4f84 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -2,7 +2,6 @@ module.exports = { plugins: [ require('postcss-import')(), require('postcss-preset-env')(), - require('postcss-apply')(), require('postcss-responsive-type')() ] }; diff --git a/yarn.lock b/yarn.lock index 961ce5de268..dcebeb2972f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5517,9 +5517,11 @@ eslint-plugin-deprecation@^1.4.1: "eslint-plugin-dspace-angular-html@link:./lint/dist/src/rules/html": version "0.0.0" + uid "" "eslint-plugin-dspace-angular-ts@link:./lint/dist/src/rules/ts": version "0.0.0" + uid "" eslint-plugin-import-newlines@^1.3.1: version "1.4.0" @@ -8962,11 +8964,6 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -9043,14 +9040,6 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== -postcss-apply@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/postcss-apply/-/postcss-apply-0.12.0.tgz#11a47b271b14d81db97ed7f51a6c409d025a9c34" - integrity sha512-u8qZLyA9P86cD08IhqjSVV8tf1eGiKQ4fPvjcG3Ic/eOU65EAkDQClp8We7d15TG+RIWRVPSy9v7cJ2D9OReqw== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.14" - postcss-attribute-case-insensitive@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741" @@ -9389,14 +9378,6 @@ postcss@^6.0.6: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.14: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - postcss@^8.2.14, postcss@^8.4, postcss@^8.4.23, postcss@^8.4.33, postcss@^8.4.35: version "8.4.47" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" From e7ff5646084696d96d33c56bd0ea04568c375d85 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 23 Oct 2024 13:56:46 -0500 Subject: [PATCH 258/822] Remove unused postcss-responsive-type --- package.json | 1 - postcss.config.js | 3 +-- yarn.lock | 20 ++------------------ 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 65a03efe6c9..ae74beaae49 100644 --- a/package.json +++ b/package.json @@ -198,7 +198,6 @@ "postcss-import": "^14.0.0", "postcss-loader": "^4.0.3", "postcss-preset-env": "^7.4.2", - "postcss-responsive-type": "1.0.0", "react": "^16.14.0", "react-dom": "^16.14.0", "rimraf": "^3.0.2", diff --git a/postcss.config.js b/postcss.config.js index 14013bd4f84..f8b9666b312 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,7 +1,6 @@ module.exports = { plugins: [ require('postcss-import')(), - require('postcss-preset-env')(), - require('postcss-responsive-type')() + require('postcss-preset-env')() ] }; diff --git a/yarn.lock b/yarn.lock index dcebeb2972f..e63ae271126 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4164,7 +4164,7 @@ chalk@^1.1.1: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -9333,13 +9333,6 @@ postcss-replace-overflow-wrap@^4.0.0: resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== -postcss-responsive-type@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postcss-responsive-type/-/postcss-responsive-type-1.0.0.tgz#bb2d57d830beb9586ec4fda7994f07e37953aad8" - integrity sha512-O4kAKbc4RLnSkzcguJ6ojW67uOfeILaj+8xjsO0quLU94d8BKCqYwwFEUVRNbj0YcXA6d3uF/byhbaEATMRVig== - dependencies: - postcss "^6.0.6" - postcss-selector-not@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz#8f0a709bf7d4b45222793fc34409be407537556d" @@ -9369,15 +9362,6 @@ postcss@8.4.35: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^6.0.6: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.4.0" - postcss@^8.2.14, postcss@^8.4, postcss@^8.4.23, postcss@^8.4.33, postcss@^8.4.35: version "8.4.47" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" @@ -10904,7 +10888,7 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== -supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: +supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== From 5c877f56e92e07633efecab036a1493b8a06c465 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 23 Oct 2024 14:11:53 -0500 Subject: [PATCH 259/822] Remove unused/unmaintained postcss-apply --- package.json | 1 - postcss.config.js | 1 - yarn.lock | 21 --------------------- 3 files changed, 23 deletions(-) diff --git a/package.json b/package.json index 5197b720dc8..b3988ad5d04 100644 --- a/package.json +++ b/package.json @@ -185,7 +185,6 @@ "ngx-mask": "^13.1.7", "nodemon": "^2.0.22", "postcss": "^8.4", - "postcss-apply": "0.12.0", "postcss-import": "^14.0.0", "postcss-loader": "^4.0.3", "postcss-preset-env": "^7.4.2", diff --git a/postcss.config.js b/postcss.config.js index df092d1d39f..14013bd4f84 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -2,7 +2,6 @@ module.exports = { plugins: [ require('postcss-import')(), require('postcss-preset-env')(), - require('postcss-apply')(), require('postcss-responsive-type')() ] }; diff --git a/yarn.lock b/yarn.lock index 3f6a555df3d..3a1f482a968 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9279,11 +9279,6 @@ performance-now@^2.1.0: resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - picocolors@^1.0.0, picocolors@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -9352,14 +9347,6 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== -postcss-apply@0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/postcss-apply/-/postcss-apply-0.12.0.tgz" - integrity sha512-u8qZLyA9P86cD08IhqjSVV8tf1eGiKQ4fPvjcG3Ic/eOU65EAkDQClp8We7d15TG+RIWRVPSy9v7cJ2D9OReqw== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.14" - postcss-attribute-case-insensitive@^5.0.2: version "5.0.2" resolved "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz" @@ -9693,14 +9680,6 @@ postcss@^6.0.6: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.14: - version "7.0.39" - resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - postcss@^8.2.14, postcss@^8.3.11, postcss@^8.3.7, postcss@^8.4, postcss@^8.4.19: version "8.4.47" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" From 425078dc4e60aac89151c5ab516597faca2271f6 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 23 Oct 2024 14:13:33 -0500 Subject: [PATCH 260/822] Remove unused postcss-responsive-type --- package.json | 1 - postcss.config.js | 3 +-- yarn.lock | 20 ++------------------ 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index b3988ad5d04..aaf3c176562 100644 --- a/package.json +++ b/package.json @@ -188,7 +188,6 @@ "postcss-import": "^14.0.0", "postcss-loader": "^4.0.3", "postcss-preset-env": "^7.4.2", - "postcss-responsive-type": "1.0.0", "react": "^16.14.0", "react-dom": "^16.14.0", "rimraf": "^3.0.2", diff --git a/postcss.config.js b/postcss.config.js index 14013bd4f84..f8b9666b312 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,7 +1,6 @@ module.exports = { plugins: [ require('postcss-import')(), - require('postcss-preset-env')(), - require('postcss-responsive-type')() + require('postcss-preset-env')() ] }; diff --git a/yarn.lock b/yarn.lock index 3a1f482a968..b05cebf7cdb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3937,7 +3937,7 @@ chalk@^1.1.1: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -9635,13 +9635,6 @@ postcss-replace-overflow-wrap@^4.0.0: resolved "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz" integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== -postcss-responsive-type@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/postcss-responsive-type/-/postcss-responsive-type-1.0.0.tgz" - integrity sha512-O4kAKbc4RLnSkzcguJ6ojW67uOfeILaj+8xjsO0quLU94d8BKCqYwwFEUVRNbj0YcXA6d3uF/byhbaEATMRVig== - dependencies: - postcss "^6.0.6" - postcss-selector-not@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz" @@ -9671,15 +9664,6 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^6.0.6: - version "6.0.23" - resolved "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.4.0" - postcss@^8.2.14, postcss@^8.3.11, postcss@^8.3.7, postcss@^8.4, postcss@^8.4.19: version "8.4.47" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" @@ -11315,7 +11299,7 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== -supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: +supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== From 0ed8c05e1c40824d8d428a96c9fb5a0fddd5131a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 23 Oct 2024 15:01:54 -0500 Subject: [PATCH 261/822] Bump http-proxy-middleware from 1.0.5 to 2.0.7 --- package.json | 2 +- yarn.lock | 21 +++++---------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 5197b720dc8..d9251da2b94 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "express-rate-limit": "^5.1.3", "fast-json-patch": "^3.1.1", "filesize": "^6.1.0", - "http-proxy-middleware": "^1.0.5", + "http-proxy-middleware": "^2.0.7", "http-terminator": "^3.2.0", "isbot": "^5.1.17", "js-cookie": "2.2.1", diff --git a/yarn.lock b/yarn.lock index 3f6a555df3d..dd61f43ddba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2522,7 +2522,7 @@ "@types/react" "*" hoist-non-react-statics "^3.3.0" -"@types/http-proxy@^1.17.5", "@types/http-proxy@^1.17.8": +"@types/http-proxy@^1.17.8": version "1.17.10" resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.10.tgz" integrity sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g== @@ -6629,21 +6629,10 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" -http-proxy-middleware@^1.0.5: - version "1.3.1" - resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz" - integrity sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg== - dependencies: - "@types/http-proxy" "^1.17.5" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== +http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.6, http-proxy-middleware@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6" + integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" From 26f6dc562bd07597ad2bf161d1151d6824d88f9b Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 23 Oct 2024 14:57:51 -0500 Subject: [PATCH 262/822] Bump http-proxy-middleware from 1.0.5 to 2.0.7 --- package.json | 2 +- yarn.lock | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index c48d1e31545..c32aea3711c 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "express-rate-limit": "^5.1.3", "fast-json-patch": "^3.1.1", "filesize": "^6.1.0", - "http-proxy-middleware": "^1.0.5", + "http-proxy-middleware": "^2.0.7", "http-terminator": "^3.2.0", "isbot": "^5.1.17", "js-cookie": "2.2.1", diff --git a/yarn.lock b/yarn.lock index 961ce5de268..d93534d387c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2735,7 +2735,7 @@ resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== -"@types/http-proxy@^1.17.5", "@types/http-proxy@^1.17.8": +"@types/http-proxy@^1.17.8": version "1.17.15" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.15.tgz#12118141ce9775a6499ecb4c01d02f90fc839d36" integrity sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ== @@ -5517,9 +5517,11 @@ eslint-plugin-deprecation@^1.4.1: "eslint-plugin-dspace-angular-html@link:./lint/dist/src/rules/html": version "0.0.0" + uid "" "eslint-plugin-dspace-angular-ts@link:./lint/dist/src/rules/ts": version "0.0.0" + uid "" eslint-plugin-import-newlines@^1.3.1: version "1.4.0" @@ -6586,7 +6588,7 @@ http-proxy-agent@^7.0.0: agent-base "^7.1.0" debug "^4.3.4" -http-proxy-middleware@2.0.6, http-proxy-middleware@^2.0.3: +http-proxy-middleware@2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== @@ -6597,12 +6599,12 @@ http-proxy-middleware@2.0.6, http-proxy-middleware@^2.0.3: is-plain-obj "^3.0.0" micromatch "^4.0.2" -http-proxy-middleware@^1.0.5: - version "1.3.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz#43700d6d9eecb7419bf086a128d0f7205d9eb665" - integrity sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg== +http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6" + integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA== dependencies: - "@types/http-proxy" "^1.17.5" + "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" is-glob "^4.0.1" is-plain-obj "^3.0.0" From d4bb79ca18d20111786015bd4657c468a29985f2 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Tue, 22 Oct 2024 13:29:05 -0300 Subject: [PATCH 263/822] Issue 3426 - Aligning the browse button (cherry picked from commit ddafda33b8c4730a732a133147451390ee2c7ab7) --- src/app/shared/upload/uploader/uploader.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/shared/upload/uploader/uploader.component.html b/src/app/shared/upload/uploader/uploader.component.html index b1fd8199d83..4c1db13d133 100644 --- a/src/app/shared/upload/uploader/uploader.component.html +++ b/src/app/shared/upload/uploader/uploader.component.html @@ -19,8 +19,8 @@ (fileOver)="fileOverBase($event)" class="well ds-base-drop-zone mt-1 mb-3 text-muted">
- - + + {{dropMsg | translate}}{{'uploader.or' | translate}}
{{ dsoNameService.getName(undefined) }} + {{ dsoNameService.getName((group.object | async)?.payload) }} +
diff --git a/src/app/access-control/group-registry/group-form/group-form.component.ts b/src/app/access-control/group-registry/group-form/group-form.component.ts index 37ce30473f2..c0ea034fbb1 100644 --- a/src/app/access-control/group-registry/group-form/group-form.component.ts +++ b/src/app/access-control/group-registry/group-form/group-form.component.ts @@ -13,7 +13,7 @@ import { Observable, Subscription, combineLatest, } from 'rxjs'; -import { map, switchMap, take, debounceTime, startWith, filter } from 'rxjs/operators'; +import { map, switchMap, take, debounceTime } from 'rxjs/operators'; import { getCollectionEditRolesRoute } from '../../../collection-page/collection-page-routing-paths'; import { getCommunityEditRolesRoute } from '../../../community-page/community-page-routing-paths'; import { DSpaceObjectDataService } from '../../../core/data/dspace-object-data.service'; @@ -35,7 +35,7 @@ import { } from '../../../core/shared/operators'; import { AlertType } from '../../../shared/alert/aletr-type'; import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component'; -import { hasValue, isNotEmpty, hasValueOperator, hasNoValue } from '../../../shared/empty.util'; +import { hasValue, isNotEmpty, hasValueOperator } from '../../../shared/empty.util'; import { FormBuilderService } from '../../../shared/form/builder/form-builder.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { followLink } from '../../../shared/utils/follow-link-config.model'; @@ -164,11 +164,16 @@ export class GroupFormComponent implements OnInit, OnDestroy { this.activeGroupLinkedDSO$ = this.getActiveGroupLinkedDSO(); this.linkedEditRolesRoute$ = this.getLinkedEditRolesRoute(); this.canEdit$ = this.activeGroupLinkedDSO$.pipe( - filter((dso: DSpaceObject) => hasNoValue(dso)), - switchMap(() => this.activeGroup$), - hasValueOperator(), - switchMap((group: Group) => this.authorizationService.isAuthorized(FeatureID.CanDelete, group.self)), - startWith(false), + switchMap((dso: DSpaceObject) => { + if (hasValue(dso)) { + return [false]; + } else { + return this.activeGroup$.pipe( + hasValueOperator(), + switchMap((group: Group) => this.authorizationService.isAuthorized(FeatureID.CanDelete, group.self)), + ); + } + }), ); this.initialisePage(); } @@ -216,7 +221,7 @@ export class GroupFormComponent implements OnInit, OnDestroy { combineLatest([ this.activeGroup$, this.canEdit$, - this.activeGroupLinkedDSO$.pipe(take(1)), + this.activeGroupLinkedDSO$, ]).subscribe(([activeGroup, canEdit, linkedObject]) => { if (activeGroup != null) { @@ -224,25 +229,31 @@ export class GroupFormComponent implements OnInit, OnDestroy { // Disable group name exists validator this.formGroup.controls.groupName.clearAsyncValidators(); - if (linkedObject?.name) { - this.formBuilderService.insertFormGroupControl(1, this.formGroup, this.formModel, groupCommunityModel); - this.groupDescription = this.formGroup.get('groupCommunity'); + if (isNotEmpty(linkedObject?.name)) { + if (!this.formGroup.controls.groupCommunity) { + this.formBuilderService.insertFormGroupControl(1, this.formGroup, this.formModel, groupCommunityModel); + this.groupDescription = this.formGroup.get('groupCommunity'); + } this.formGroup.patchValue({ groupName: activeGroup.name, groupCommunity: linkedObject?.name ?? '', groupDescription: activeGroup.firstMetadataValue('dc.description'), }); } else { + this.formModel = [ + groupNameModel, + groupDescriptionModel, + ]; this.formGroup.patchValue({ groupName: activeGroup.name, groupDescription: activeGroup.firstMetadataValue('dc.description'), }); } - setTimeout(() => { - if (!canEdit || activeGroup.permanent) { - this.formGroup.disable(); - } - }, 200); + if (!canEdit || activeGroup.permanent) { + this.formGroup.disable(); + } else { + this.formGroup.enable(); + } } }) ); @@ -471,6 +482,7 @@ export class GroupFormComponent implements OnInit, OnDestroy { */ getLinkedEditRolesRoute(): Observable { return this.activeGroupLinkedDSO$.pipe( + hasValueOperator(), map((dso: DSpaceObject) => { switch ((dso as any).type) { case Community.type.value: @@ -478,7 +490,7 @@ export class GroupFormComponent implements OnInit, OnDestroy { case Collection.type.value: return getCollectionEditRolesRoute(dso.id); } - }) + }), ); } } From 8dd132d7a7b4d69864dfcd6fe0d4269c5726b86f Mon Sep 17 00:00:00 2001 From: DanGastardelli <55243638+DanGastardelli@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:15:53 -0300 Subject: [PATCH 290/822] Changing the bitstream title in the submission form to use the view component title, avoiding disappearance with changes to the form (cherry picked from commit fec4aa6df1bd6c5ea1ca9eeb10e4bc643a16d39e) --- .../sections/upload/file/section-upload-file.component.html | 3 +-- .../upload/file/view/section-upload-file-view.component.html | 5 +++-- .../upload/file/view/section-upload-file-view.component.ts | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/submission/sections/upload/file/section-upload-file.component.html b/src/app/submission/sections/upload/file/section-upload-file.component.html index da83e3f9a02..4698fdf68a6 100644 --- a/src/app/submission/sections/upload/file/section-upload-file.component.html +++ b/src/app/submission/sections/upload/file/section-upload-file.component.html @@ -18,7 +18,7 @@
-

{{fileName}} ({{fileData?.sizeBytes | dsFileSize}})

+
@@ -43,7 +43,6 @@

{{fileName}} ({{fileData?.sizeBytes | dsFileSize}})

-
diff --git a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.html b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.html index cc12b5dea63..dc72fbdad01 100644 --- a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.html +++ b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.html @@ -2,9 +2,10 @@ -
+

{{entry.value}} -

+ ({{fileData?.sizeBytes | dsFileSize}}) +
diff --git a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts index 0630a28a76b..7ab21fb85bd 100644 --- a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts +++ b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts @@ -18,6 +18,7 @@ import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submis import { isNotEmpty } from '../../../../../shared/empty.util'; import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; import { SubmissionSectionUploadAccessConditionsComponent } from '../../accessConditions/submission-section-upload-access-conditions.component'; +import { FileSizePipe } from "../../../../../shared/utils/file-size-pipe"; /** * This component allow to show bitstream's metadata @@ -31,7 +32,8 @@ import { SubmissionSectionUploadAccessConditionsComponent } from '../../accessCo TruncatePipe, NgIf, NgForOf, - ], + FileSizePipe +], standalone: true, }) export class SubmissionSectionUploadFileViewComponent implements OnInit { From 3104264cd4b1801cb1ab1ee8938d45374204ec9a Mon Sep 17 00:00:00 2001 From: DanGastardelli <55243638+DanGastardelli@users.noreply.github.com> Date: Wed, 2 Oct 2024 08:38:42 -0300 Subject: [PATCH 291/822] Adjusting spacing and good rules (cherry picked from commit df24a63a464c3f88adedf982cdf540241414a86a) --- .../upload/file/view/section-upload-file-view.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts index 7ab21fb85bd..378753a1e6b 100644 --- a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts +++ b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts @@ -18,7 +18,7 @@ import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submis import { isNotEmpty } from '../../../../../shared/empty.util'; import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; import { SubmissionSectionUploadAccessConditionsComponent } from '../../accessConditions/submission-section-upload-access-conditions.component'; -import { FileSizePipe } from "../../../../../shared/utils/file-size-pipe"; +import { FileSizePipe } from '../../../../../shared/utils/file-size-pipe'; /** * This component allow to show bitstream's metadata @@ -32,8 +32,8 @@ import { FileSizePipe } from "../../../../../shared/utils/file-size-pipe"; TruncatePipe, NgIf, NgForOf, - FileSizePipe -], + FileSizePipe, + ], standalone: true, }) export class SubmissionSectionUploadFileViewComponent implements OnInit { From 10f11a55fff372a40bb85250d433a54ed915caa9 Mon Sep 17 00:00:00 2001 From: DanGastardelli <55243638+DanGastardelli@users.noreply.github.com> Date: Wed, 2 Oct 2024 08:46:37 -0300 Subject: [PATCH 292/822] Adjusting spacing (cherry picked from commit 762bc8ce8c5a87a1dc7ba9763916addaabe06398) --- .../upload/file/view/section-upload-file-view.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts index 378753a1e6b..7b8e8704004 100644 --- a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts +++ b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts @@ -54,13 +54,13 @@ export class SubmissionSectionUploadFileViewComponent implements OnInit { * The bitstream's title key * @type {string} */ - public fileTitleKey = 'Title'; + public fileTitleKey: string = 'Title'; /** * The bitstream's description key * @type {string} */ - public fileDescrKey = 'Description'; + public fileDescrKey: string = 'Description'; public fileFormat!: string; From 784f5c180861f8d79aac119a951a42e1e455b10a Mon Sep 17 00:00:00 2001 From: DanGastardelli <55243638+DanGastardelli@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:01:56 -0300 Subject: [PATCH 293/822] Fix last commit (cherry picked from commit 62006c00cacf7e74661d6cc3dd4b5a53f47aeb72) --- .../upload/file/view/section-upload-file-view.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts index 7b8e8704004..378753a1e6b 100644 --- a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts +++ b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts @@ -54,13 +54,13 @@ export class SubmissionSectionUploadFileViewComponent implements OnInit { * The bitstream's title key * @type {string} */ - public fileTitleKey: string = 'Title'; + public fileTitleKey = 'Title'; /** * The bitstream's description key * @type {string} */ - public fileDescrKey: string = 'Description'; + public fileDescrKey = 'Description'; public fileFormat!: string; From fccfc93a10f895d065d67eb49a9c2c8bb0b8386b Mon Sep 17 00:00:00 2001 From: DanGastardelli <55243638+DanGastardelli@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:10:48 -0300 Subject: [PATCH 294/822] Import order adjustment (cherry picked from commit eeaac8965b8b82e8d21f712350781c3e7f627157) --- .../upload/file/view/section-upload-file-view.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts index 378753a1e6b..20e86a492dd 100644 --- a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts +++ b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts @@ -17,8 +17,8 @@ import { Metadata } from '../../../../../core/shared/metadata.utils'; import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submission/models/workspaceitem-section-upload-file.model'; import { isNotEmpty } from '../../../../../shared/empty.util'; import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; -import { SubmissionSectionUploadAccessConditionsComponent } from '../../accessConditions/submission-section-upload-access-conditions.component'; import { FileSizePipe } from '../../../../../shared/utils/file-size-pipe'; +import { SubmissionSectionUploadAccessConditionsComponent } from '../../accessConditions/submission-section-upload-access-conditions.component'; /** * This component allow to show bitstream's metadata From 7e827165e930d0235a8561aa8a0783e3aaa8856f Mon Sep 17 00:00:00 2001 From: DanGastardelli <55243638+DanGastardelli@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:24:46 -0300 Subject: [PATCH 295/822] Import order adjustment (cherry picked from commit 2643a459b6a1213b4edb16f245732ba0a1b32bcb) --- .../upload/file/view/section-upload-file-view.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts index 20e86a492dd..f065fc9e190 100644 --- a/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts +++ b/src/app/submission/sections/upload/file/view/section-upload-file-view.component.ts @@ -16,8 +16,8 @@ import { import { Metadata } from '../../../../../core/shared/metadata.utils'; import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submission/models/workspaceitem-section-upload-file.model'; import { isNotEmpty } from '../../../../../shared/empty.util'; -import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; import { FileSizePipe } from '../../../../../shared/utils/file-size-pipe'; +import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; import { SubmissionSectionUploadAccessConditionsComponent } from '../../accessConditions/submission-section-upload-access-conditions.component'; /** From 3b8a075049c52b569ebe1a7f0cb4d31808cdbf4d Mon Sep 17 00:00:00 2001 From: Nima Behforouz <92104872+nimabehforouz@users.noreply.github.com> Date: Tue, 29 Oct 2024 15:48:53 -0400 Subject: [PATCH 296/822] Update fr.json5 Translation updates to fr.json5 file regarding the Access Control sections. (cherry picked from commit 8d00d435c432db20409a2d01835442196a4b94e9) --- src/assets/i18n/fr.json5 | 96 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index 185576e186e..b2a03fad7dc 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -357,6 +357,18 @@ // "admin.access-control.epeople.breadcrumbs": "EPeople", "admin.access-control.epeople.breadcrumbs": "EPeople", + // "admin.access-control.epeople.edit.breadcrumbs": "New EPerson", + "admin.access-control.epeople.edit.breadcrumbs": "Nouvelle EPerson", + + // "admin.access-control.epeople.edit.title": "New EPerson", + "admin.access-control.epeople.edit.title": "Nouvelle EPerson", + + // "admin.access-control.epeople.add.breadcrumbs": "Add EPerson", + "admin.access-control.epeople.add.breadcrumbs": "Ajouter EPerson", + + // "admin.access-control.epeople.add.title": "Add EPerson", + "admin.access-control.epeople.add.title": "Ajouter EPerson", + // "admin.access-control.epeople.title": "EPeople", "admin.access-control.epeople.title": "EPeople", @@ -747,6 +759,30 @@ // "admin.access-control.groups.form.return": "Back", "admin.access-control.groups.form.return": "Retour", + // "admin.quality-assurance.breadcrumbs": "Quality Assurance", + "admin.quality-assurance.breadcrumbs": "Assurance qualité", + + // "admin.notifications.event.breadcrumbs": "Quality Assurance Suggestions", + "admin.notifications.event.breadcrumbs": "Suggestions d'assurance qualité", + + // "admin.notifications.event.page.title": "Quality Assurance Suggestions", + "admin.notifications.event.page.title": "Suggestions d'assurance qualité", + + // "admin.quality-assurance.page.title": "Quality Assurance", + "admin.quality-assurance.page.title": "Assurance qualité", + + // "admin.notifications.source.breadcrumbs": "Quality Assurance", + "admin.notifications.source.breadcrumbs": "Assurance qualité", + + // "admin.access-control.groups.form.tooltip.editGroupPage": "On this page, you can modify the properties and members of a group. In the top section, you can edit the group name and description, unless this is an admin group for a collection or community, in which case the group name and description are auto-generated and cannot be edited. In the following sections, you can edit group membership. See [the wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group) for more details.", + "admin.access-control.groups.form.tooltip.editGroupPage": "Sur cette page, vous pouvez modifier les propriétés et les membres d'un groupe. Dans la section supérieure, vous pouvez éditer le nom et la description du groupe, sauf s'il s'agit d'un groupe d'administrateurs d'une collection ou d'une communauté ; dans ce cas, le nom et la description du groupe sont générés automatiquement et ne peuvent pas être modifiés. Dans les sections suivantes, vous pouvez modifier l'appartenance au groupe. Voir [le wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group) pour plus de détails.", + + // "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "To add or remove an EPerson to/from this group, either click the 'Browse All' button or use the search bar below to search for users (use the dropdown to the left of the search bar to choose whether to search by metadata or by email). Then click the plus icon for each user you wish to add in the list below, or the trash can icon for each user you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages.", + "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "Pour ajouter ou retirer une EPerson à/de ce groupe, cliquez sur le bouton « Parcourir tout », ou utilisez la barre de recherche ci-dessous pour rechercher des utilisateurs (utilisez le menu déroulant à gauche de la barre de recherche pour choisir si vous souhaitez effectuer la recherche par métadonnées ou par courriel). Ensuite, cliquez sur l'icône + pour chaque utilisateur que vous souhaitez ajouter dans la liste ci-dessous, ou sur l'icône de la corbeille pour chaque utilisateur que vous souhaitez retirer. La liste ci-dessous peut comporter plusieurs pages : utilisez les contrôles de pagination sous la liste pour naviguer vers les pages suivantes.", + + // "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "To add or remove a Subgroup to/from this group, either click the 'Browse All' button or use the search bar below to search for groups. Then click the plus icon for each group you wish to add in the list below, or the trash can icon for each group you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages.", + "admin.access-control.groups.form.tooltip.editGroup.addSubgroups": "Pour ajouter ou retirer un sous-groupe à/de ce groupe, cliquez sur le bouton « Parcourir tout », ou utilisez la barre de recherche ci-dessous pour rechercher des groupes. Ensuite, cliquez sur l'icône + pour chaque groupe que vous souhaitez ajouter dans la liste ci-dessous, ou sur l'icône de la corbeille pour chaque groupe que vous souhaitez retirer. La liste ci-dessous peut comporter plusieurs pages : utilisez les contrôles de pagination sous la liste pour naviguer vers les pages suivantes.", + //"admin.reports.collections.title": "Collection Filter Report", "admin.reports.collections.title": "Rapport de collections filtrées", @@ -1576,6 +1612,12 @@ // "collection.edit.return": "Back", "collection.edit.return": "Retour", + // "collection.edit.tabs.access-control.head": "Access Control", + "collection.edit.tabs.access-control.head": "Contrôle d'accès", + + // "collection.edit.tabs.access-control.title": "Collection Edit - Access Control", + "collection.edit.tabs.access-control.title": "Édition de Collection - Contrôle d'accès", + // "collection.edit.tabs.curate.head": "Curate", "collection.edit.tabs.curate.head": "Gestion du contenu", @@ -1932,6 +1974,12 @@ // "community.edit.tabs.curate.title": "Community Edit - Curate", "community.edit.tabs.curate.title": "Édition de communauté - Gestion du contenu", + // "community.edit.tabs.access-control.head": "Access Control", + "community.edit.tabs.access-control.head": "Contrôle d'accès", + + // "community.edit.tabs.access-control.title": "Community Edit - Access Control", + "community.edit.tabs.access-control.title": "Édition de Communauté - Contrôle d'accès", + // "community.edit.tabs.metadata.head": "Edit Metadata", "community.edit.tabs.metadata.head": "Éditer Métadonnées", @@ -3227,6 +3275,15 @@ // "item.edit.tabs.curate.title": "Item Edit - Curate", "item.edit.tabs.curate.title": "Édition d'Item - Gestion de contenu", + // "item.edit.curate.title": "Curate Item: {{item}}", + "item.edit.curate.title": "Gestion de contenu de l'Item: {{item}}", + + // "item.edit.tabs.access-control.head": "Access Control", + "item.edit.tabs.access-control.head": "Contrôle d'accès", + + // "item.edit.tabs.access-control.title": "Item Edit - Access Control", + "item.edit.tabs.access-control.title": "Édition de l'Item - Contrôle d'accès", + // "item.edit.tabs.metadata.head": "Metadata", "item.edit.tabs.metadata.head": "Métadonnées", @@ -6687,6 +6744,45 @@ //"access-control-cancel": "Cancel", "access-control-cancel": "Annuler", + // "item-access-control-title": "This form allows you to perform changes to the access conditions of the item's metadata or its bitstreams.", + "item-access-control-title": "Ce formulaire vous permet de modifier les conditions d'accès aux métadonnées de l'Item ou à ses Bitstreams.", + + // "access-control-execute": "Execute", + "access-control-execute": "Exécuter", + + // "access-control-add-more": "Add more", + "access-control-add-more": "Ajouter plus", + + // "access-control-remove": "Remove access condition", + "access-control-remove": "Supprimer la condition d'accès", + + // "access-control-select-bitstreams-modal.title": "Select bitstreams", + "access-control-select-bitstreams-modal.title": "Sélectionner les Bitstreams", + + // "access-control-select-bitstreams-modal.no-items": "No items to show.", + "access-control-select-bitstreams-modal.no-items": "Aucun Item à afficher.", + + // "access-control-select-bitstreams-modal.close": "Close", + "access-control-select-bitstreams-modal.close": "Fermer", + + // "access-control-option-label": "Access condition type", + "access-control-option-label": "Type de condition d'accès", + + // "access-control-option-note": "Choose an access condition to apply to selected objects.", + "access-control-option-note": "Choisissez une condition d'accès à appliquer aux objets sélectionnés.", + + // "access-control-option-start-date": "Grant access from", + "access-control-option-start-date": "Accorder l'accès à partir de", + + //"access-control-option-start-date-note": "Select the date from which the related access condition is applied", + "access-control-option-start-date-note": "Sélectionnez la date à partir de laquelle la condition d'accès liée est appliquée", + + // "access-control-option-end-date": "Grant access until", + "access-control-option-end-date": "Accorder l'accès jusqu'à", + + // "access-control-option-end-date-note": "Select the date until which the related access condition is applied", + "access-control-option-end-date-note": "Sélectionnez la date jusqu'à laquelle la condition d'accès liée est appliquée", + } From 585bbec5d53ebc8dedbafaf37f89c095addb883a Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Tue, 27 Aug 2024 17:02:12 -0300 Subject: [PATCH 297/822] Improving accessibility on the new user registration page (cherry picked from commit 0eb2d5ce587ece5d3573cad7534bcbb8df5c6ed4) --- .../register-email-form.component.html | 9 ++++++--- src/assets/i18n/en.json5 | 2 ++ src/assets/i18n/es.json5 | 3 +++ src/assets/i18n/pt-BR.json5 | 3 +++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index d4cf75b5630..b47790d1cb7 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -14,13 +14,16 @@

{{MESSAGE_PREFIX + '.header'|translate}}

+ type="text" id="email" formControlName="email" + [attr.aria-label]="'register-email.aria.label'|translate" + aria-describedby="email-errors-required email-error-not-valid" + [attr.aria-invalid]="form.get('email')?.invalid"/>
- + {{ MESSAGE_PREFIX + '.email.error.required' | translate }} - + {{ MESSAGE_PREFIX + '.email.error.not-email-form' | translate }} {{ MESSAGE_PREFIX + '.email.error.not-valid-domain' | translate: { domains: validMailDomains.join(', ') } }} diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 475e6437d66..84fbb5db968 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5369,4 +5369,6 @@ "process.overview.unknown.user": "Unknown", "browse.search-form.placeholder": "Search the repository", + + "register-email.aria.label": "Enter your e-mail address", } diff --git a/src/assets/i18n/es.json5 b/src/assets/i18n/es.json5 index 3bc98a9502a..6373f91652a 100644 --- a/src/assets/i18n/es.json5 +++ b/src/assets/i18n/es.json5 @@ -7831,5 +7831,8 @@ //"browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar en el repositorio", + // "register-email.aria.label": "Enter your e-mail address", + "register-email.aria.label": "Introduzca su dirección de correo electrónico", + } diff --git a/src/assets/i18n/pt-BR.json5 b/src/assets/i18n/pt-BR.json5 index aae51b36719..09c6cbf6306 100644 --- a/src/assets/i18n/pt-BR.json5 +++ b/src/assets/i18n/pt-BR.json5 @@ -7857,4 +7857,7 @@ //"browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar no repositório", + + // "register-email.aria.label": "Enter your e-mail address", + "register-email.aria.label": "Digite seu e-mail", } From a6b45f777cbfdafd4bf104cff81c9ed8f3a7460c Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 5 Sep 2024 09:35:55 -0300 Subject: [PATCH 298/822] Code refactoring - Accessibility on the new user registration and forgotten password forms (cherry picked from commit f00eae67602c3b1d12c5f8fcf43db774a7a70e11) --- .../register-email-form/register-email-form.component.html | 4 ++-- src/assets/i18n/en.json5 | 4 +++- src/assets/i18n/es.json5 | 7 +++++-- src/assets/i18n/pt-BR.json5 | 7 +++++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index b47790d1cb7..9192226b1ea 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -15,9 +15,9 @@

{{MESSAGE_PREFIX + '.header'|translate}}

for="email">{{MESSAGE_PREFIX + '.email' | translate}} + [attr.aria-invalid]="email.invalid"/>
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 84fbb5db968..56439dee436 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5370,5 +5370,7 @@ "browse.search-form.placeholder": "Search the repository", - "register-email.aria.label": "Enter your e-mail address", + "register-page.registration.aria.label": "Enter your e-mail address", + + "forgot-email.form.aria.label": "Enter your e-mail address", } diff --git a/src/assets/i18n/es.json5 b/src/assets/i18n/es.json5 index 6373f91652a..dfdf4ca6281 100644 --- a/src/assets/i18n/es.json5 +++ b/src/assets/i18n/es.json5 @@ -7831,8 +7831,11 @@ //"browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar en el repositorio", - // "register-email.aria.label": "Enter your e-mail address", - "register-email.aria.label": "Introduzca su dirección de correo electrónico", + // "register-page.registration.aria.label": "Enter your e-mail address", + "register-page.registration.aria.label": "Introduzca su dirección de correo electrónico", + + // "forgot-email.form.aria.label": "Enter your e-mail address", + "forgot-email.form.aria.label": "Introduzca su dirección de correo electrónico", } diff --git a/src/assets/i18n/pt-BR.json5 b/src/assets/i18n/pt-BR.json5 index 09c6cbf6306..eebf8968895 100644 --- a/src/assets/i18n/pt-BR.json5 +++ b/src/assets/i18n/pt-BR.json5 @@ -7858,6 +7858,9 @@ //"browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar no repositório", - // "register-email.aria.label": "Enter your e-mail address", - "register-email.aria.label": "Digite seu e-mail", + // "register-page.registration.aria.label": "Enter your e-mail address", + "register-page.registration.aria.label": "Digite seu e-mail", + + // "forgot-email.form.aria.label": "Enter your e-mail address", + "forgot-email.form.aria.label": "Digite seu e-mail", } From 3b3fa4f643ca96e81216963018b826d8989545ec Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 11:27:10 -0300 Subject: [PATCH 299/822] Dynamic aria-describedby attribute (cherry picked from commit e629d9edf0d2177953950f5e145bf49ff1203f88) --- .../register-email-form.component.html | 2 +- .../register-email-form.component.spec.ts | 35 +++++++++++++++++++ .../register-email-form.component.ts | 26 ++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index 9192226b1ea..a3ccc4bce8a 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -16,7 +16,7 @@

{{MESSAGE_PREFIX + '.header'|translate}}

diff --git a/src/app/register-email-form/register-email-form.component.spec.ts b/src/app/register-email-form/register-email-form.component.spec.ts index 9e852d94913..67b87a974c7 100644 --- a/src/app/register-email-form/register-email-form.component.spec.ts +++ b/src/app/register-email-form/register-email-form.component.spec.ts @@ -192,4 +192,39 @@ describe('RegisterEmailFormComponent', () => { expect(router.navigate).not.toHaveBeenCalled(); })); }); + describe('ariaDescribedby', () => { + it('should have required error message when email is empty', () => { + comp.form.patchValue({ email: '' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toContain('email-errors-required'); + }); + + it('should have invalid email error message when email is invalid', () => { + comp.form.patchValue({ email: 'invalid-email' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toContain('email-error-not-valid'); + }); + + it('should clear ariaDescribedby when email is valid', () => { + comp.form.patchValue({ email: 'valid@email.com' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toBe(''); + }); + + it('should update ariaDescribedby on value changes', () => { + spyOn(comp, 'checkEmailValidity').and.callThrough(); + + comp.form.patchValue({ email: '' }); + expect(comp.ariaDescribedby).toContain('email-errors-required'); + + comp.form.patchValue({ email: 'invalid-email' }); + expect(comp.ariaDescribedby).toContain('email-error-not-valid'); + + comp.form.patchValue({ email: 'valid@email.com' }); + expect(comp.ariaDescribedby).toBe(''); + }); + }); }); diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index df7e9bea5ef..0ba37a90903 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -66,6 +66,11 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { subscriptions: Subscription[] = []; + /** + * Stores error messages related to the email field + */ + ariaDescribedby: string = ''; + captchaVersion(): Observable { return this.googleRecaptchaService.captchaVersion(); } @@ -135,6 +140,13 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { this.disableUntilChecked = res; this.changeDetectorRef.detectChanges(); })); + + /** + * Subscription to email field value changes + */ + this.subscriptions.push(this.email.valueChanges.subscribe(() => { + this.checkEmailValidity(); + })); } /** @@ -248,4 +260,18 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { } } + checkEmailValidity() { + const descriptions = []; + + if (this.email.errors?.required) { + descriptions.push('email-errors-required'); + } + + if (this.email.errors?.pattern || this.email.errors?.email) { + descriptions.push('email-error-not-valid'); + } + + this.ariaDescribedby = descriptions.join(' '); + } + } From c330e83095c844c3db61e4be47499f793c0c1773 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 11:39:34 -0300 Subject: [PATCH 300/822] Resolving a wrongly declared variable error (cherry picked from commit 7b72a5f0c26514eb07f58faf3470c89fe9729d6f) --- src/app/register-email-form/register-email-form.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index 0ba37a90903..1d8a6d34742 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -69,7 +69,7 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { /** * Stores error messages related to the email field */ - ariaDescribedby: string = ''; + ariaDescribedby = ''; captchaVersion(): Observable { return this.googleRecaptchaService.captchaVersion(); From 1fad3cffc7c78dd52380ca21006ea2aa17ada847 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 15:01:54 -0300 Subject: [PATCH 301/822] Simplifying the implementation of dynamic aria-describedby (cherry picked from commit fa6e85d6db5a671038e8e27968701b46520154df) --- .../register-email-form.component.html | 2 +- .../register-email-form.component.spec.ts | 35 ------------------- .../register-email-form.component.ts | 28 +-------------- 3 files changed, 2 insertions(+), 63 deletions(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index a3ccc4bce8a..f6f4880ab6e 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -16,7 +16,7 @@

{{MESSAGE_PREFIX + '.header'|translate}}

diff --git a/src/app/register-email-form/register-email-form.component.spec.ts b/src/app/register-email-form/register-email-form.component.spec.ts index 67b87a974c7..9e852d94913 100644 --- a/src/app/register-email-form/register-email-form.component.spec.ts +++ b/src/app/register-email-form/register-email-form.component.spec.ts @@ -192,39 +192,4 @@ describe('RegisterEmailFormComponent', () => { expect(router.navigate).not.toHaveBeenCalled(); })); }); - describe('ariaDescribedby', () => { - it('should have required error message when email is empty', () => { - comp.form.patchValue({ email: '' }); - comp.checkEmailValidity(); - - expect(comp.ariaDescribedby).toContain('email-errors-required'); - }); - - it('should have invalid email error message when email is invalid', () => { - comp.form.patchValue({ email: 'invalid-email' }); - comp.checkEmailValidity(); - - expect(comp.ariaDescribedby).toContain('email-error-not-valid'); - }); - - it('should clear ariaDescribedby when email is valid', () => { - comp.form.patchValue({ email: 'valid@email.com' }); - comp.checkEmailValidity(); - - expect(comp.ariaDescribedby).toBe(''); - }); - - it('should update ariaDescribedby on value changes', () => { - spyOn(comp, 'checkEmailValidity').and.callThrough(); - - comp.form.patchValue({ email: '' }); - expect(comp.ariaDescribedby).toContain('email-errors-required'); - - comp.form.patchValue({ email: 'invalid-email' }); - expect(comp.ariaDescribedby).toContain('email-error-not-valid'); - - comp.form.patchValue({ email: 'valid@email.com' }); - expect(comp.ariaDescribedby).toBe(''); - }); - }); }); diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index 1d8a6d34742..42be43aab37 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -66,11 +66,6 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { subscriptions: Subscription[] = []; - /** - * Stores error messages related to the email field - */ - ariaDescribedby = ''; - captchaVersion(): Observable { return this.googleRecaptchaService.captchaVersion(); } @@ -140,13 +135,6 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { this.disableUntilChecked = res; this.changeDetectorRef.detectChanges(); })); - - /** - * Subscription to email field value changes - */ - this.subscriptions.push(this.email.valueChanges.subscribe(() => { - this.checkEmailValidity(); - })); } /** @@ -259,19 +247,5 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { console.warn(`Unimplemented notification '${key}' from reCaptcha service`); } } - - checkEmailValidity() { - const descriptions = []; - - if (this.email.errors?.required) { - descriptions.push('email-errors-required'); - } - - if (this.email.errors?.pattern || this.email.errors?.email) { - descriptions.push('email-error-not-valid'); - } - - this.ariaDescribedby = descriptions.join(' '); - } - + } From 1011468273f2887b21e77bf687285acb240d3e53 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 15:07:22 -0300 Subject: [PATCH 302/822] Adjusting spaces in ts (cherry picked from commit 009da08177f31d049c2094151d8485c157ee0ede) --- src/app/register-email-form/register-email-form.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index 42be43aab37..c8ca0cc7109 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -247,5 +247,4 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { console.warn(`Unimplemented notification '${key}' from reCaptcha service`); } } - } From b041601006bafe81ed6c0658418a0d7369a921cd Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Tue, 27 Aug 2024 17:02:12 -0300 Subject: [PATCH 303/822] Improving accessibility on the new user registration page (cherry picked from commit 0eb2d5ce587ece5d3573cad7534bcbb8df5c6ed4) --- .../register-email-form.component.html | 9 ++++++--- src/assets/i18n/en.json5 | 2 ++ src/assets/i18n/es.json5 | 3 +++ src/assets/i18n/pt-BR.json5 | 3 +++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index a38c4a81c02..740018392cc 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -14,13 +14,16 @@

{{MESSAGE_PREFIX + '.header'|translate}}

+ type="text" id="email" formControlName="email" + [attr.aria-label]="'register-email.aria.label'|translate" + aria-describedby="email-errors-required email-error-not-valid" + [attr.aria-invalid]="form.get('email')?.invalid"/>
- + {{ MESSAGE_PREFIX + '.email.error.required' | translate }} - + {{ MESSAGE_PREFIX + '.email.error.not-email-form' | translate }} {{ MESSAGE_PREFIX + '.email.error.not-valid-domain' | translate: { domains: validMailDomains.join(', ') } }} diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 7c106f3c706..43b12b92d26 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -6741,4 +6741,6 @@ "item.page.cc.license.disclaimer": "Except where otherwised noted, this item's license is described as", "browse.search-form.placeholder": "Search the repository", + + "register-email.aria.label": "Enter your e-mail address", } diff --git a/src/assets/i18n/es.json5 b/src/assets/i18n/es.json5 index 55962d25b5f..0306c5a9bbf 100644 --- a/src/assets/i18n/es.json5 +++ b/src/assets/i18n/es.json5 @@ -8152,5 +8152,8 @@ //"browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar en el repositorio", + // "register-email.aria.label": "Enter your e-mail address", + "register-email.aria.label": "Introduzca su dirección de correo electrónico", + } diff --git a/src/assets/i18n/pt-BR.json5 b/src/assets/i18n/pt-BR.json5 index c3b26a09d28..6f4f94d464f 100644 --- a/src/assets/i18n/pt-BR.json5 +++ b/src/assets/i18n/pt-BR.json5 @@ -10249,4 +10249,7 @@ //"browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar no repositório", + + // "register-email.aria.label": "Enter your e-mail address", + "register-email.aria.label": "Digite seu e-mail", } From 58612ce22738ed1af97bed94c2e3dd4554005197 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 5 Sep 2024 09:35:55 -0300 Subject: [PATCH 304/822] Code refactoring - Accessibility on the new user registration and forgotten password forms (cherry picked from commit f00eae67602c3b1d12c5f8fcf43db774a7a70e11) --- .../register-email-form/register-email-form.component.html | 4 ++-- src/assets/i18n/en.json5 | 4 +++- src/assets/i18n/es.json5 | 7 +++++-- src/assets/i18n/pt-BR.json5 | 7 +++++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index 740018392cc..8fd17157d73 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -15,9 +15,9 @@

{{MESSAGE_PREFIX + '.header'|translate}}

for="email">{{MESSAGE_PREFIX + '.email' | translate}} + [attr.aria-invalid]="email.invalid"/>
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 43b12b92d26..0ba1f5476b0 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -6742,5 +6742,7 @@ "browse.search-form.placeholder": "Search the repository", - "register-email.aria.label": "Enter your e-mail address", + "register-page.registration.aria.label": "Enter your e-mail address", + + "forgot-email.form.aria.label": "Enter your e-mail address", } diff --git a/src/assets/i18n/es.json5 b/src/assets/i18n/es.json5 index 0306c5a9bbf..25dfb54ca21 100644 --- a/src/assets/i18n/es.json5 +++ b/src/assets/i18n/es.json5 @@ -8152,8 +8152,11 @@ //"browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar en el repositorio", - // "register-email.aria.label": "Enter your e-mail address", - "register-email.aria.label": "Introduzca su dirección de correo electrónico", + // "register-page.registration.aria.label": "Enter your e-mail address", + "register-page.registration.aria.label": "Introduzca su dirección de correo electrónico", + + // "forgot-email.form.aria.label": "Enter your e-mail address", + "forgot-email.form.aria.label": "Introduzca su dirección de correo electrónico", } diff --git a/src/assets/i18n/pt-BR.json5 b/src/assets/i18n/pt-BR.json5 index 6f4f94d464f..9ebdc5fbbf7 100644 --- a/src/assets/i18n/pt-BR.json5 +++ b/src/assets/i18n/pt-BR.json5 @@ -10250,6 +10250,9 @@ //"browse.search-form.placeholder": "Search the repository", "browse.search-form.placeholder": "Buscar no repositório", - // "register-email.aria.label": "Enter your e-mail address", - "register-email.aria.label": "Digite seu e-mail", + // "register-page.registration.aria.label": "Enter your e-mail address", + "register-page.registration.aria.label": "Digite seu e-mail", + + // "forgot-email.form.aria.label": "Enter your e-mail address", + "forgot-email.form.aria.label": "Digite seu e-mail", } From c71e7139cae90d554acd8f1f2a7854b584782f47 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 11:27:10 -0300 Subject: [PATCH 305/822] Dynamic aria-describedby attribute (cherry picked from commit e629d9edf0d2177953950f5e145bf49ff1203f88) --- .../register-email-form.component.html | 2 +- .../register-email-form.component.spec.ts | 35 +++++++++++++++++++ .../register-email-form.component.ts | 26 ++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index 8fd17157d73..d830fc441de 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -16,7 +16,7 @@

{{MESSAGE_PREFIX + '.header'|translate}}

diff --git a/src/app/register-email-form/register-email-form.component.spec.ts b/src/app/register-email-form/register-email-form.component.spec.ts index eda9110dc79..c622b9c0e97 100644 --- a/src/app/register-email-form/register-email-form.component.spec.ts +++ b/src/app/register-email-form/register-email-form.component.spec.ts @@ -210,4 +210,39 @@ describe('RegisterEmailFormComponent', () => { expect(router.navigate).not.toHaveBeenCalled(); })); }); + describe('ariaDescribedby', () => { + it('should have required error message when email is empty', () => { + comp.form.patchValue({ email: '' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toContain('email-errors-required'); + }); + + it('should have invalid email error message when email is invalid', () => { + comp.form.patchValue({ email: 'invalid-email' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toContain('email-error-not-valid'); + }); + + it('should clear ariaDescribedby when email is valid', () => { + comp.form.patchValue({ email: 'valid@email.com' }); + comp.checkEmailValidity(); + + expect(comp.ariaDescribedby).toBe(''); + }); + + it('should update ariaDescribedby on value changes', () => { + spyOn(comp, 'checkEmailValidity').and.callThrough(); + + comp.form.patchValue({ email: '' }); + expect(comp.ariaDescribedby).toContain('email-errors-required'); + + comp.form.patchValue({ email: 'invalid-email' }); + expect(comp.ariaDescribedby).toContain('email-error-not-valid'); + + comp.form.patchValue({ email: 'valid@email.com' }); + expect(comp.ariaDescribedby).toBe(''); + }); + }); }); diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index ac13abb865e..3c207aae713 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -109,6 +109,11 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { subscriptions: Subscription[] = []; + /** + * Stores error messages related to the email field + */ + ariaDescribedby: string = ''; + captchaVersion(): Observable { return this.googleRecaptchaService.captchaVersion(); } @@ -178,6 +183,13 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { this.disableUntilChecked = res; this.changeDetectorRef.detectChanges(); })); + + /** + * Subscription to email field value changes + */ + this.subscriptions.push(this.email.valueChanges.subscribe(() => { + this.checkEmailValidity(); + })); } /** @@ -291,4 +303,18 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { } } + checkEmailValidity() { + const descriptions = []; + + if (this.email.errors?.required) { + descriptions.push('email-errors-required'); + } + + if (this.email.errors?.pattern || this.email.errors?.email) { + descriptions.push('email-error-not-valid'); + } + + this.ariaDescribedby = descriptions.join(' '); + } + } From 67cd8a989bed3aed4ede54c08bb7ed702821d636 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 11:39:34 -0300 Subject: [PATCH 306/822] Resolving a wrongly declared variable error (cherry picked from commit 7b72a5f0c26514eb07f58faf3470c89fe9729d6f) --- src/app/register-email-form/register-email-form.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index 3c207aae713..936d11063e2 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -112,7 +112,7 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { /** * Stores error messages related to the email field */ - ariaDescribedby: string = ''; + ariaDescribedby = ''; captchaVersion(): Observable { return this.googleRecaptchaService.captchaVersion(); From 45b6f251f34fd2a17bec103d9a3941b2d23c6436 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 15:01:54 -0300 Subject: [PATCH 307/822] Simplifying the implementation of dynamic aria-describedby (cherry picked from commit fa6e85d6db5a671038e8e27968701b46520154df) --- .../register-email-form.component.html | 2 +- .../register-email-form.component.spec.ts | 35 ------------------- .../register-email-form.component.ts | 28 +-------------- 3 files changed, 2 insertions(+), 63 deletions(-) diff --git a/src/app/register-email-form/register-email-form.component.html b/src/app/register-email-form/register-email-form.component.html index d830fc441de..2e93902ada9 100644 --- a/src/app/register-email-form/register-email-form.component.html +++ b/src/app/register-email-form/register-email-form.component.html @@ -16,7 +16,7 @@

{{MESSAGE_PREFIX + '.header'|translate}}

diff --git a/src/app/register-email-form/register-email-form.component.spec.ts b/src/app/register-email-form/register-email-form.component.spec.ts index c622b9c0e97..eda9110dc79 100644 --- a/src/app/register-email-form/register-email-form.component.spec.ts +++ b/src/app/register-email-form/register-email-form.component.spec.ts @@ -210,39 +210,4 @@ describe('RegisterEmailFormComponent', () => { expect(router.navigate).not.toHaveBeenCalled(); })); }); - describe('ariaDescribedby', () => { - it('should have required error message when email is empty', () => { - comp.form.patchValue({ email: '' }); - comp.checkEmailValidity(); - - expect(comp.ariaDescribedby).toContain('email-errors-required'); - }); - - it('should have invalid email error message when email is invalid', () => { - comp.form.patchValue({ email: 'invalid-email' }); - comp.checkEmailValidity(); - - expect(comp.ariaDescribedby).toContain('email-error-not-valid'); - }); - - it('should clear ariaDescribedby when email is valid', () => { - comp.form.patchValue({ email: 'valid@email.com' }); - comp.checkEmailValidity(); - - expect(comp.ariaDescribedby).toBe(''); - }); - - it('should update ariaDescribedby on value changes', () => { - spyOn(comp, 'checkEmailValidity').and.callThrough(); - - comp.form.patchValue({ email: '' }); - expect(comp.ariaDescribedby).toContain('email-errors-required'); - - comp.form.patchValue({ email: 'invalid-email' }); - expect(comp.ariaDescribedby).toContain('email-error-not-valid'); - - comp.form.patchValue({ email: 'valid@email.com' }); - expect(comp.ariaDescribedby).toBe(''); - }); - }); }); diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index 936d11063e2..69497a77035 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -109,11 +109,6 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { subscriptions: Subscription[] = []; - /** - * Stores error messages related to the email field - */ - ariaDescribedby = ''; - captchaVersion(): Observable { return this.googleRecaptchaService.captchaVersion(); } @@ -183,13 +178,6 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { this.disableUntilChecked = res; this.changeDetectorRef.detectChanges(); })); - - /** - * Subscription to email field value changes - */ - this.subscriptions.push(this.email.valueChanges.subscribe(() => { - this.checkEmailValidity(); - })); } /** @@ -302,19 +290,5 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { console.warn(`Unimplemented notification '${key}' from reCaptcha service`); } } - - checkEmailValidity() { - const descriptions = []; - - if (this.email.errors?.required) { - descriptions.push('email-errors-required'); - } - - if (this.email.errors?.pattern || this.email.errors?.email) { - descriptions.push('email-error-not-valid'); - } - - this.ariaDescribedby = descriptions.join(' '); - } - + } From ebc7a7548ea916a719d21d5b7baf7d12b41e468d Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Thu, 31 Oct 2024 15:07:22 -0300 Subject: [PATCH 308/822] Adjusting spaces in ts (cherry picked from commit 009da08177f31d049c2094151d8485c157ee0ede) --- src/app/register-email-form/register-email-form.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/register-email-form/register-email-form.component.ts b/src/app/register-email-form/register-email-form.component.ts index 69497a77035..fff8479cbe3 100644 --- a/src/app/register-email-form/register-email-form.component.ts +++ b/src/app/register-email-form/register-email-form.component.ts @@ -290,5 +290,4 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit { console.warn(`Unimplemented notification '${key}' from reCaptcha service`); } } - } From 26f4d1d329d21f1661b6e10bd06362897c7521d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:46:18 +0000 Subject: [PATCH 309/822] Bump sass from 1.80.4 to 1.80.6 in the sass group Bumps the sass group with 1 update: [sass](https://github.com/sass/dart-sass). Updates `sass` from 1.80.4 to 1.80.6 - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.80.4...1.80.6) --- updated-dependencies: - dependency-name: sass dependency-type: direct:development update-type: version-update:semver-patch dependency-group: sass ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e2923712c01..67e416e6e10 100644 --- a/package.json +++ b/package.json @@ -186,7 +186,7 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^16.14.0", "rimraf": "^3.0.2", - "sass": "~1.80.4", + "sass": "~1.80.6", "sass-loader": "^12.6.0", "sass-resources-loader": "^2.2.5", "ts-node": "^8.10.2", diff --git a/yarn.lock b/yarn.lock index 21dcdd6fa50..69b50f026ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10234,15 +10234,16 @@ sass@1.58.1: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" -sass@^1.25.0, sass@~1.80.4: - version "1.80.4" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.80.4.tgz#bc0418fd796cad2f1a1309d8b4d7fe44b7027de0" - integrity sha512-rhMQ2tSF5CsuuspvC94nPM9rToiAFw2h3JTrLlgmNw1MH79v8Cr3DH6KF6o6r+8oofY3iYVPUf66KzC8yuVN1w== +sass@^1.25.0, sass@~1.80.6: + version "1.80.6" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.80.6.tgz#5d0aa55763984effe41e40019c9571ab73e6851f" + integrity sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg== dependencies: - "@parcel/watcher" "^2.4.1" chokidar "^4.0.0" immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" + optionalDependencies: + "@parcel/watcher" "^2.4.1" sax@^1.2.4: version "1.2.4" From 2eb120909b6b917d3f82852382429e391ace7bfd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:46:50 +0000 Subject: [PATCH 310/822] Bump compression from 1.7.4 to 1.7.5 Bumps [compression](https://github.com/expressjs/compression) from 1.7.4 to 1.7.5. - [Release notes](https://github.com/expressjs/compression/releases) - [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/compression/compare/1.7.4...1.7.5) --- updated-dependencies: - dependency-name: compression dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index e2923712c01..24c674d8d6f 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "cerialize": "0.1.18", "cli-progress": "^3.12.0", "colors": "^1.4.0", - "compression": "^1.7.4", + "compression": "^1.7.5", "cookie-parser": "1.4.7", "core-js": "^3.38.1", "date-fns": "^2.30.0", diff --git a/yarn.lock b/yarn.lock index 21dcdd6fa50..0208ffe1a27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2983,7 +2983,7 @@ abbrev@1, abbrev@^1.0.0: resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: +accepts@~1.3.4, accepts@~1.3.8: version "1.3.8" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -3710,11 +3710,6 @@ builtins@^5.0.0: dependencies: semver "^7.0.0" -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== - bytes@3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" @@ -4119,7 +4114,7 @@ commondir@^1.0.1: resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== -compressible@~2.0.16: +compressible@~2.0.18: version "2.0.18" resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== @@ -4134,17 +4129,17 @@ compression-webpack-plugin@^9.2.0: schema-utils "^4.0.0" serialize-javascript "^6.0.0" -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== +compression@^1.7.4, compression@^1.7.5: + version "1.7.5" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.5.tgz#fdd256c0a642e39e314c478f6c2cd654edd74c93" + integrity sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q== dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" + bytes "3.1.2" + compressible "~2.0.18" debug "2.6.9" + negotiator "~0.6.4" on-headers "~1.0.2" - safe-buffer "5.1.2" + safe-buffer "5.2.1" vary "~1.1.2" concat-map@0.0.1: @@ -8351,11 +8346,16 @@ needle@^3.1.0: iconv-lite "^0.6.3" sax "^1.2.4" -negotiator@0.6.3, negotiator@^0.6.3: +negotiator@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@^0.6.3, negotiator@~0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== + neo-async@^2.6.2: version "2.6.2" resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" @@ -10158,12 +10158,12 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== From 1b77530a3187f5e991a686876053b72a16d9ddcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:47:05 +0000 Subject: [PATCH 311/822] Bump @types/lodash from 4.17.12 to 4.17.13 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.12 to 4.17.13. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e2923712c01..6aef716bd57 100644 --- a/package.json +++ b/package.json @@ -145,7 +145,7 @@ "@types/grecaptcha": "^3.0.9", "@types/jasmine": "~3.6.0", "@types/js-cookie": "2.2.6", - "@types/lodash": "^4.17.12", + "@types/lodash": "^4.17.13", "@types/node": "^14.18.63", "@types/sanitize-html": "^2.13.0", "@typescript-eslint/eslint-plugin": "^5.62.0", diff --git a/yarn.lock b/yarn.lock index 21dcdd6fa50..a44db790f68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2539,10 +2539,10 @@ resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/lodash@^4.17.12": - version "4.17.12" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.12.tgz#25d71312bf66512105d71e55d42e22c36bcfc689" - integrity sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ== +"@types/lodash@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb" + integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg== "@types/mime@*": version "3.0.1" From 64e65a6e8c285b8ced61a73372d1f396a0c82f56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:56:51 +0000 Subject: [PATCH 312/822] Bump webpack from 5.95.0 to 5.96.1 in the webpack group Bumps the webpack group with 1 update: [webpack](https://github.com/webpack/webpack). Updates `webpack` from 5.95.0 to 5.96.1 - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.95.0...v5.96.1) --- updated-dependencies: - dependency-name: webpack dependency-type: direct:development update-type: version-update:semver-minor dependency-group: webpack ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 85 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index aa3121389b4..83f9cd90ed4 100644 --- a/package.json +++ b/package.json @@ -199,7 +199,7 @@ "sass-resources-loader": "^2.2.5", "ts-node": "^8.10.2", "typescript": "~5.4.5", - "webpack": "5.95.0", + "webpack": "5.96.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" } diff --git a/yarn.lock b/yarn.lock index 998c3415bb4..dc2889a8dd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2682,7 +2682,23 @@ resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.5.tgz#49d738257cc73bafe45c13cb8ff240683b4d5117" integrity sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg== -"@types/estree@1.0.6", "@types/estree@^1.0.5": +"@types/eslint-scope@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "9.6.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" + integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@1.0.6", "@types/estree@^1.0.5", "@types/estree@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== @@ -2742,7 +2758,7 @@ resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f" integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw== -"@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -3345,10 +3361,10 @@ acorn-walk@^8.1.1: dependencies: acorn "^8.11.0" -acorn@^8.11.0, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: - version "8.12.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" - integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +acorn@^8.11.0, acorn@^8.14.0, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== adjust-sourcemap-loader@^4.0.0: version "4.0.0" @@ -3892,15 +3908,15 @@ braces@^3.0.2, braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4.23.0, browserslist@^4.23.1, browserslist@^4.23.3: - version "4.23.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" - integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== +browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4.23.0, browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.24.0: + version "4.24.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" + integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== dependencies: - caniuse-lite "^1.0.30001646" - electron-to-chromium "^1.5.4" + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" node-releases "^2.0.18" - update-browserslist-db "^1.1.0" + update-browserslist-db "^1.1.1" buffer-crc32@~0.2.3: version "0.2.13" @@ -4008,6 +4024,11 @@ caniuse-lite@^1.0.30001591, caniuse-lite@^1.0.30001646: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001659.tgz#f370c311ffbc19c4965d8ec0064a3625c8aaa7af" integrity sha512-Qxxyfv3RdHAfJcXelgf0hU4DFUVXBGTjqrBUZLUh8AtlGnsDo+CnncYtTd95+ZKfnANUOzxyIQCuU/UeBZBYoA== +caniuse-lite@^1.0.30001669: + version "1.0.30001677" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz#27c2e2c637e007cfa864a16f7dfe7cde66b38b5f" + integrity sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -4931,10 +4952,10 @@ ejs@^3.1.10: dependencies: jake "^10.8.5" -electron-to-chromium@^1.5.4: - version "1.5.18" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.18.tgz#5fe62b9d21efbcfa26571066502d94f3ed97e495" - integrity sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ== +electron-to-chromium@^1.5.41: + version "1.5.50" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz#d9ba818da7b2b5ef1f3dd32bce7046feb7e93234" + integrity sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw== element-resize-detector@^1.2.1: version "1.2.4" @@ -5234,7 +5255,7 @@ esbuild@^0.19.3: "@esbuild/win32-ia32" "0.19.12" "@esbuild/win32-x64" "0.19.12" -escalade@^3.1.1, escalade@^3.1.2: +escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== @@ -10850,13 +10871,13 @@ untildify@^4.0.0: resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== -update-browserslist-db@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" - integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" + escalade "^3.2.0" + picocolors "^1.1.0" uri-js@^4.2.2: version "4.4.1" @@ -11152,18 +11173,18 @@ webpack@5.94.0: watchpack "^2.4.1" webpack-sources "^3.2.3" -webpack@5.95.0: - version "5.95.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.95.0.tgz#8fd8c454fa60dad186fbe36c400a55848307b4c0" - integrity sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q== +webpack@5.96.1: + version "5.96.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.96.1.tgz#3676d1626d8312b6b10d0c18cc049fba7ac01f0c" + integrity sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA== dependencies: - "@types/estree" "^1.0.5" + "@types/eslint-scope" "^3.7.7" + "@types/estree" "^1.0.6" "@webassemblyjs/ast" "^1.12.1" "@webassemblyjs/wasm-edit" "^1.12.1" "@webassemblyjs/wasm-parser" "^1.12.1" - acorn "^8.7.1" - acorn-import-attributes "^1.9.5" - browserslist "^4.21.10" + acorn "^8.14.0" + browserslist "^4.24.0" chrome-trace-event "^1.0.2" enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" From 1484464232b8870c40b27f6efc9973bda24e2b3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:57:37 +0000 Subject: [PATCH 313/822] Bump compression from 1.7.4 to 1.7.5 Bumps [compression](https://github.com/expressjs/compression) from 1.7.4 to 1.7.5. - [Release notes](https://github.com/expressjs/compression/releases) - [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/compression/compare/1.7.4...1.7.5) --- updated-dependencies: - dependency-name: compression dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index aa3121389b4..6cb4246b593 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "cerialize": "0.1.18", "cli-progress": "^3.12.0", "colors": "^1.4.0", - "compression": "^1.7.4", + "compression": "^1.7.5", "cookie-parser": "1.4.7", "core-js": "^3.30.1", "date-fns": "^2.29.3", diff --git a/yarn.lock b/yarn.lock index 998c3415bb4..e4d0272be68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3320,7 +3320,7 @@ abbrev@^2.0.0: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: +accepts@~1.3.4, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -3920,11 +3920,6 @@ buffer@^5.5.0, buffer@^5.7.1: base64-js "^1.3.1" ieee754 "^1.1.13" -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== - bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -4258,7 +4253,7 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== -compressible@~2.0.16: +compressible@~2.0.18: version "2.0.18" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== @@ -4273,17 +4268,17 @@ compression-webpack-plugin@^9.2.0: schema-utils "^4.0.0" serialize-javascript "^6.0.0" -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== +compression@^1.7.4, compression@^1.7.5: + version "1.7.5" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.5.tgz#fdd256c0a642e39e314c478f6c2cd654edd74c93" + integrity sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q== dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" + bytes "3.1.2" + compressible "~2.0.18" debug "2.6.9" + negotiator "~0.6.4" on-headers "~1.0.2" - safe-buffer "5.1.2" + safe-buffer "5.2.1" vary "~1.1.2" concat-map@0.0.1: @@ -7925,11 +7920,16 @@ needle@^3.1.0: iconv-lite "^0.6.3" sax "^1.2.4" -negotiator@0.6.3, negotiator@^0.6.3: +negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@^0.6.3, negotiator@~0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== + neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" From 76b73405897b98cb89efd2e37ed23b881e98854b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:57:55 +0000 Subject: [PATCH 314/822] Bump @types/lodash from 4.17.12 to 4.17.13 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.12 to 4.17.13. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index aa3121389b4..a430cd6640a 100644 --- a/package.json +++ b/package.json @@ -146,7 +146,7 @@ "@types/grecaptcha": "^3.0.9", "@types/jasmine": "~3.6.0", "@types/js-cookie": "2.2.6", - "@types/lodash": "^4.17.12", + "@types/lodash": "^4.17.13", "@types/node": "^14.14.9", "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", diff --git a/yarn.lock b/yarn.lock index 998c3415bb4..ebb324ce656 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2752,10 +2752,10 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/lodash@^4.17.12": - version "4.17.12" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.12.tgz#25d71312bf66512105d71e55d42e22c36bcfc689" - integrity sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ== +"@types/lodash@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb" + integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg== "@types/mime@^1": version "1.3.5" From 2aaa32ae5f27594aaea2146c809352c7a8a02cc6 Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Thu, 31 Oct 2024 11:12:29 -0400 Subject: [PATCH 315/822] Complete tag translation in french for ORCID Contains all french translations for ORCID and Researcher Profile. (cherry picked from commit ac720033dcca82c0bbd8c6a9f8ac8b1d07ffb37e) --- src/assets/i18n/fr.json5 | 366 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index a73baacf2d4..9c0b85cfe4c 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -6241,6 +6241,372 @@ // "idle-modal.extend-session": "Extend session", "idle-modal.extend-session": "Prolonger la session", + //"researcher.profile.action.processing": "Processing...", + "researcher.profile.action.processing": "En traitement...", + + //"researcher.profile.associated": "Researcher profile associated", + "researcher.profile.associated": "Profil du chercheur associé", + + //"researcher.profile.change-visibility.fail": "An unexpected error occurs while changing the profile visibility", + "researcher.profile.change-visibility.fail": "Une erreur inattendue s'est produite pendant le changement apporté à la visibilité du profil.", + + //"researcher.profile.create.new": "Create new", + "researcher.profile.create.new": "Créer un nouveau", + + //"researcher.profile.create.success": "Researcher profile created successfully", + "researcher.profile.create.success": "Profil créé avec succès", + + //"researcher.profile.create.fail": "An error occurs during the researcher profile creation", + "researcher.profile.create.fail": "Une erreur s'est produite lors de la création du profil", + + //"researcher.profile.delete": "Delete", + "researcher.profile.delete": "Supprimer", + + //"researcher.profile.expose": "Expose", + "researcher.profile.expose": "Exposer", + + //"researcher.profile.hide": "Hide", + "researcher.profile.hide": "Cacher", + + //"researcher.profile.not.associated": "Researcher profile not yet associated", + "researcher.profile.not.associated": "Profil non associé", + + //"researcher.profile.view": "View", + "researcher.profile.view": "Voir", + + //"researcher.profile.private.visibility": "PRIVATE", + "researcher.profile.private.visibility": "PRIVÉ", + + //"researcher.profile.public.visibility": "PUBLIC", + "researcher.profile.public.visibility": "PUBLIC", + + //"researcher.profile.status": "Status:", + "researcher.profile.status": "Statut:", + + //"researcherprofile.claim.not-authorized": "You are not authorized to claim this item. For more details contact the administrator(s).", + "researcherprofile.claim.not-authorized": "Vous n'êtes pas autorisé à réclamer cet item. Pour plus de détails contacter la personne administratrice.", + + //"researcherprofile.error.claim.body": "An error occurred while claiming the profile, please try again later", + "researcherprofile.error.claim.body": "Une erreur s'est produite lors de la réclamation du profil, veuillez réessayer plus tard.", + + //"researcherprofile.error.claim.title": "Error", + "researcherprofile.error.claim.title": "Erreur", + + //"researcherprofile.success.claim.body": "Profile claimed with success", + "researcherprofile.success.claim.body": "Profil réclamé avec succès", + + //"researcherprofile.success.claim.title": "Success", + "researcherprofile.success.claim.title": "Succès", + + //"person.page.orcid.create": "Create an ORCID ID", + "person.page.orcid.create": "Créer un identifiant ORCID", + + //"person.page.orcid.granted-authorizations": "Granted authorizations", + "person.page.orcid.granted-authorizations": "Autorisations accordées", + + //"person.page.orcid.grant-authorizations": "Grant authorizations", + "person.page.orcid.grant-authorizations": "Accorder des autorisations", + + //"person.page.orcid.link": "Connect to ORCID ID", + "person.page.orcid.link": "Se connecter à ORCID", + + //"person.page.orcid.link.processing": "Linking profile to ORCID...", + "person.page.orcid.link.processing": "Liaison du profil avec ORCID en cours...", + + //"person.page.orcid.link.error.message": "Something went wrong while connecting the profile with ORCID. If the problem persists, contact the administrator.", + "person.page.orcid.link.error.message": "Quelque chose a échoué lors de la connection du profil avec ORCID. Si le problème persiste, contacter la personne administratice.", + + //"person.page.orcid.orcid-not-linked-message": "The ORCID iD of this profile ({{ orcid }}) has not yet been connected to an account on the ORCID registry or the connection is expired.", + "person.page.orcid.orcid-not-linked-message": "L'identifiant ORCID du profil ({{ orcid }}) n'a pas encore été connecté à une compte du registre ORCID ou la connection a expiré. ", + + //"person.page.orcid.unlink": "Disconnect from ORCID", + "person.page.orcid.unlink": "Déconnecter d'ORCID", + + //"person.page.orcid.unlink.processing": "Processing...", + "person.page.orcid.unlink.processing": "Traitement en cours...", + + //"person.page.orcid.missing-authorizations": "Missing authorizations", + "person.page.orcid.missing-authorizations": "Autorisations manquantes", + + //"person.page.orcid.missing-authorizations-message": "The following authorizations are missing:", + "person.page.orcid.missing-authorizations-message": "Les autorisations suivantes sont manquantes :", + + //"person.page.orcid.no-missing-authorizations-message": "Great! This box is empty, so you have granted all access rights to use all functions offers by your institution.", + "person.page.orcid.no-missing-authorizations-message": "Cette boite est vide, vous avez autorisé l'utilisation de toutes les fonctions proposées par votre organisation.", + + //"person.page.orcid.no-orcid-message": "No ORCID iD associated yet. By clicking on the button below it is possible to link this profile with an ORCID account.", + "person.page.orcid.no-orcid-message": "Aucun identifiant ORCID n'est encore associé. En cliquant sur le bouton ci-dessous, il est possible de lier ce profil à un compte ORCID.", + + //"person.page.orcid.profile-preferences": "Profile preferences", + "person.page.orcid.profile-preferences": "Préférences du profil", + + //"person.page.orcid.funding-preferences": "Funding preferences", + "person.page.orcid.funding-preferences": "Préférence pour la section Financement", + + //"person.page.orcid.publications-preferences": "Publication preferences", + "person.page.orcid.publications-preferences": "Préférence pour la section Publication", + + //"person.page.orcid.remove-orcid-message": "If you need to remove your ORCID, please contact the repository administrator", + "person.page.orcid.remove-orcid-message": "Si vous avez besoin de retirer votre ORCID, contacter la personne administratrice du dépôt.", + + //"person.page.orcid.save.preference.changes": "Update settings", + "person.page.orcid.save.preference.changes": "Mettre à jour les configurations", + + //"person.page.orcid.sync-profile.affiliation": "Affiliation", + "person.page.orcid.sync-profile.affiliation": "Affiliation", + + //"person.page.orcid.sync-profile.biographical": "Biographical data", + "person.page.orcid.sync-profile.biographical": "Données biographiques", + + //"person.page.orcid.sync-profile.education": "Education", + "person.page.orcid.sync-profile.education": "Éducation", + + //"person.page.orcid.sync-profile.identifiers": "Identifiers", + "person.page.orcid.sync-profile.identifiers": "Identifiants", + + //"person.page.orcid.sync-fundings.all": "All fundings", + "person.page.orcid.sync-fundings.all": "Tous les financements", + + //"person.page.orcid.sync-fundings.mine": "My fundings", + "person.page.orcid.sync-fundings.mine": "Mes financements", + + //"person.page.orcid.sync-fundings.my_selected": "Selected fundings", + "person.page.orcid.sync-fundings.my_selected": "Financements sélectionnés", + + //"person.page.orcid.sync-fundings.disabled": "Disabled", + "person.page.orcid.sync-fundings.disabled": "Désactivé", + + //"person.page.orcid.sync-publications.all": "All publications", + "person.page.orcid.sync-publications.all": "Toutes les publications", + + //"person.page.orcid.sync-publications.mine": "My publications", + "person.page.orcid.sync-publications.mine": "Mes publications", + + //"person.page.orcid.sync-publications.my_selected": "Selected publications", + "person.page.orcid.sync-publications.my_selected": "Publications sélectionnées", + + //"person.page.orcid.sync-publications.disabled": "Disabled", + "person.page.orcid.sync-publications.disabled": "Désactivé", + + //"person.page.orcid.sync-queue.discard": "Discard the change and do not synchronize with the ORCID registry", + "person.page.orcid.sync-queue.discard": "Ignorer les changements et ne pas synchroniser avec le registre ORCID.", + + //"person.page.orcid.sync-queue.discard.error": "The discarding of the ORCID queue record failed", + "person.page.orcid.sync-queue.discard.error": "L'annulation de la file d'attente ORCID a échoué.", + + //"person.page.orcid.sync-queue.discard.success": "The ORCID queue record have been discarded successfully", + "person.page.orcid.sync-queue.discard.success": "La file d'attente ORCID a été annulée avec succès.", + + //"person.page.orcid.sync-queue.empty-message": "The ORCID queue registry is empty", + "person.page.orcid.sync-queue.empty-message": "La file d'attente ORCID est vide.", + + //"person.page.orcid.sync-queue.table.header.type": "Type", + "person.page.orcid.sync-queue.table.header.type": "Type", + + //"person.page.orcid.sync-queue.table.header.description": "Description", + "person.page.orcid.sync-queue.table.header.description": "Description", + + //"person.page.orcid.sync-queue.table.header.action": "Action", + "person.page.orcid.sync-queue.table.header.action": "Action", + + //"person.page.orcid.sync-queue.description.affiliation": "Affiliations", + "person.page.orcid.sync-queue.description.affiliation": "Affiliations", + + //"person.page.orcid.sync-queue.description.country": "Country", + "person.page.orcid.sync-queue.description.country": "Pays", + + //"person.page.orcid.sync-queue.description.education": "Educations", + "person.page.orcid.sync-queue.description.education": "Éducation", + + //"person.page.orcid.sync-queue.description.external_ids": "External ids", + "person.page.orcid.sync-queue.description.external_ids": "Identifiants externes", + + //"person.page.orcid.sync-queue.description.other_names": "Other names", + "person.page.orcid.sync-queue.description.other_names": "Autres noms", + + //"person.page.orcid.sync-queue.description.qualification": "Qualifications", + "person.page.orcid.sync-queue.description.qualification": "Qualifications", + + //"person.page.orcid.sync-queue.description.researcher_urls": "Researcher urls", + "person.page.orcid.sync-queue.description.researcher_urls": "URLs du chercheur", + + //"person.page.orcid.sync-queue.description.keywords": "Keywords", + "person.page.orcid.sync-queue.description.keywords": "Mots clés", + + //"person.page.orcid.sync-queue.tooltip.insert": "Add a new entry in the ORCID registry", + "person.page.orcid.sync-queue.tooltip.insert": "Ajouter une nouvelle entrée dans le registre ORCID", + + //"person.page.orcid.sync-queue.tooltip.update": "Update this entry on the ORCID registry", + "person.page.orcid.sync-queue.tooltip.update": "Mettre à jour cette entrée dans le registre ORCID", + + //"person.page.orcid.sync-queue.tooltip.delete": "Remove this entry from the ORCID registry", + "person.page.orcid.sync-queue.tooltip.delete": "Supprimer cette entrée du registre ORCID", + + //"person.page.orcid.sync-queue.tooltip.publication": "Publication", + "person.page.orcid.sync-queue.tooltip.publication": "Publication", + + //"person.page.orcid.sync-queue.tooltip.project": "Project", + "person.page.orcid.sync-queue.tooltip.project": "Projet", + + //"person.page.orcid.sync-queue.tooltip.affiliation": "Affiliation", + "person.page.orcid.sync-queue.tooltip.affiliation": "Affiliation", + + //"person.page.orcid.sync-queue.tooltip.education": "Education", + "person.page.orcid.sync-queue.tooltip.education": "Éducation", + + //"person.page.orcid.sync-queue.tooltip.qualification": "Qualification", + "person.page.orcid.sync-queue.tooltip.qualification": "Qualification", + + //"person.page.orcid.sync-queue.tooltip.other_names": "Other name", + "person.page.orcid.sync-queue.tooltip.other_names": "Autre nom", + + //"person.page.orcid.sync-queue.tooltip.country": "Country", + "person.page.orcid.sync-queue.tooltip.country": "Pays", + + //"person.page.orcid.sync-queue.tooltip.keywords": "Keyword", + "person.page.orcid.sync-queue.tooltip.keywords": "Mot clé", + + //"person.page.orcid.sync-queue.tooltip.external_ids": "External identifier", + "person.page.orcid.sync-queue.tooltip.external_ids": "Identifiant externe", + + //"person.page.orcid.sync-queue.tooltip.researcher_urls": "Researcher url", + "person.page.orcid.sync-queue.tooltip.researcher_urls": "URL du chercheur", + + //"person.page.orcid.sync-queue.send": "Synchronize with ORCID registry", + "person.page.orcid.sync-queue.send": "Synchroniser avec le registre ORCID", + + //"person.page.orcid.sync-queue.send.unauthorized-error.title": "The submission to ORCID failed for missing authorizations.", + "person.page.orcid.sync-queue.send.unauthorized-error.title": "La transmission à ORCID a échoué en raison d'autorisations manquantes.", + + //"person.page.orcid.sync-queue.send.unauthorized-error.content": "Click here to grant again the required permissions. If the problem persists, contact the administrator", + "person.page.orcid.sync-queue.send.unauthorized-error.content": "Cliquer ici afin d'accorder à nouveau les permissions nécessaires. Si le problème persiste, contacter l'administrateur.", + + //"person.page.orcid.sync-queue.send.bad-request-error": "The submission to ORCID failed because the resource sent to ORCID registry is not valid", + "person.page.orcid.sync-queue.send.bad-request-error": "La transmission à ORCID a échoué en raison du fait que la ressource envoyée n'est pas valide.", + + //"person.page.orcid.sync-queue.send.error": "The submission to ORCID failed", + "person.page.orcid.sync-queue.send.error": "La transmission à ORCID a échoué.", + + //"person.page.orcid.sync-queue.send.conflict-error": "The submission to ORCID failed because the resource is already present on the ORCID registry", + "person.page.orcid.sync-queue.send.conflict-error": "La transmission à ORCID a échoué en raison du fait que la ressource est déjà présente dans le registre ORCID.", + + //"person.page.orcid.sync-queue.send.not-found-warning": "The resource does not exists anymore on the ORCID registry.", + "person.page.orcid.sync-queue.send.not-found-warning": "La ressource n'existe plus dans le registre ORCID.", + + //"person.page.orcid.sync-queue.send.success": "The submission to ORCID was completed successfully", + "person.page.orcid.sync-queue.send.success": "La transmission à ORCID a été effectuée avec succès.", + + //"person.page.orcid.sync-queue.send.validation-error": "The data that you want to synchronize with ORCID is not valid", + "person.page.orcid.sync-queue.send.validation-error": "Les données que vous souhaitez synchroniser avec ORCID ne sont pas valides.", + + //"person.page.orcid.sync-queue.send.validation-error.amount-currency.required": "The amount's currency is required", + "person.page.orcid.sync-queue.send.validation-error.amount-currency.required": "La devise du montant est requise.", + + //"person.page.orcid.sync-queue.send.validation-error.external-id.required": "The resource to be sent requires at least one identifier", + "person.page.orcid.sync-queue.send.validation-error.external-id.required": "La ressource à transmettre doit avoir au moins un identifiant.", + + //"person.page.orcid.sync-queue.send.validation-error.title.required": "The title is required", + "person.page.orcid.sync-queue.send.validation-error.title.required": "Le titre est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.type.required": "The dc.type is required", + "person.page.orcid.sync-queue.send.validation-error.type.required": "Le type de document est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.start-date.required": "The start date is required", + "person.page.orcid.sync-queue.send.validation-error.start-date.required": "La date de début est obbligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.funder.required": "The funder is required", + "person.page.orcid.sync-queue.send.validation-error.funder.required": "L'organisme subventionnaire est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.country.invalid": "Invalid 2 digits ISO 3166 country", + "person.page.orcid.sync-queue.send.validation-error.country.invalid": "Code de pays ISO 3166 à 2 chiffres invalide", + + //"person.page.orcid.sync-queue.send.validation-error.organization.required": "The organization is required", + "person.page.orcid.sync-queue.send.validation-error.organization.required": "L'organisation est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.organization.name-required": "The organization's name is required", + "person.page.orcid.sync-queue.send.validation-error.organization.name-required": "Le nom de l'organisation est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.publication.date-invalid": "The publication date must be one year after 1900", + "person.page.orcid.sync-queue.send.validation-error.publication.date-invalid": "La date de publication doit être d'au moins un an après 1900.", + + //"person.page.orcid.sync-queue.send.validation-error.organization.address-required": "The organization to be sent requires an address", + "person.page.orcid.sync-queue.send.validation-error.organization.address-required": "L'organisation a transmettre doit avoir une adresse.", + + //"person.page.orcid.sync-queue.send.validation-error.organization.city-required": "The address of the organization to be sent requires a city", + "person.page.orcid.sync-queue.send.validation-error.organization.city-required": "L'adresse de l'organisation à transmettre doit mentionner une ville.", + + //"person.page.orcid.sync-queue.send.validation-error.organization.country-required": "The address of the organization to be sent requires a valid 2 digits ISO 3166 country", + "person.page.orcid.sync-queue.send.validation-error.organization.country-required": "L'adresse de l'organisation à transmettre doit avoir une code de pays ISO 3166 à 2 chiffres valide.", + + //"person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.required": "An identifier to disambiguate organizations is required. Supported ids are GRID, Ringgold, Legal Entity identifiers (LEIs) and Crossref Funder Registry identifiers", + "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.required": "Un identifiant pour désambiguer l'orgnisation est obligatoire. Les identifiants possibles sont GRID, Ringgold, Legal Entity identifiers (LEIs) et Crossref Funder Registry identifiers", + + //"person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.value-required": "The organization's identifiers requires a value", + "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.value-required": "Une valeur pour l'identifiant de l'organisation est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "The organization's identifiers requires a source", + "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "La source de l'identifiant de l'organisation est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "The source of one of the organization identifiers is invalid. Supported sources are RINGGOLD, GRID, LEI and FUNDREF", + "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "La source d'un des identifiants d'organisation est invalide. Les sources possibles sont RINGGOLD, GRID, LEI and FUNDREF", + + //"person.page.orcid.synchronization-mode": "Synchronization mode", + "person.page.orcid.synchronization-mode": "Mode de synchronisation", + + //"person.page.orcid.synchronization-mode.batch": "Batch", + "person.page.orcid.synchronization-mode.batch": "En lot", + + //"person.page.orcid.synchronization-mode.label": "Synchronization mode", + "person.page.orcid.synchronization-mode.label": "Mode de synchronisation", + + //"person.page.orcid.synchronization-mode-message": "Please select how you would like synchronization to ORCID to occur. The options include \"Manual\" (you must send your data to ORCID manually), or \"Batch\" (the system will send your data to ORCID via a scheduled script).", + "person.page.orcid.synchronization-mode-message": "Sélectionner le mode de synchronisation vers ORCID. Les options sont \"Manuel\" (vous devrez sélectionner les données à transmettre vers ORCID manuellement), ou \"En lot\" (le système transmettra vos données vers ORCID automatiquement).", + + //"person.page.orcid.synchronization-mode-funding-message": "Select whether to send your linked Project entities to your ORCID record's list of funding information.", + "person.page.orcid.synchronization-mode-funding-message": "Sélectionnez si vous souhaitez transmettre vos projets de recherche vers votre profil ORCID.", + + //"person.page.orcid.synchronization-mode-publication-message": "Select whether to send your linked Publication entities to your ORCID record's list of works.", + "person.page.orcid.synchronization-mode-publication-message": "Sélectionnez si vous souhaitez transmettre vos publications vers votre profil ORCID.", + + //"person.page.orcid.synchronization-mode-profile-message": "Select whether to send your biographical data or personal identifiers to your ORCID record.", + "person.page.orcid.synchronization-mode-profile-message": "Sélectionnez si vous souhaitez transmettre vos données biographiques vers votre profil ORCID.", + + //"person.page.orcid.synchronization-settings-update.success": "The synchronization settings have been updated successfully", + "person.page.orcid.synchronization-settings-update.success": "Les paramètres de synchronisation ont été mis à jour avec succès.", + + //"person.page.orcid.synchronization-settings-update.error": "The update of the synchronization settings failed", + "person.page.orcid.synchronization-settings-update.error": "La mise à jour des paramètres de synchronisation a échoué.", + + //"person.page.orcid.synchronization-mode.manual": "Manual", + "person.page.orcid.synchronization-mode.manual": "Manuel", + + //"person.page.orcid.scope.authenticate": "Get your ORCID iD", + "person.page.orcid.scope.authenticate": "Obtenez votre identifiant ORCID", + + //"person.page.orcid.scope.read-limited": "Read your information with visibility set to Trusted Parties", + "person.page.orcid.scope.read-limited": "Consultez vos informations ayant le paramètre de visibilité réglé sur Parties de confiance.", + + //"person.page.orcid.scope.activities-update": "Add/update your research activities", + "person.page.orcid.scope.activities-update": "Ajouter ou mettre à jour vos activités de recherche", + + //"person.page.orcid.scope.person-update": "Add/update other information about you", + "person.page.orcid.scope.person-update": "Ajouter ou mettre à jour d'autre information sur vous", + + //"person.page.orcid.unlink.success": "The disconnection between the profile and the ORCID registry was successful", + "person.page.orcid.unlink.success": "La déconnexion entre votre profil et le registre ORCID a été effectuée avec succès.", + + //"person.page.orcid.unlink.error": "An error occurred while disconnecting between the profile and the ORCID registry. Try again", + "person.page.orcid.unlink.error": "Une erreur s'est produite lors de la déconnexion entre votre profil et le registre ORCID. Veuillez réessayer.", + + //"person.orcid.sync.setting": "ORCID Synchronization settings", + "person.orcid.sync.setting": "Paramètres de synchronisation ORCID", + + //"person.orcid.registry.queue": "ORCID Registry Queue", + "person.orcid.registry.queue": "Liste d'attente pour le registre ORCID", + + //"person.orcid.registry.auth": "ORCID Authorizations", + "person.orcid.registry.auth": "Autorisation ORCID", + // "system-wide-alert-banner.retrieval.error": "Something went wrong retrieving the system-wide alert banner", "system-wide-alert-banner.retrieval.error": "Une erreur s'est produite lors de la récupération de la bannière du message d'avertissement", From 33262795babe9ada5d4d97f83fbaaf36cd8c626f Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Fri, 1 Nov 2024 11:35:05 -0400 Subject: [PATCH 316/822] Correct small alignment errors (cherry picked from commit fde2db85e72e44e9606938d216c1205c8dabd253) --- src/assets/i18n/fr.json5 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index 9c0b85cfe4c..8122486a4ee 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -6358,8 +6358,8 @@ //"person.page.orcid.sync-profile.biographical": "Biographical data", "person.page.orcid.sync-profile.biographical": "Données biographiques", - //"person.page.orcid.sync-profile.education": "Education", - "person.page.orcid.sync-profile.education": "Éducation", + //"person.page.orcid.sync-profile.education": "Education", + "person.page.orcid.sync-profile.education": "Éducation", //"person.page.orcid.sync-profile.identifiers": "Identifiers", "person.page.orcid.sync-profile.identifiers": "Identifiants", @@ -6490,8 +6490,8 @@ //"person.page.orcid.sync-queue.send.conflict-error": "The submission to ORCID failed because the resource is already present on the ORCID registry", "person.page.orcid.sync-queue.send.conflict-error": "La transmission à ORCID a échoué en raison du fait que la ressource est déjà présente dans le registre ORCID.", - //"person.page.orcid.sync-queue.send.not-found-warning": "The resource does not exists anymore on the ORCID registry.", - "person.page.orcid.sync-queue.send.not-found-warning": "La ressource n'existe plus dans le registre ORCID.", + //"person.page.orcid.sync-queue.send.not-found-warning": "The resource does not exists anymore on the ORCID registry.", + "person.page.orcid.sync-queue.send.not-found-warning": "La ressource n'existe plus dans le registre ORCID.", //"person.page.orcid.sync-queue.send.success": "The submission to ORCID was completed successfully", "person.page.orcid.sync-queue.send.success": "La transmission à ORCID a été effectuée avec succès.", @@ -6547,7 +6547,7 @@ //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "The organization's identifiers requires a source", "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "La source de l'identifiant de l'organisation est obligatoire.", - //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "The source of one of the organization identifiers is invalid. Supported sources are RINGGOLD, GRID, LEI and FUNDREF", + //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "The source of one of the organization identifiers is invalid. Supported sources are RINGGOLD, GRID, LEI and FUNDREF", "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "La source d'un des identifiants d'organisation est invalide. Les sources possibles sont RINGGOLD, GRID, LEI and FUNDREF", //"person.page.orcid.synchronization-mode": "Synchronization mode", @@ -6589,7 +6589,7 @@ //"person.page.orcid.scope.activities-update": "Add/update your research activities", "person.page.orcid.scope.activities-update": "Ajouter ou mettre à jour vos activités de recherche", - //"person.page.orcid.scope.person-update": "Add/update other information about you", + //"person.page.orcid.scope.person-update": "Add/update other information about you", "person.page.orcid.scope.person-update": "Ajouter ou mettre à jour d'autre information sur vous", //"person.page.orcid.unlink.success": "The disconnection between the profile and the ORCID registry was successful", From 9c3363d4652c97279836e5b655a369eab18e76dc Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Fri, 1 Nov 2024 14:02:00 -0400 Subject: [PATCH 317/822] Correction of 2 lint errors due to spacing. (cherry picked from commit 23dd7903ba36bd4140c3e15af2f9d33bfd2fd9a5) --- src/assets/i18n/fr.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index 8122486a4ee..0f5587626bd 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -6314,7 +6314,7 @@ "person.page.orcid.link.processing": "Liaison du profil avec ORCID en cours...", //"person.page.orcid.link.error.message": "Something went wrong while connecting the profile with ORCID. If the problem persists, contact the administrator.", - "person.page.orcid.link.error.message": "Quelque chose a échoué lors de la connection du profil avec ORCID. Si le problème persiste, contacter la personne administratice.", + "person.page.orcid.link.error.message": "Quelque chose a échoué lors de la connection du profil avec ORCID. Si le problème persiste, contacter la personne administratice.", //"person.page.orcid.orcid-not-linked-message": "The ORCID iD of this profile ({{ orcid }}) has not yet been connected to an account on the ORCID registry or the connection is expired.", "person.page.orcid.orcid-not-linked-message": "L'identifiant ORCID du profil ({{ orcid }}) n'a pas encore été connecté à une compte du registre ORCID ou la connection a expiré. ", @@ -6567,7 +6567,7 @@ //"person.page.orcid.synchronization-mode-publication-message": "Select whether to send your linked Publication entities to your ORCID record's list of works.", "person.page.orcid.synchronization-mode-publication-message": "Sélectionnez si vous souhaitez transmettre vos publications vers votre profil ORCID.", - + //"person.page.orcid.synchronization-mode-profile-message": "Select whether to send your biographical data or personal identifiers to your ORCID record.", "person.page.orcid.synchronization-mode-profile-message": "Sélectionnez si vous souhaitez transmettre vos données biographiques vers votre profil ORCID.", From 73e0c1ffcf0f41d56c80131cdc9c5f2534b3b91e Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Thu, 31 Oct 2024 11:12:29 -0400 Subject: [PATCH 318/822] Complete tag translation in french for ORCID Contains all french translations for ORCID and Researcher Profile. (cherry picked from commit ac720033dcca82c0bbd8c6a9f8ac8b1d07ffb37e) --- src/assets/i18n/fr.json5 | 366 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index b2a03fad7dc..f4f4bd1ce44 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -6615,6 +6615,372 @@ // "idle-modal.extend-session": "Extend session", "idle-modal.extend-session": "Prolonger la session", + //"researcher.profile.action.processing": "Processing...", + "researcher.profile.action.processing": "En traitement...", + + //"researcher.profile.associated": "Researcher profile associated", + "researcher.profile.associated": "Profil du chercheur associé", + + //"researcher.profile.change-visibility.fail": "An unexpected error occurs while changing the profile visibility", + "researcher.profile.change-visibility.fail": "Une erreur inattendue s'est produite pendant le changement apporté à la visibilité du profil.", + + //"researcher.profile.create.new": "Create new", + "researcher.profile.create.new": "Créer un nouveau", + + //"researcher.profile.create.success": "Researcher profile created successfully", + "researcher.profile.create.success": "Profil créé avec succès", + + //"researcher.profile.create.fail": "An error occurs during the researcher profile creation", + "researcher.profile.create.fail": "Une erreur s'est produite lors de la création du profil", + + //"researcher.profile.delete": "Delete", + "researcher.profile.delete": "Supprimer", + + //"researcher.profile.expose": "Expose", + "researcher.profile.expose": "Exposer", + + //"researcher.profile.hide": "Hide", + "researcher.profile.hide": "Cacher", + + //"researcher.profile.not.associated": "Researcher profile not yet associated", + "researcher.profile.not.associated": "Profil non associé", + + //"researcher.profile.view": "View", + "researcher.profile.view": "Voir", + + //"researcher.profile.private.visibility": "PRIVATE", + "researcher.profile.private.visibility": "PRIVÉ", + + //"researcher.profile.public.visibility": "PUBLIC", + "researcher.profile.public.visibility": "PUBLIC", + + //"researcher.profile.status": "Status:", + "researcher.profile.status": "Statut:", + + //"researcherprofile.claim.not-authorized": "You are not authorized to claim this item. For more details contact the administrator(s).", + "researcherprofile.claim.not-authorized": "Vous n'êtes pas autorisé à réclamer cet item. Pour plus de détails contacter la personne administratrice.", + + //"researcherprofile.error.claim.body": "An error occurred while claiming the profile, please try again later", + "researcherprofile.error.claim.body": "Une erreur s'est produite lors de la réclamation du profil, veuillez réessayer plus tard.", + + //"researcherprofile.error.claim.title": "Error", + "researcherprofile.error.claim.title": "Erreur", + + //"researcherprofile.success.claim.body": "Profile claimed with success", + "researcherprofile.success.claim.body": "Profil réclamé avec succès", + + //"researcherprofile.success.claim.title": "Success", + "researcherprofile.success.claim.title": "Succès", + + //"person.page.orcid.create": "Create an ORCID ID", + "person.page.orcid.create": "Créer un identifiant ORCID", + + //"person.page.orcid.granted-authorizations": "Granted authorizations", + "person.page.orcid.granted-authorizations": "Autorisations accordées", + + //"person.page.orcid.grant-authorizations": "Grant authorizations", + "person.page.orcid.grant-authorizations": "Accorder des autorisations", + + //"person.page.orcid.link": "Connect to ORCID ID", + "person.page.orcid.link": "Se connecter à ORCID", + + //"person.page.orcid.link.processing": "Linking profile to ORCID...", + "person.page.orcid.link.processing": "Liaison du profil avec ORCID en cours...", + + //"person.page.orcid.link.error.message": "Something went wrong while connecting the profile with ORCID. If the problem persists, contact the administrator.", + "person.page.orcid.link.error.message": "Quelque chose a échoué lors de la connection du profil avec ORCID. Si le problème persiste, contacter la personne administratice.", + + //"person.page.orcid.orcid-not-linked-message": "The ORCID iD of this profile ({{ orcid }}) has not yet been connected to an account on the ORCID registry or the connection is expired.", + "person.page.orcid.orcid-not-linked-message": "L'identifiant ORCID du profil ({{ orcid }}) n'a pas encore été connecté à une compte du registre ORCID ou la connection a expiré. ", + + //"person.page.orcid.unlink": "Disconnect from ORCID", + "person.page.orcid.unlink": "Déconnecter d'ORCID", + + //"person.page.orcid.unlink.processing": "Processing...", + "person.page.orcid.unlink.processing": "Traitement en cours...", + + //"person.page.orcid.missing-authorizations": "Missing authorizations", + "person.page.orcid.missing-authorizations": "Autorisations manquantes", + + //"person.page.orcid.missing-authorizations-message": "The following authorizations are missing:", + "person.page.orcid.missing-authorizations-message": "Les autorisations suivantes sont manquantes :", + + //"person.page.orcid.no-missing-authorizations-message": "Great! This box is empty, so you have granted all access rights to use all functions offers by your institution.", + "person.page.orcid.no-missing-authorizations-message": "Cette boite est vide, vous avez autorisé l'utilisation de toutes les fonctions proposées par votre organisation.", + + //"person.page.orcid.no-orcid-message": "No ORCID iD associated yet. By clicking on the button below it is possible to link this profile with an ORCID account.", + "person.page.orcid.no-orcid-message": "Aucun identifiant ORCID n'est encore associé. En cliquant sur le bouton ci-dessous, il est possible de lier ce profil à un compte ORCID.", + + //"person.page.orcid.profile-preferences": "Profile preferences", + "person.page.orcid.profile-preferences": "Préférences du profil", + + //"person.page.orcid.funding-preferences": "Funding preferences", + "person.page.orcid.funding-preferences": "Préférence pour la section Financement", + + //"person.page.orcid.publications-preferences": "Publication preferences", + "person.page.orcid.publications-preferences": "Préférence pour la section Publication", + + //"person.page.orcid.remove-orcid-message": "If you need to remove your ORCID, please contact the repository administrator", + "person.page.orcid.remove-orcid-message": "Si vous avez besoin de retirer votre ORCID, contacter la personne administratrice du dépôt.", + + //"person.page.orcid.save.preference.changes": "Update settings", + "person.page.orcid.save.preference.changes": "Mettre à jour les configurations", + + //"person.page.orcid.sync-profile.affiliation": "Affiliation", + "person.page.orcid.sync-profile.affiliation": "Affiliation", + + //"person.page.orcid.sync-profile.biographical": "Biographical data", + "person.page.orcid.sync-profile.biographical": "Données biographiques", + + //"person.page.orcid.sync-profile.education": "Education", + "person.page.orcid.sync-profile.education": "Éducation", + + //"person.page.orcid.sync-profile.identifiers": "Identifiers", + "person.page.orcid.sync-profile.identifiers": "Identifiants", + + //"person.page.orcid.sync-fundings.all": "All fundings", + "person.page.orcid.sync-fundings.all": "Tous les financements", + + //"person.page.orcid.sync-fundings.mine": "My fundings", + "person.page.orcid.sync-fundings.mine": "Mes financements", + + //"person.page.orcid.sync-fundings.my_selected": "Selected fundings", + "person.page.orcid.sync-fundings.my_selected": "Financements sélectionnés", + + //"person.page.orcid.sync-fundings.disabled": "Disabled", + "person.page.orcid.sync-fundings.disabled": "Désactivé", + + //"person.page.orcid.sync-publications.all": "All publications", + "person.page.orcid.sync-publications.all": "Toutes les publications", + + //"person.page.orcid.sync-publications.mine": "My publications", + "person.page.orcid.sync-publications.mine": "Mes publications", + + //"person.page.orcid.sync-publications.my_selected": "Selected publications", + "person.page.orcid.sync-publications.my_selected": "Publications sélectionnées", + + //"person.page.orcid.sync-publications.disabled": "Disabled", + "person.page.orcid.sync-publications.disabled": "Désactivé", + + //"person.page.orcid.sync-queue.discard": "Discard the change and do not synchronize with the ORCID registry", + "person.page.orcid.sync-queue.discard": "Ignorer les changements et ne pas synchroniser avec le registre ORCID.", + + //"person.page.orcid.sync-queue.discard.error": "The discarding of the ORCID queue record failed", + "person.page.orcid.sync-queue.discard.error": "L'annulation de la file d'attente ORCID a échoué.", + + //"person.page.orcid.sync-queue.discard.success": "The ORCID queue record have been discarded successfully", + "person.page.orcid.sync-queue.discard.success": "La file d'attente ORCID a été annulée avec succès.", + + //"person.page.orcid.sync-queue.empty-message": "The ORCID queue registry is empty", + "person.page.orcid.sync-queue.empty-message": "La file d'attente ORCID est vide.", + + //"person.page.orcid.sync-queue.table.header.type": "Type", + "person.page.orcid.sync-queue.table.header.type": "Type", + + //"person.page.orcid.sync-queue.table.header.description": "Description", + "person.page.orcid.sync-queue.table.header.description": "Description", + + //"person.page.orcid.sync-queue.table.header.action": "Action", + "person.page.orcid.sync-queue.table.header.action": "Action", + + //"person.page.orcid.sync-queue.description.affiliation": "Affiliations", + "person.page.orcid.sync-queue.description.affiliation": "Affiliations", + + //"person.page.orcid.sync-queue.description.country": "Country", + "person.page.orcid.sync-queue.description.country": "Pays", + + //"person.page.orcid.sync-queue.description.education": "Educations", + "person.page.orcid.sync-queue.description.education": "Éducation", + + //"person.page.orcid.sync-queue.description.external_ids": "External ids", + "person.page.orcid.sync-queue.description.external_ids": "Identifiants externes", + + //"person.page.orcid.sync-queue.description.other_names": "Other names", + "person.page.orcid.sync-queue.description.other_names": "Autres noms", + + //"person.page.orcid.sync-queue.description.qualification": "Qualifications", + "person.page.orcid.sync-queue.description.qualification": "Qualifications", + + //"person.page.orcid.sync-queue.description.researcher_urls": "Researcher urls", + "person.page.orcid.sync-queue.description.researcher_urls": "URLs du chercheur", + + //"person.page.orcid.sync-queue.description.keywords": "Keywords", + "person.page.orcid.sync-queue.description.keywords": "Mots clés", + + //"person.page.orcid.sync-queue.tooltip.insert": "Add a new entry in the ORCID registry", + "person.page.orcid.sync-queue.tooltip.insert": "Ajouter une nouvelle entrée dans le registre ORCID", + + //"person.page.orcid.sync-queue.tooltip.update": "Update this entry on the ORCID registry", + "person.page.orcid.sync-queue.tooltip.update": "Mettre à jour cette entrée dans le registre ORCID", + + //"person.page.orcid.sync-queue.tooltip.delete": "Remove this entry from the ORCID registry", + "person.page.orcid.sync-queue.tooltip.delete": "Supprimer cette entrée du registre ORCID", + + //"person.page.orcid.sync-queue.tooltip.publication": "Publication", + "person.page.orcid.sync-queue.tooltip.publication": "Publication", + + //"person.page.orcid.sync-queue.tooltip.project": "Project", + "person.page.orcid.sync-queue.tooltip.project": "Projet", + + //"person.page.orcid.sync-queue.tooltip.affiliation": "Affiliation", + "person.page.orcid.sync-queue.tooltip.affiliation": "Affiliation", + + //"person.page.orcid.sync-queue.tooltip.education": "Education", + "person.page.orcid.sync-queue.tooltip.education": "Éducation", + + //"person.page.orcid.sync-queue.tooltip.qualification": "Qualification", + "person.page.orcid.sync-queue.tooltip.qualification": "Qualification", + + //"person.page.orcid.sync-queue.tooltip.other_names": "Other name", + "person.page.orcid.sync-queue.tooltip.other_names": "Autre nom", + + //"person.page.orcid.sync-queue.tooltip.country": "Country", + "person.page.orcid.sync-queue.tooltip.country": "Pays", + + //"person.page.orcid.sync-queue.tooltip.keywords": "Keyword", + "person.page.orcid.sync-queue.tooltip.keywords": "Mot clé", + + //"person.page.orcid.sync-queue.tooltip.external_ids": "External identifier", + "person.page.orcid.sync-queue.tooltip.external_ids": "Identifiant externe", + + //"person.page.orcid.sync-queue.tooltip.researcher_urls": "Researcher url", + "person.page.orcid.sync-queue.tooltip.researcher_urls": "URL du chercheur", + + //"person.page.orcid.sync-queue.send": "Synchronize with ORCID registry", + "person.page.orcid.sync-queue.send": "Synchroniser avec le registre ORCID", + + //"person.page.orcid.sync-queue.send.unauthorized-error.title": "The submission to ORCID failed for missing authorizations.", + "person.page.orcid.sync-queue.send.unauthorized-error.title": "La transmission à ORCID a échoué en raison d'autorisations manquantes.", + + //"person.page.orcid.sync-queue.send.unauthorized-error.content": "Click here to grant again the required permissions. If the problem persists, contact the administrator", + "person.page.orcid.sync-queue.send.unauthorized-error.content": "Cliquer ici afin d'accorder à nouveau les permissions nécessaires. Si le problème persiste, contacter l'administrateur.", + + //"person.page.orcid.sync-queue.send.bad-request-error": "The submission to ORCID failed because the resource sent to ORCID registry is not valid", + "person.page.orcid.sync-queue.send.bad-request-error": "La transmission à ORCID a échoué en raison du fait que la ressource envoyée n'est pas valide.", + + //"person.page.orcid.sync-queue.send.error": "The submission to ORCID failed", + "person.page.orcid.sync-queue.send.error": "La transmission à ORCID a échoué.", + + //"person.page.orcid.sync-queue.send.conflict-error": "The submission to ORCID failed because the resource is already present on the ORCID registry", + "person.page.orcid.sync-queue.send.conflict-error": "La transmission à ORCID a échoué en raison du fait que la ressource est déjà présente dans le registre ORCID.", + + //"person.page.orcid.sync-queue.send.not-found-warning": "The resource does not exists anymore on the ORCID registry.", + "person.page.orcid.sync-queue.send.not-found-warning": "La ressource n'existe plus dans le registre ORCID.", + + //"person.page.orcid.sync-queue.send.success": "The submission to ORCID was completed successfully", + "person.page.orcid.sync-queue.send.success": "La transmission à ORCID a été effectuée avec succès.", + + //"person.page.orcid.sync-queue.send.validation-error": "The data that you want to synchronize with ORCID is not valid", + "person.page.orcid.sync-queue.send.validation-error": "Les données que vous souhaitez synchroniser avec ORCID ne sont pas valides.", + + //"person.page.orcid.sync-queue.send.validation-error.amount-currency.required": "The amount's currency is required", + "person.page.orcid.sync-queue.send.validation-error.amount-currency.required": "La devise du montant est requise.", + + //"person.page.orcid.sync-queue.send.validation-error.external-id.required": "The resource to be sent requires at least one identifier", + "person.page.orcid.sync-queue.send.validation-error.external-id.required": "La ressource à transmettre doit avoir au moins un identifiant.", + + //"person.page.orcid.sync-queue.send.validation-error.title.required": "The title is required", + "person.page.orcid.sync-queue.send.validation-error.title.required": "Le titre est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.type.required": "The dc.type is required", + "person.page.orcid.sync-queue.send.validation-error.type.required": "Le type de document est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.start-date.required": "The start date is required", + "person.page.orcid.sync-queue.send.validation-error.start-date.required": "La date de début est obbligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.funder.required": "The funder is required", + "person.page.orcid.sync-queue.send.validation-error.funder.required": "L'organisme subventionnaire est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.country.invalid": "Invalid 2 digits ISO 3166 country", + "person.page.orcid.sync-queue.send.validation-error.country.invalid": "Code de pays ISO 3166 à 2 chiffres invalide", + + //"person.page.orcid.sync-queue.send.validation-error.organization.required": "The organization is required", + "person.page.orcid.sync-queue.send.validation-error.organization.required": "L'organisation est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.organization.name-required": "The organization's name is required", + "person.page.orcid.sync-queue.send.validation-error.organization.name-required": "Le nom de l'organisation est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.publication.date-invalid": "The publication date must be one year after 1900", + "person.page.orcid.sync-queue.send.validation-error.publication.date-invalid": "La date de publication doit être d'au moins un an après 1900.", + + //"person.page.orcid.sync-queue.send.validation-error.organization.address-required": "The organization to be sent requires an address", + "person.page.orcid.sync-queue.send.validation-error.organization.address-required": "L'organisation a transmettre doit avoir une adresse.", + + //"person.page.orcid.sync-queue.send.validation-error.organization.city-required": "The address of the organization to be sent requires a city", + "person.page.orcid.sync-queue.send.validation-error.organization.city-required": "L'adresse de l'organisation à transmettre doit mentionner une ville.", + + //"person.page.orcid.sync-queue.send.validation-error.organization.country-required": "The address of the organization to be sent requires a valid 2 digits ISO 3166 country", + "person.page.orcid.sync-queue.send.validation-error.organization.country-required": "L'adresse de l'organisation à transmettre doit avoir une code de pays ISO 3166 à 2 chiffres valide.", + + //"person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.required": "An identifier to disambiguate organizations is required. Supported ids are GRID, Ringgold, Legal Entity identifiers (LEIs) and Crossref Funder Registry identifiers", + "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.required": "Un identifiant pour désambiguer l'orgnisation est obligatoire. Les identifiants possibles sont GRID, Ringgold, Legal Entity identifiers (LEIs) et Crossref Funder Registry identifiers", + + //"person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.value-required": "The organization's identifiers requires a value", + "person.page.orcid.sync-queue.send.validation-error.disambiguated-organization.value-required": "Une valeur pour l'identifiant de l'organisation est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "The organization's identifiers requires a source", + "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "La source de l'identifiant de l'organisation est obligatoire.", + + //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "The source of one of the organization identifiers is invalid. Supported sources are RINGGOLD, GRID, LEI and FUNDREF", + "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "La source d'un des identifiants d'organisation est invalide. Les sources possibles sont RINGGOLD, GRID, LEI and FUNDREF", + + //"person.page.orcid.synchronization-mode": "Synchronization mode", + "person.page.orcid.synchronization-mode": "Mode de synchronisation", + + //"person.page.orcid.synchronization-mode.batch": "Batch", + "person.page.orcid.synchronization-mode.batch": "En lot", + + //"person.page.orcid.synchronization-mode.label": "Synchronization mode", + "person.page.orcid.synchronization-mode.label": "Mode de synchronisation", + + //"person.page.orcid.synchronization-mode-message": "Please select how you would like synchronization to ORCID to occur. The options include \"Manual\" (you must send your data to ORCID manually), or \"Batch\" (the system will send your data to ORCID via a scheduled script).", + "person.page.orcid.synchronization-mode-message": "Sélectionner le mode de synchronisation vers ORCID. Les options sont \"Manuel\" (vous devrez sélectionner les données à transmettre vers ORCID manuellement), ou \"En lot\" (le système transmettra vos données vers ORCID automatiquement).", + + //"person.page.orcid.synchronization-mode-funding-message": "Select whether to send your linked Project entities to your ORCID record's list of funding information.", + "person.page.orcid.synchronization-mode-funding-message": "Sélectionnez si vous souhaitez transmettre vos projets de recherche vers votre profil ORCID.", + + //"person.page.orcid.synchronization-mode-publication-message": "Select whether to send your linked Publication entities to your ORCID record's list of works.", + "person.page.orcid.synchronization-mode-publication-message": "Sélectionnez si vous souhaitez transmettre vos publications vers votre profil ORCID.", + + //"person.page.orcid.synchronization-mode-profile-message": "Select whether to send your biographical data or personal identifiers to your ORCID record.", + "person.page.orcid.synchronization-mode-profile-message": "Sélectionnez si vous souhaitez transmettre vos données biographiques vers votre profil ORCID.", + + //"person.page.orcid.synchronization-settings-update.success": "The synchronization settings have been updated successfully", + "person.page.orcid.synchronization-settings-update.success": "Les paramètres de synchronisation ont été mis à jour avec succès.", + + //"person.page.orcid.synchronization-settings-update.error": "The update of the synchronization settings failed", + "person.page.orcid.synchronization-settings-update.error": "La mise à jour des paramètres de synchronisation a échoué.", + + //"person.page.orcid.synchronization-mode.manual": "Manual", + "person.page.orcid.synchronization-mode.manual": "Manuel", + + //"person.page.orcid.scope.authenticate": "Get your ORCID iD", + "person.page.orcid.scope.authenticate": "Obtenez votre identifiant ORCID", + + //"person.page.orcid.scope.read-limited": "Read your information with visibility set to Trusted Parties", + "person.page.orcid.scope.read-limited": "Consultez vos informations ayant le paramètre de visibilité réglé sur Parties de confiance.", + + //"person.page.orcid.scope.activities-update": "Add/update your research activities", + "person.page.orcid.scope.activities-update": "Ajouter ou mettre à jour vos activités de recherche", + + //"person.page.orcid.scope.person-update": "Add/update other information about you", + "person.page.orcid.scope.person-update": "Ajouter ou mettre à jour d'autre information sur vous", + + //"person.page.orcid.unlink.success": "The disconnection between the profile and the ORCID registry was successful", + "person.page.orcid.unlink.success": "La déconnexion entre votre profil et le registre ORCID a été effectuée avec succès.", + + //"person.page.orcid.unlink.error": "An error occurred while disconnecting between the profile and the ORCID registry. Try again", + "person.page.orcid.unlink.error": "Une erreur s'est produite lors de la déconnexion entre votre profil et le registre ORCID. Veuillez réessayer.", + + //"person.orcid.sync.setting": "ORCID Synchronization settings", + "person.orcid.sync.setting": "Paramètres de synchronisation ORCID", + + //"person.orcid.registry.queue": "ORCID Registry Queue", + "person.orcid.registry.queue": "Liste d'attente pour le registre ORCID", + + //"person.orcid.registry.auth": "ORCID Authorizations", + "person.orcid.registry.auth": "Autorisation ORCID", + // "system-wide-alert-banner.retrieval.error": "Something went wrong retrieving the system-wide alert banner", "system-wide-alert-banner.retrieval.error": "Une erreur s'est produite lors de la récupération de la bannière du message d'avertissement", From 07e4e0cabb03fdbe2c7d16326513a7987cf1e879 Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Fri, 1 Nov 2024 11:35:05 -0400 Subject: [PATCH 319/822] Correct small alignment errors (cherry picked from commit fde2db85e72e44e9606938d216c1205c8dabd253) --- src/assets/i18n/fr.json5 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index f4f4bd1ce44..b0017068d70 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -6732,8 +6732,8 @@ //"person.page.orcid.sync-profile.biographical": "Biographical data", "person.page.orcid.sync-profile.biographical": "Données biographiques", - //"person.page.orcid.sync-profile.education": "Education", - "person.page.orcid.sync-profile.education": "Éducation", + //"person.page.orcid.sync-profile.education": "Education", + "person.page.orcid.sync-profile.education": "Éducation", //"person.page.orcid.sync-profile.identifiers": "Identifiers", "person.page.orcid.sync-profile.identifiers": "Identifiants", @@ -6864,8 +6864,8 @@ //"person.page.orcid.sync-queue.send.conflict-error": "The submission to ORCID failed because the resource is already present on the ORCID registry", "person.page.orcid.sync-queue.send.conflict-error": "La transmission à ORCID a échoué en raison du fait que la ressource est déjà présente dans le registre ORCID.", - //"person.page.orcid.sync-queue.send.not-found-warning": "The resource does not exists anymore on the ORCID registry.", - "person.page.orcid.sync-queue.send.not-found-warning": "La ressource n'existe plus dans le registre ORCID.", + //"person.page.orcid.sync-queue.send.not-found-warning": "The resource does not exists anymore on the ORCID registry.", + "person.page.orcid.sync-queue.send.not-found-warning": "La ressource n'existe plus dans le registre ORCID.", //"person.page.orcid.sync-queue.send.success": "The submission to ORCID was completed successfully", "person.page.orcid.sync-queue.send.success": "La transmission à ORCID a été effectuée avec succès.", @@ -6921,7 +6921,7 @@ //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "The organization's identifiers requires a source", "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.required": "La source de l'identifiant de l'organisation est obligatoire.", - //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "The source of one of the organization identifiers is invalid. Supported sources are RINGGOLD, GRID, LEI and FUNDREF", + //"person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "The source of one of the organization identifiers is invalid. Supported sources are RINGGOLD, GRID, LEI and FUNDREF", "person.page.orcid.sync-queue.send.validation-error.disambiguation-source.invalid": "La source d'un des identifiants d'organisation est invalide. Les sources possibles sont RINGGOLD, GRID, LEI and FUNDREF", //"person.page.orcid.synchronization-mode": "Synchronization mode", @@ -6963,7 +6963,7 @@ //"person.page.orcid.scope.activities-update": "Add/update your research activities", "person.page.orcid.scope.activities-update": "Ajouter ou mettre à jour vos activités de recherche", - //"person.page.orcid.scope.person-update": "Add/update other information about you", + //"person.page.orcid.scope.person-update": "Add/update other information about you", "person.page.orcid.scope.person-update": "Ajouter ou mettre à jour d'autre information sur vous", //"person.page.orcid.unlink.success": "The disconnection between the profile and the ORCID registry was successful", From fe8f79b750a0aba295529bd1ad75736066cc9f0e Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Fri, 1 Nov 2024 14:02:00 -0400 Subject: [PATCH 320/822] Correction of 2 lint errors due to spacing. (cherry picked from commit 23dd7903ba36bd4140c3e15af2f9d33bfd2fd9a5) --- src/assets/i18n/fr.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index b0017068d70..2ea96ad58db 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -6688,7 +6688,7 @@ "person.page.orcid.link.processing": "Liaison du profil avec ORCID en cours...", //"person.page.orcid.link.error.message": "Something went wrong while connecting the profile with ORCID. If the problem persists, contact the administrator.", - "person.page.orcid.link.error.message": "Quelque chose a échoué lors de la connection du profil avec ORCID. Si le problème persiste, contacter la personne administratice.", + "person.page.orcid.link.error.message": "Quelque chose a échoué lors de la connection du profil avec ORCID. Si le problème persiste, contacter la personne administratice.", //"person.page.orcid.orcid-not-linked-message": "The ORCID iD of this profile ({{ orcid }}) has not yet been connected to an account on the ORCID registry or the connection is expired.", "person.page.orcid.orcid-not-linked-message": "L'identifiant ORCID du profil ({{ orcid }}) n'a pas encore été connecté à une compte du registre ORCID ou la connection a expiré. ", @@ -6941,7 +6941,7 @@ //"person.page.orcid.synchronization-mode-publication-message": "Select whether to send your linked Publication entities to your ORCID record's list of works.", "person.page.orcid.synchronization-mode-publication-message": "Sélectionnez si vous souhaitez transmettre vos publications vers votre profil ORCID.", - + //"person.page.orcid.synchronization-mode-profile-message": "Select whether to send your biographical data or personal identifiers to your ORCID record.", "person.page.orcid.synchronization-mode-profile-message": "Sélectionnez si vous souhaitez transmettre vos données biographiques vers votre profil ORCID.", From 8f708d0e2898b0bf0eef9ce0d50f07e6f4119d88 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 22 Oct 2024 11:37:47 +0200 Subject: [PATCH 321/822] 119602: Add AccessibilitySettingsService --- .../accessibility-settings.service.ts | 231 ++++++++++++++++++ src/app/core/auth/auth.service.ts | 23 +- 2 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 src/app/accessibility/accessibility-settings.service.ts diff --git a/src/app/accessibility/accessibility-settings.service.ts b/src/app/accessibility/accessibility-settings.service.ts new file mode 100644 index 00000000000..805d0d5a0b1 --- /dev/null +++ b/src/app/accessibility/accessibility-settings.service.ts @@ -0,0 +1,231 @@ +import { Injectable } from '@angular/core'; +import { Observable, of, switchMap } from 'rxjs'; +import { map, take } from 'rxjs/operators'; +import { CookieService } from '../core/services/cookie.service'; +import { hasValue, isNotEmpty, isNotEmptyOperator } from '../shared/empty.util'; +import { AuthService } from '../core/auth/auth.service'; +import { EPerson } from '../core/eperson/models/eperson.model'; +import { EPersonDataService } from '../core/eperson/eperson-data.service'; +import { getFirstCompletedRemoteData } from '../core/shared/operators'; +import cloneDeep from 'lodash/cloneDeep'; + +/** + * Name of the cookie used to store the settings locally + */ +export const ACCESSIBILITY_COOKIE = 'dsAccessibilityCookie'; + +/** + * Name of the metadata field to store settings on the ePerson + */ +export const ACCESSIBILITY_SETTINGS_METADATA_KEY = 'dspace.accessibility.settings'; + +/** + * The duration in days after which the accessibility settings cookie expires + */ +export const ACCESSIBILITY_SETTINGS_COOKIE_STORAGE_DURATION = 7; + +/** + * Enum containing all possible accessibility settings. + * When adding new settings, the {@link AccessibilitySettingsService#getInputType} method and the i18n keys for the + * accessibility settings page should be updated. + */ +export enum AccessibilitySetting { + NotificationTimeOut = 'notificationTimeOut', + LiveRegionTimeOut = 'liveRegionTimeOut', +} + +export type AccessibilitySettings = { [key in AccessibilitySetting]?: any }; + +/** + * Service handling the retrieval and configuration of accessibility settings. + * + * This service stores the configured settings in either a cookie or on the user's metadata depending on whether + * the user is authenticated. + */ +@Injectable({ + providedIn: 'root' +}) +export class AccessibilitySettingsService { + + constructor( + protected cookieService: CookieService, + protected authService: AuthService, + protected ePersonService: EPersonDataService, + ) { + } + + getAllAccessibilitySettingKeys(): AccessibilitySetting[] { + return Object.entries(AccessibilitySetting).map(([_, val]) => val); + } + + /** + * Get the stored value for the provided {@link AccessibilitySetting}. If the value does not exist or if it is empty, + * the provided defaultValue is emitted instead. + */ + get(setting: AccessibilitySetting, defaultValue: string = null): Observable { + return this.getAll().pipe( + map(settings => settings[setting]), + map(value => isNotEmpty(value) ? value : defaultValue), + ); + } + + /** + * Get the stored value for the provided {@link AccessibilitySetting} as a number. If the stored value + * could not be converted to a number, the value of the defaultValue parameter is emitted instead. + */ + getAsNumber(setting: AccessibilitySetting, defaultValue: number = null): Observable { + return this.get(setting).pipe( + map(value => hasValue(value) ? parseInt(value, 10) : NaN), + map(number => !isNaN(number) ? number : defaultValue), + ); + } + + /** + * Get all currently stored accessibility settings + */ + getAll(): Observable { + return this.getAllSettingsFromAuthenticatedUserMetadata().pipe( + map(value => isNotEmpty(value) ? value : this.getAllSettingsFromCookie()), + map(value => isNotEmpty(value) ? value : {}), + ); + } + + /** + * Get all settings from the accessibility settings cookie + */ + getAllSettingsFromCookie(): AccessibilitySettings { + return this.cookieService.get(ACCESSIBILITY_COOKIE); + } + + /** + * Attempts to retrieve all settings from the authenticated user's metadata. + * Returns an empty object when no user is authenticated. + */ + getAllSettingsFromAuthenticatedUserMetadata(): Observable { + return this.authService.getAuthenticatedUserFromStoreIfAuthenticated().pipe( + take(1), + map(user => hasValue(user) && hasValue(user.firstMetadataValue(ACCESSIBILITY_SETTINGS_METADATA_KEY)) ? + JSON.parse(user.firstMetadataValue(ACCESSIBILITY_SETTINGS_METADATA_KEY)) : + {} + ), + ); + } + + /** + * Set a single accessibility setting value, leaving all other settings unchanged. + * When setting all values, {@link AccessibilitySettingsService#setSettings} should be used. + * When updating multiple values, {@link AccessibilitySettingsService#updateSettings} should be used. + * + * Returns 'cookie' when the changes were stored in the cookie. + * Returns 'metadata' when the changes were stored in metadata. + */ + set(setting: AccessibilitySetting, value: string): Observable<'cookie' | 'metadata'> { + return this.updateSettings({ [setting]: value }); + } + + /** + * Set all accessibility settings simultaneously. + * This method removes existing settings if they are missing from the provided {@link AccessibilitySettings} object. + * Removes all settings if the provided object is empty. + * + * Returns 'cookie' when the changes were stored in the cookie. + * Returns 'metadata' when the changes were stored in metadata. + */ + setSettings(settings: AccessibilitySettings): Observable<'cookie' | 'metadata'> { + return this.setSettingsInAuthenticatedUserMetadata(settings).pipe( + take(1), + map((succeeded) => { + if (!succeeded) { + this.setSettingsInCookie(settings); + return 'cookie'; + } else { + return 'metadata'; + } + }) + ); + } + + /** + * Update multiple accessibility settings simultaneously. + * This method does not change the settings that are missing from the provided {@link AccessibilitySettings} object. + * + * Returns 'cookie' when the changes were stored in the cookie. + * Returns 'metadata' when the changes were stored in metadata. + */ + updateSettings(settings: AccessibilitySettings): Observable<'cookie' | 'metadata'> { + return this.getAll().pipe( + take(1), + map(currentSettings => Object.assign({}, currentSettings, settings)), + switchMap(newSettings => this.setSettings(newSettings)) + ); + } + + /** + * Attempts to set the provided settings on the currently authorized user's metadata. + * Emits false when no user is authenticated or when the metadata update failed. + * Emits true when the metadata update succeeded. + */ + setSettingsInAuthenticatedUserMetadata(settings: AccessibilitySettings): Observable { + return this.authService.getAuthenticatedUserFromStoreIfAuthenticated().pipe( + take(1), + switchMap(user => { + if (hasValue(user)) { + // EPerson has to be cloned, otherwise the EPerson's metadata can't be modified + const clonedUser = cloneDeep(user); + return this.setSettingsInMetadata(clonedUser, settings); + } else { + return of(false); + } + }) + ); + } + + /** + * Attempts to set the provided settings on the user's metadata. + * Emits false when the update failed, true when the update succeeded. + */ + setSettingsInMetadata( + user: EPerson, + settings: AccessibilitySettings, + ): Observable { + if (isNotEmpty(settings)) { + user.setMetadata(ACCESSIBILITY_SETTINGS_METADATA_KEY, null, JSON.stringify(settings)); + } else { + user.removeMetadata(ACCESSIBILITY_SETTINGS_METADATA_KEY); + } + + return this.ePersonService.createPatchFromCache(user).pipe( + take(1), + isNotEmptyOperator(), + switchMap(operations => this.ePersonService.patch(user, operations)), + getFirstCompletedRemoteData(), + map(rd => rd.hasSucceeded), + ); + } + + /** + * Sets the provided settings in a cookie + */ + setSettingsInCookie(settings: AccessibilitySettings) { + if (isNotEmpty(settings)) { + this.cookieService.set(ACCESSIBILITY_COOKIE, settings, { expires: ACCESSIBILITY_SETTINGS_COOKIE_STORAGE_DURATION }); + } else { + this.cookieService.remove(ACCESSIBILITY_COOKIE); + } + } + + /** + * Returns the input type that a form should use for the provided {@link AccessibilitySetting} + */ + getInputType(setting: AccessibilitySetting): string { + switch (setting) { + case AccessibilitySetting.NotificationTimeOut: + return 'number'; + case AccessibilitySetting.LiveRegionTimeOut: + return 'number'; + default: + return 'text'; + } + } + +} diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts index 6604936cde1..9b0ec277352 100644 --- a/src/app/core/auth/auth.service.ts +++ b/src/app/core/auth/auth.service.ts @@ -44,7 +44,11 @@ import { import { NativeWindowRef, NativeWindowService } from '../services/window.service'; import { RouteService } from '../services/route.service'; import { EPersonDataService } from '../eperson/eperson-data.service'; -import { getAllSucceededRemoteDataPayload, getFirstCompletedRemoteData } from '../shared/operators'; +import { + getAllSucceededRemoteDataPayload, + getFirstCompletedRemoteData, + getFirstSucceededRemoteDataPayload +} from '../shared/operators'; import { AuthMethod } from './models/auth.method'; import { HardRedirectService } from '../services/hard-redirect.service'; import { RemoteData } from '../data/remote-data'; @@ -229,6 +233,23 @@ export class AuthService { ); } + /** + * Returns an observable which emits the currently authenticated user from the store, + * or null if the user is not authenticated. + */ + public getAuthenticatedUserFromStoreIfAuthenticated(): Observable { + return this.store.pipe( + select(getAuthenticatedUserId), + switchMap((id: string) => { + if (hasValue(id)) { + return this.epersonService.findById(id).pipe(getFirstSucceededRemoteDataPayload()); + } else { + return observableOf(null); + } + }), + ); + } + /** * Checks if token is present into browser storage and is valid. */ From b72ce73931ace11de9c8cb3f8aed4abbf73e1d08 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 22 Oct 2024 14:34:35 +0200 Subject: [PATCH 322/822] 119602: Add Accessibility Settings page --- src/app/footer/footer.component.html | 4 ++ .../accessibility-settings.component.html | 26 ++++++++++ .../accessibility-settings.component.ts | 47 +++++++++++++++++++ src/app/info/info-routing-paths.ts | 5 ++ src/app/info/info-routing.module.ts | 16 ++++++- src/app/info/info.module.ts | 4 +- src/assets/i18n/en.json5 | 20 ++++++++ 7 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 src/app/info/accessibility-settings/accessibility-settings.component.html create mode 100644 src/app/info/accessibility-settings/accessibility-settings.component.ts diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index 13d84e6e2e1..d3534706e88 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -79,6 +79,10 @@
Footer Content
{{ 'footer.link.feedback' | translate}} +
  • + {{ 'footer.link.accessibility' | translate }} +
  • diff --git a/src/app/info/accessibility-settings/accessibility-settings.component.html b/src/app/info/accessibility-settings/accessibility-settings.component.html new file mode 100644 index 00000000000..6550c6a2880 --- /dev/null +++ b/src/app/info/accessibility-settings/accessibility-settings.component.html @@ -0,0 +1,26 @@ +
    +

    {{ 'info.accessibility-settings.title' | translate }}

    + +
    +
    + + +
    + + + + {{ 'info.accessibility-settings.' + setting + '.hint' | translate }} + +
    +
    + + +
    + +
    diff --git a/src/app/info/accessibility-settings/accessibility-settings.component.ts b/src/app/info/accessibility-settings/accessibility-settings.component.ts new file mode 100644 index 00000000000..97e3ddb321f --- /dev/null +++ b/src/app/info/accessibility-settings/accessibility-settings.component.ts @@ -0,0 +1,47 @@ +import { Component, OnInit } from '@angular/core'; +import { AuthService } from '../../core/auth/auth.service'; +import { + AccessibilitySetting, + AccessibilitySettingsService, + AccessibilitySettings +} from '../../accessibility/accessibility-settings.service'; +import { take } from 'rxjs'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { TranslateService } from '@ngx-translate/core'; + +@Component({ + selector: 'ds-accessibility-settings', + templateUrl: './accessibility-settings.component.html' +}) +export class AccessibilitySettingsComponent implements OnInit { + + protected accessibilitySettingsOptions: AccessibilitySetting[]; + + protected formValues: AccessibilitySettings = { }; + + constructor( + protected authService: AuthService, + protected settingsService: AccessibilitySettingsService, + protected notificationsService: NotificationsService, + protected translateService: TranslateService, + ) { + } + + ngOnInit() { + this.accessibilitySettingsOptions = this.settingsService.getAllAccessibilitySettingKeys(); + this.settingsService.getAll().pipe(take(1)).subscribe(currentSettings => { + this.formValues = currentSettings; + }); + } + + getInputType(setting: AccessibilitySetting): string { + return this.settingsService.getInputType(setting); + } + + saveSettings() { + this.settingsService.setSettings(this.formValues).pipe(take(1)).subscribe(location => { + this.notificationsService.success(null, this.translateService.instant('info.accessibility-settings.save-notification.' + location)); + }); + } + +} diff --git a/src/app/info/info-routing-paths.ts b/src/app/info/info-routing-paths.ts index a18de2c6111..5210bd7062a 100644 --- a/src/app/info/info-routing-paths.ts +++ b/src/app/info/info-routing-paths.ts @@ -3,6 +3,7 @@ import { getInfoModulePath } from '../app-routing-paths'; export const END_USER_AGREEMENT_PATH = 'end-user-agreement'; export const PRIVACY_PATH = 'privacy'; export const FEEDBACK_PATH = 'feedback'; +export const ACCESSIBILITY_SETTINGS_PATH = 'accessibility'; export function getEndUserAgreementPath() { return getSubPath(END_USER_AGREEMENT_PATH); @@ -16,6 +17,10 @@ export function getFeedbackPath() { return getSubPath(FEEDBACK_PATH); } +export function getAccessibilitySettingsPath() { + return getSubPath(ACCESSIBILITY_SETTINGS_PATH); +} + function getSubPath(path: string) { return `${getInfoModulePath()}/${path}`; } diff --git a/src/app/info/info-routing.module.ts b/src/app/info/info-routing.module.ts index 4c497461e71..45079ba4980 100644 --- a/src/app/info/info-routing.module.ts +++ b/src/app/info/info-routing.module.ts @@ -1,12 +1,18 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; -import { PRIVACY_PATH, END_USER_AGREEMENT_PATH, FEEDBACK_PATH } from './info-routing-paths'; +import { + PRIVACY_PATH, + END_USER_AGREEMENT_PATH, + FEEDBACK_PATH, + ACCESSIBILITY_SETTINGS_PATH +} from './info-routing-paths'; import { ThemedEndUserAgreementComponent } from './end-user-agreement/themed-end-user-agreement.component'; import { ThemedPrivacyComponent } from './privacy/themed-privacy.component'; import { ThemedFeedbackComponent } from './feedback/themed-feedback.component'; import { FeedbackGuard } from '../core/feedback/feedback.guard'; import { environment } from '../../environments/environment'; +import { AccessibilitySettingsComponent } from './accessibility-settings/accessibility-settings.component'; const imports = [ @@ -17,7 +23,13 @@ const imports = [ resolve: { breadcrumb: I18nBreadcrumbResolver }, data: { title: 'info.feedback.title', breadcrumbKey: 'info.feedback' }, canActivate: [FeedbackGuard] - } + }, + { + path: ACCESSIBILITY_SETTINGS_PATH, + component: AccessibilitySettingsComponent, + resolve: { breadcrumb: I18nBreadcrumbResolver }, + data: { title: 'info.accessibility-settings.title', breadcrumbKey: 'info.accessibility-settings' }, + }, ]) ]; diff --git a/src/app/info/info.module.ts b/src/app/info/info.module.ts index ccc4af0a7dd..d01ded1af09 100644 --- a/src/app/info/info.module.ts +++ b/src/app/info/info.module.ts @@ -13,6 +13,7 @@ import { FeedbackFormComponent } from './feedback/feedback-form/feedback-form.co import { ThemedFeedbackFormComponent } from './feedback/feedback-form/themed-feedback-form.component'; import { ThemedFeedbackComponent } from './feedback/themed-feedback.component'; import { FeedbackGuard } from '../core/feedback/feedback.guard'; +import { AccessibilitySettingsComponent } from './accessibility-settings/accessibility-settings.component'; const DECLARATIONS = [ @@ -25,7 +26,8 @@ const DECLARATIONS = [ FeedbackComponent, FeedbackFormComponent, ThemedFeedbackFormComponent, - ThemedFeedbackComponent + ThemedFeedbackComponent, + AccessibilitySettingsComponent, ]; @NgModule({ diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 6c91bae4c16..1316c8d3cf6 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1618,6 +1618,8 @@ "footer.copyright": "copyright © 2002-{{ year }}", + "footer.link.accessibility": "Accessibility settings", + "footer.link.dspace": "DSpace software", "footer.link.lyrasis": "LYRASIS", @@ -1840,6 +1842,24 @@ "home.top-level-communities.help": "Select a community to browse its collections.", + "info.accessibility-settings.breadcrumbs": "Accessibility settings", + + "info.accessibility-settings.liveRegionTimeOut.label": "Live region time-out", + + "info.accessibility-settings.liveRegionTimeOut.hint": "The duration in milliseconds after which a message in the live region disappears.", + + "info.accessibility-settings.notificationTimeOut.label": "Notification time-out", + + "info.accessibility-settings.notificationTimeOut.hint": "The duration in milliseconds after which a notification disappears. Set to 0 for notifications to remain indefinitely.", + + "info.accessibility-settings.save-notification.cookie": "Successfully saved settings locally.", + + "info.accessibility-settings.save-notification.metadata": "Successfully saved settings on the user profile.", + + "info.accessibility-settings.submit": "Save accessibility settings", + + "info.accessibility-settings.title": "Accessibility settings", + "info.end-user-agreement.accept": "I have read and I agree to the End User Agreement", "info.end-user-agreement.accept.error": "An error occurred accepting the End User Agreement", From d224a2c47db09d6e202f66f0192afc8ad2ab1ce5 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 22 Oct 2024 15:03:37 +0200 Subject: [PATCH 323/822] 119602: Integrate accessibility settings into live-region --- .../shared/live-region/live-region.service.ts | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/app/shared/live-region/live-region.service.ts b/src/app/shared/live-region/live-region.service.ts index 72940c1a0eb..7a7b99fa6e7 100644 --- a/src/app/shared/live-region/live-region.service.ts +++ b/src/app/shared/live-region/live-region.service.ts @@ -1,7 +1,10 @@ import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, map, Observable, switchMap, take, timer } from 'rxjs'; import { environment } from '../../../environments/environment'; import { UUIDService } from '../../core/shared/uuid.service'; +import { AccessibilitySettingsService, AccessibilitySetting } from '../../accessibility/accessibility-settings.service'; + +export const MIN_MESSAGE_DURATION = 200; /** * The LiveRegionService is responsible for handling the messages that are shown by the {@link LiveRegionComponent}. @@ -14,6 +17,7 @@ export class LiveRegionService { constructor( protected uuidService: UUIDService, + protected accessibilitySettingsService: AccessibilitySettingsService, ) { } @@ -64,7 +68,12 @@ export class LiveRegionService { addMessage(message: string): string { const uuid = this.uuidService.generate(); this.messages.push({ message, uuid }); - setTimeout(() => this.clearMessageByUUID(uuid), this.messageTimeOutDurationMs); + + this.getConfiguredMessageTimeOutMs().pipe( + take(1), + switchMap(timeOut => timer(timeOut)), + ).subscribe(() => this.clearMessageByUUID(uuid)); + this.emitCurrentMessages(); return uuid; } @@ -115,6 +124,17 @@ export class LiveRegionService { this.liveRegionIsVisible = isVisible; } + /** + * Gets the user-configured timeOut, or the stored timeOut if the user has not configured a timeOut duration. + * Emits {@link MIN_MESSAGE_DURATION} if the configured value is smaller. + */ + getConfiguredMessageTimeOutMs(): Observable { + return this.accessibilitySettingsService.getAsNumber( + AccessibilitySetting.LiveRegionTimeOut, + this.getMessageTimeOutMs(), + ).pipe(map(timeOut => Math.max(timeOut, MIN_MESSAGE_DURATION))); + } + /** * Gets the current message timeOut duration in milliseconds */ From 6a49df59af0206b1cf2bd8b6cba4a3391ba7eeac Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 25 Oct 2024 13:04:55 +0200 Subject: [PATCH 324/822] 119602: Integrate accessibility settings into notifications-board --- .../notifications-board.component.ts | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/app/shared/notifications/notifications-board/notifications-board.component.ts b/src/app/shared/notifications/notifications-board/notifications-board.component.ts index 97ae09c1a67..20bf7175f6f 100644 --- a/src/app/shared/notifications/notifications-board/notifications-board.component.ts +++ b/src/app/shared/notifications/notifications-board/notifications-board.component.ts @@ -9,7 +9,7 @@ import { } from '@angular/core'; import { select, Store } from '@ngrx/store'; -import { BehaviorSubject, Subscription } from 'rxjs'; +import { BehaviorSubject, Subscription, take } from 'rxjs'; import difference from 'lodash/difference'; import { NotificationsService } from '../notifications.service'; @@ -18,6 +18,11 @@ import { notificationsStateSelector } from '../selectors'; import { INotification } from '../models/notification.model'; import { NotificationsState } from '../notifications.reducers'; import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces'; +import { + AccessibilitySettingsService, + AccessibilitySetting +} from '../../../accessibility/accessibility-settings.service'; +import cloneDeep from 'lodash/cloneDeep'; @Component({ selector: 'ds-notifications-board', @@ -49,9 +54,12 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy { */ public isPaused$: BehaviorSubject = new BehaviorSubject(false); - constructor(private service: NotificationsService, - private store: Store, - private cdr: ChangeDetectorRef) { + constructor( + protected service: NotificationsService, + protected store: Store, + protected cdr: ChangeDetectorRef, + protected accessibilitySettingsService: AccessibilitySettingsService, + ) { } ngOnInit(): void { @@ -84,7 +92,22 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy { if (this.notifications.length >= this.maxStack) { this.notifications.splice(this.notifications.length - 1, 1); } - this.notifications.splice(0, 0, item); + + // It would be a bit better to handle the retrieval of configured settings in the NotificationsService. + // Due to circular dependencies this is difficult to implement. + this.accessibilitySettingsService.getAsNumber(AccessibilitySetting.NotificationTimeOut, item.options.timeOut) + .pipe(take(1)).subscribe(timeOut => { + if (timeOut < 0) { + timeOut = 0; + } + + // Deep clone because the unaltered item is read-only + const modifiedNotification = cloneDeep(item); + modifiedNotification.options.timeOut = timeOut; + this.notifications.splice(0, 0, modifiedNotification); + this.cdr.detectChanges(); + }); + } else { // Remove the notification from the store // This notification was in the store, but not in this.notifications From cad086c94599675b195f2685312c52e8c83e16f8 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 25 Oct 2024 14:39:23 +0200 Subject: [PATCH 325/822] 119602: Add AccessibilitySettingsService stub & fix live-region test --- .../accessibility-settings.service.stub.ts | 34 ++++++++++++ .../live-region/live-region.service.spec.ts | 55 +++++-------------- .../notifications-board.component.spec.ts | 3 + 3 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 src/app/accessibility/accessibility-settings.service.stub.ts diff --git a/src/app/accessibility/accessibility-settings.service.stub.ts b/src/app/accessibility/accessibility-settings.service.stub.ts new file mode 100644 index 00000000000..b619a337de9 --- /dev/null +++ b/src/app/accessibility/accessibility-settings.service.stub.ts @@ -0,0 +1,34 @@ +import { of } from 'rxjs'; +import { AccessibilitySettingsService } from './accessibility-settings.service'; + +export function getAccessibilitySettingsServiceStub(): AccessibilitySettingsService { + return new AccessibilitySettingsServiceStub() as unknown as AccessibilitySettingsService; +} + +export class AccessibilitySettingsServiceStub { + getAllAccessibilitySettingKeys = jasmine.createSpy('getAllAccessibilitySettingKeys').and.returnValue([]); + + get = jasmine.createSpy('get').and.returnValue(of(null)); + + getAsNumber = jasmine.createSpy('getAsNumber').and.returnValue(of(0)); + + getAll = jasmine.createSpy('getAll').and.returnValue(of({})); + + getAllSettingsFromCookie = jasmine.createSpy('getAllSettingsFromCookie').and.returnValue({}); + + getAllSettingsFromAuthenticatedUserMetadata = jasmine.createSpy('getAllSettingsFromAuthenticatedUserMetadata') + .and.returnValue(of({})); + + set = jasmine.createSpy('setSettings').and.returnValue(of('cookie')); + + updateSettings = jasmine.createSpy('updateSettings').and.returnValue(of('cookie')); + + setSettingsInAuthenticatedUserMetadata = jasmine.createSpy('setSettingsInAuthenticatedUserMetadata') + .and.returnValue(of(false)); + + setSettingsInMetadata = jasmine.createSpy('setSettingsInMetadata').and.returnValue(of(false)); + + setSettingsInCookie = jasmine.createSpy('setSettingsInCookie'); + + getInputType = jasmine.createSpy('getInputType').and.returnValue('text'); +} diff --git a/src/app/shared/live-region/live-region.service.spec.ts b/src/app/shared/live-region/live-region.service.spec.ts index 858ef883134..b14fa7abaf2 100644 --- a/src/app/shared/live-region/live-region.service.spec.ts +++ b/src/app/shared/live-region/live-region.service.spec.ts @@ -1,13 +1,22 @@ import { LiveRegionService } from './live-region.service'; -import { fakeAsync, tick, flush } from '@angular/core/testing'; +import { fakeAsync, tick } from '@angular/core/testing'; import { UUIDService } from '../../core/shared/uuid.service'; +import { getAccessibilitySettingsServiceStub } from '../../accessibility/accessibility-settings.service.stub'; +import { AccessibilitySettingsService } from '../../accessibility/accessibility-settings.service'; +import { of } from 'rxjs'; describe('liveRegionService', () => { let service: LiveRegionService; + let accessibilitySettingsService: AccessibilitySettingsService; beforeEach(() => { + accessibilitySettingsService = getAccessibilitySettingsServiceStub(); + + accessibilitySettingsService.getAsNumber = jasmine.createSpy('getAsNumber').and.returnValue(of(100)); + service = new LiveRegionService( new UUIDService(), + accessibilitySettingsService, ); }); @@ -81,13 +90,16 @@ describe('liveRegionService', () => { expect(results[2]).toEqual(['Message One', 'Message Two']); service.clear(); - flush(); + tick(200); expect(results.length).toEqual(4); expect(results[3]).toEqual([]); })); it('should not pop messages added after clearing within timeOut period', fakeAsync(() => { + // test expects a clear rate of 30 seconds + accessibilitySettingsService.getAsNumber = jasmine.createSpy('getAsNumber').and.returnValue(of(30000)); + const results: string[][] = []; service.getMessages$().subscribe((messages) => { @@ -114,45 +126,6 @@ describe('liveRegionService', () => { expect(results.length).toEqual(5); expect(results[4]).toEqual([]); })); - - it('should respect configured timeOut', fakeAsync(() => { - const results: string[][] = []; - - service.getMessages$().subscribe((messages) => { - results.push(messages); - }); - - expect(results.length).toEqual(1); - expect(results[0]).toEqual([]); - - const timeOutMs = 500; - service.setMessageTimeOutMs(timeOutMs); - - service.addMessage('Message One'); - tick(timeOutMs - 1); - - expect(results.length).toEqual(2); - expect(results[1]).toEqual(['Message One']); - - tick(1); - - expect(results.length).toEqual(3); - expect(results[2]).toEqual([]); - - const timeOutMsTwo = 50000; - service.setMessageTimeOutMs(timeOutMsTwo); - - service.addMessage('Message Two'); - tick(timeOutMsTwo - 1); - - expect(results.length).toEqual(4); - expect(results[3]).toEqual(['Message Two']); - - tick(1); - - expect(results.length).toEqual(5); - expect(results[4]).toEqual([]); - })); }); describe('liveRegionVisibility', () => { diff --git a/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts b/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts index 08b9585a8c7..22d0671d9c7 100644 --- a/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts +++ b/src/app/shared/notifications/notifications-board/notifications-board.component.spec.ts @@ -15,6 +15,8 @@ import uniqueId from 'lodash/uniqueId'; import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces'; import { NotificationsServiceStub } from '../../testing/notifications-service.stub'; import { cold } from 'jasmine-marbles'; +import { AccessibilitySettingsService } from '../../../accessibility/accessibility-settings.service'; +import { getAccessibilitySettingsServiceStub } from '../../../accessibility/accessibility-settings.service.stub'; export const bools = { f: false, t: true }; @@ -36,6 +38,7 @@ describe('NotificationsBoardComponent', () => { declarations: [NotificationsBoardComponent, NotificationComponent], // declare the test component providers: [ { provide: NotificationsService, useClass: NotificationsServiceStub }, + { provide: AccessibilitySettingsService, useValue: getAccessibilitySettingsServiceStub() }, ChangeDetectorRef] }).compileComponents(); // compile template and css })); From 52eabec70d46649fd97faeee229deaac0da989f5 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Fri, 25 Oct 2024 15:27:37 +0200 Subject: [PATCH 326/822] 119602: Add AccessibilitySettingsService tests --- .../accessibility-settings.service.spec.ts | 379 ++++++++++++++++++ src/app/shared/testing/auth-service.stub.ts | 4 + 2 files changed, 383 insertions(+) create mode 100644 src/app/accessibility/accessibility-settings.service.spec.ts diff --git a/src/app/accessibility/accessibility-settings.service.spec.ts b/src/app/accessibility/accessibility-settings.service.spec.ts new file mode 100644 index 00000000000..d6f61840575 --- /dev/null +++ b/src/app/accessibility/accessibility-settings.service.spec.ts @@ -0,0 +1,379 @@ +import { + AccessibilitySettingsService, + AccessibilitySetting, + AccessibilitySettings, + ACCESSIBILITY_SETTINGS_METADATA_KEY, + ACCESSIBILITY_COOKIE +} from './accessibility-settings.service'; +import { CookieService } from '../core/services/cookie.service'; +import { AuthService } from '../core/auth/auth.service'; +import { EPersonDataService } from '../core/eperson/eperson-data.service'; +import { CookieServiceMock } from '../shared/mocks/cookie.service.mock'; +import { AuthServiceStub } from '../shared/testing/auth-service.stub'; +import { of } from 'rxjs'; +import { EPerson } from '../core/eperson/models/eperson.model'; +import { fakeAsync, flush } from '@angular/core/testing'; +import { createSuccessfulRemoteDataObject$, createFailedRemoteDataObject$ } from '../shared/remote-data.utils'; + + +describe('accessibilitySettingsService', () => { + let service: AccessibilitySettingsService; + let cookieService: CookieServiceMock; + let authService: AuthServiceStub; + let ePersonService: EPersonDataService; + + beforeEach(() => { + cookieService = new CookieServiceMock(); + authService = new AuthServiceStub(); + + ePersonService = jasmine.createSpyObj('ePersonService', { + createPatchFromCache: of([{ + op: 'add', + value: null, + }]), + patch: of({}), + }); + + service = new AccessibilitySettingsService( + cookieService as unknown as CookieService, + authService as unknown as AuthService, + ePersonService, + ); + }); + + describe('getALlAccessibilitySettingsKeys', () => { + it('should return an array containing all accessibility setting names', () => { + const settingNames: AccessibilitySetting[] = [ + AccessibilitySetting.NotificationTimeOut, + AccessibilitySetting.LiveRegionTimeOut, + ]; + + expect(service.getAllAccessibilitySettingKeys()).toEqual(settingNames); + }); + }); + + describe('get', () => { + it('should return the setting if it is set', () => { + const settings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.getAll = jasmine.createSpy('getAll').and.returnValue(of(settings)); + + service.get(AccessibilitySetting.NotificationTimeOut, 'default').subscribe(value => + expect(value).toEqual('1000') + ); + }); + + it('should return the default value if the setting is not set', () => { + const settings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.getAll = jasmine.createSpy('getAll').and.returnValue(of(settings)); + + service.get(AccessibilitySetting.LiveRegionTimeOut, 'default').subscribe(value => + expect(value).toEqual('default') + ); + }); + }); + + describe('getAsNumber', () => { + it('should return the setting as number if the value for the setting can be parsed to a number', () => { + service.get = jasmine.createSpy('get').and.returnValue(of('1000')); + + service.getAsNumber(AccessibilitySetting.NotificationTimeOut).subscribe(value => + expect(value).toEqual(1000) + ); + }); + + it('should return the default value if no value is set for the setting', () => { + service.get = jasmine.createSpy('get').and.returnValue(of(null)); + + service.getAsNumber(AccessibilitySetting.NotificationTimeOut, 123).subscribe(value => + expect(value).toEqual(123) + ); + }); + + it('should return the default value if the value for the setting can not be parsed to a number', () => { + service.get = jasmine.createSpy('get').and.returnValue(of('text')); + + service.getAsNumber(AccessibilitySetting.NotificationTimeOut, 123).subscribe(value => + expect(value).toEqual(123) + ); + }); + }); + + describe('getAll', () => { + it('should attempt to get the settings from metadata first', () => { + service.getAllSettingsFromAuthenticatedUserMetadata = + jasmine.createSpy('getAllSettingsFromAuthenticatedUserMetadata').and.returnValue(of({ })); + + service.getAll().subscribe(); + expect(service.getAllSettingsFromAuthenticatedUserMetadata).toHaveBeenCalled(); + }); + + it('should attempt to get the settings from the cookie if the settings from metadata are empty', () => { + service.getAllSettingsFromAuthenticatedUserMetadata = + jasmine.createSpy('getAllSettingsFromAuthenticatedUserMetadata').and.returnValue(of({ })); + + service.getAllSettingsFromCookie = jasmine.createSpy('getAllSettingsFromCookie').and.returnValue({ }); + + service.getAll().subscribe(); + expect(service.getAllSettingsFromCookie).toHaveBeenCalled(); + }); + + it('should not attempt to get the settings from the cookie if the settings from metadata are not empty', () => { + const settings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.getAllSettingsFromAuthenticatedUserMetadata = + jasmine.createSpy('getAllSettingsFromAuthenticatedUserMetadata').and.returnValue(of(settings)); + + service.getAllSettingsFromCookie = jasmine.createSpy('getAllSettingsFromCookie').and.returnValue({ }); + + service.getAll().subscribe(); + expect(service.getAllSettingsFromCookie).not.toHaveBeenCalled(); + }); + + it('should return an empty object if both are empty', () => { + service.getAllSettingsFromAuthenticatedUserMetadata = + jasmine.createSpy('getAllSettingsFromAuthenticatedUserMetadata').and.returnValue(of({ })); + + service.getAllSettingsFromCookie = jasmine.createSpy('getAllSettingsFromCookie').and.returnValue({ }); + + service.getAll().subscribe(value => expect(value).toEqual({})); + }); + }); + + describe('getAllSettingsFromCookie', () => { + it('should retrieve the settings from the cookie', () => { + cookieService.get = jasmine.createSpy(); + + service.getAllSettingsFromCookie(); + expect(cookieService.get).toHaveBeenCalledWith(ACCESSIBILITY_COOKIE); + }); + }); + + describe('getAllSettingsFromAuthenticatedUserMetadata', () => { + it('should retrieve all settings from the user\'s metadata', () => { + const settings = { 'liveRegionTimeOut': '1000' }; + + const user = new EPerson(); + user.setMetadata(ACCESSIBILITY_SETTINGS_METADATA_KEY, null, JSON.stringify(settings)); + + authService.getAuthenticatedUserFromStoreIfAuthenticated = + jasmine.createSpy('getAuthenticatedUserFromStoreIfAuthenticated').and.returnValue(of(user)); + + service.getAllSettingsFromAuthenticatedUserMetadata().subscribe(value => + expect(value).toEqual(settings) + ); + }); + }); + + describe('set', () => { + it('should correctly update the chosen setting', () => { + service.updateSettings = jasmine.createSpy('updateSettings'); + + service.set(AccessibilitySetting.LiveRegionTimeOut, '500'); + expect(service.updateSettings).toHaveBeenCalledWith({ liveRegionTimeOut: '500' }); + }); + }); + + describe('setSettings', () => { + beforeEach(() => { + service.setSettingsInCookie = jasmine.createSpy('setSettingsInCookie'); + }); + + it('should attempt to set settings in metadata', () => { + service.setSettingsInAuthenticatedUserMetadata = + jasmine.createSpy('setSettingsInAuthenticatedUserMetadata').and.returnValue(of(false)); + + const settings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.setSettings(settings).subscribe(); + expect(service.setSettingsInAuthenticatedUserMetadata).toHaveBeenCalledWith(settings); + }); + + it('should set settings in cookie if metadata failed', () => { + service.setSettingsInAuthenticatedUserMetadata = + jasmine.createSpy('setSettingsInAuthenticatedUserMetadata').and.returnValue(of(false)); + + const settings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.setSettings(settings).subscribe(); + expect(service.setSettingsInCookie).toHaveBeenCalled(); + }); + + it('should not set settings in cookie if metadata succeeded', () => { + service.setSettingsInAuthenticatedUserMetadata = + jasmine.createSpy('setSettingsInAuthenticatedUserMetadata').and.returnValue(of(true)); + + const settings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.setSettings(settings).subscribe(); + expect(service.setSettingsInCookie).not.toHaveBeenCalled(); + }); + + it('should return \'metadata\' if settings are stored in metadata', () => { + service.setSettingsInAuthenticatedUserMetadata = + jasmine.createSpy('setSettingsInAuthenticatedUserMetadata').and.returnValue(of(true)); + + const settings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.setSettings(settings).subscribe(value => + expect(value).toEqual('metadata') + ); + }); + + it('should return \'cookie\' if settings are stored in cookie', () => { + service.setSettingsInAuthenticatedUserMetadata = + jasmine.createSpy('setSettingsInAuthenticatedUserMetadata').and.returnValue(of(false)); + + const settings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.setSettings(settings).subscribe(value => + expect(value).toEqual('cookie') + ); + }); + }); + + describe('updateSettings', () => { + it('should call setSettings with the updated settings', () => { + const beforeSettings: AccessibilitySettings = { + notificationTimeOut: '1000', + }; + + service.getAll = jasmine.createSpy('getAll').and.returnValue(of(beforeSettings)); + service.setSettings = jasmine.createSpy('setSettings').and.returnValue(of('cookie')); + + const newSettings: AccessibilitySettings = { + liveRegionTimeOut: '2000', + }; + + const combinedSettings: AccessibilitySettings = { + notificationTimeOut: '1000', + liveRegionTimeOut: '2000', + }; + + service.updateSettings(newSettings).subscribe(); + expect(service.setSettings).toHaveBeenCalledWith(combinedSettings); + }); + }); + + describe('setSettingsInAuthenticatedUserMetadata', () => { + beforeEach(() => { + service.setSettingsInMetadata = jasmine.createSpy('setSettingsInMetadata').and.returnValue(of(null)); + }); + + it('should store settings in metadata when the user is authenticated', fakeAsync(() => { + const user = new EPerson(); + authService.getAuthenticatedUserFromStoreIfAuthenticated = jasmine.createSpy().and.returnValue(of(user)); + + service.setSettingsInAuthenticatedUserMetadata({}).subscribe(); + flush(); + + expect(service.setSettingsInMetadata).toHaveBeenCalled(); + })); + + it('should emit false when the user is not authenticated', fakeAsync(() => { + authService.getAuthenticatedUserFromStoreIfAuthenticated = jasmine.createSpy().and.returnValue(of(null)); + + service.setSettingsInAuthenticatedUserMetadata({}) + .subscribe(value => expect(value).toBeFalse()); + flush(); + + expect(service.setSettingsInMetadata).not.toHaveBeenCalled(); + })); + }); + + describe('setSettingsInMetadata', () => { + const ePerson = new EPerson(); + + beforeEach(() => { + ePerson.setMetadata = jasmine.createSpy('setMetadata'); + ePerson.removeMetadata = jasmine.createSpy('removeMetadata'); + }); + + it('should set the settings in metadata', () => { + service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' }).subscribe(); + expect(ePerson.setMetadata).toHaveBeenCalled(); + }); + + it('should remove the metadata when the settings are emtpy', () => { + service.setSettingsInMetadata(ePerson, {}).subscribe(); + expect(ePerson.setMetadata).not.toHaveBeenCalled(); + expect(ePerson.removeMetadata).toHaveBeenCalled(); + }); + + it('should create a patch with the metadata changes', () => { + service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' }).subscribe(); + expect(ePersonService.createPatchFromCache).toHaveBeenCalled(); + }); + + it('should send the patch request', () => { + service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' }).subscribe(); + expect(ePersonService.patch).toHaveBeenCalled(); + }); + + it('should emit true when the update succeeded', fakeAsync(() => { + ePersonService.patch = jasmine.createSpy().and.returnValue(createSuccessfulRemoteDataObject$({})); + + service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' }) + .subscribe(value => { + expect(value).toBeTrue(); + }); + + flush(); + })); + + it('should emit false when the update failed', fakeAsync(() => { + ePersonService.patch = jasmine.createSpy().and.returnValue(createFailedRemoteDataObject$()); + + service.setSettingsInMetadata(ePerson, { [AccessibilitySetting.LiveRegionTimeOut]: '500' }) + .subscribe(value => { + expect(value).toBeFalse(); + }); + + flush(); + })); + }); + + describe('setSettingsInCookie', () => { + beforeEach(() => { + cookieService.set = jasmine.createSpy('set'); + cookieService.remove = jasmine.createSpy('remove'); + }); + + it('should store the settings in a cookie', () => { + service.setSettingsInCookie({ [AccessibilitySetting.LiveRegionTimeOut]: '500' }); + expect(cookieService.set).toHaveBeenCalled(); + }); + + it('should remove the cookie when the settings are empty', () => { + service.setSettingsInCookie({}); + expect(cookieService.set).not.toHaveBeenCalled(); + expect(cookieService.remove).toHaveBeenCalled(); + }); + }); + + describe('getInputType', () => { + it('should correctly return the input type', () => { + expect(service.getInputType(AccessibilitySetting.NotificationTimeOut)).toEqual('number'); + expect(service.getInputType(AccessibilitySetting.LiveRegionTimeOut)).toEqual('number'); + expect(service.getInputType('unknownValue' as AccessibilitySetting)).toEqual('text'); + }); + }); + +}); diff --git a/src/app/shared/testing/auth-service.stub.ts b/src/app/shared/testing/auth-service.stub.ts index 7f3d040042f..d150ac69f4d 100644 --- a/src/app/shared/testing/auth-service.stub.ts +++ b/src/app/shared/testing/auth-service.stub.ts @@ -54,6 +54,10 @@ export class AuthServiceStub { return observableOf(EPersonMock); } + getAuthenticatedUserFromStoreIfAuthenticated(): Observable { + return observableOf(EPersonMock); + } + public buildAuthHeader(token?: AuthTokenInfo): string { return `Bearer ${token ? token.accessToken : ''}`; } From 82fd9539b7862186f2396a64db8988bc7f38f362 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 5 Nov 2024 15:03:51 +0100 Subject: [PATCH 327/822] 119602: Add AccessibilitySettingsComponent tests --- .../accessibility-settings.component.spec.ts | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/app/info/accessibility-settings/accessibility-settings.component.spec.ts diff --git a/src/app/info/accessibility-settings/accessibility-settings.component.spec.ts b/src/app/info/accessibility-settings/accessibility-settings.component.spec.ts new file mode 100644 index 00000000000..f6d3252a384 --- /dev/null +++ b/src/app/info/accessibility-settings/accessibility-settings.component.spec.ts @@ -0,0 +1,79 @@ +import { AccessibilitySettingsComponent } from './accessibility-settings.component'; +import { ComponentFixture, waitForAsync, TestBed } from '@angular/core/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { AuthServiceStub } from '../../shared/testing/auth-service.stub'; +import { getAccessibilitySettingsServiceStub } from '../../accessibility/accessibility-settings.service.stub'; +import { AccessibilitySettingsService, AccessibilitySetting } from '../../accessibility/accessibility-settings.service'; +import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; +import { AuthService } from '../../core/auth/auth.service'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { of } from 'rxjs'; + + +describe('AccessibilitySettingsComponent', () => { + let component: AccessibilitySettingsComponent; + let fixture: ComponentFixture; + + let authService: AuthServiceStub; + let settingsService: AccessibilitySettingsService; + let notificationsService: NotificationsServiceStub; + + beforeEach(waitForAsync(() => { + authService = new AuthServiceStub(); + settingsService = getAccessibilitySettingsServiceStub(); + notificationsService = new NotificationsServiceStub(); + + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [AccessibilitySettingsComponent], + providers: [ + { provide: AuthService, useValue: authService }, + { provide: AccessibilitySettingsService, useValue: settingsService }, + { provide: NotificationsService, useValue: notificationsService }, + ], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AccessibilitySettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('On Init', () => { + it('should retrieve all accessibility settings options', () => { + expect(settingsService.getAllAccessibilitySettingKeys).toHaveBeenCalled(); + }); + + it('should retrieve the current settings', () => { + expect(settingsService.getAll).toHaveBeenCalled(); + }); + }); + + describe('getInputType', () => { + it('should retrieve the input type for the setting from the service', () => { + component.getInputType(AccessibilitySetting.LiveRegionTimeOut); + expect(settingsService.getInputType).toHaveBeenCalledWith(AccessibilitySetting.LiveRegionTimeOut); + }); + }); + + describe('saveSettings', () => { + it('should save the settings in the service', () => { + settingsService.setSettings = jasmine.createSpy('setSettings').and.returnValue(of('cookie')); + component.saveSettings(); + expect(settingsService.setSettings).toHaveBeenCalled(); + }); + + it('should give the user a notification mentioning where the settings were saved', () => { + settingsService.setSettings = jasmine.createSpy('setSettings').and.returnValue(of('cookie')); + component.saveSettings(); + expect(notificationsService.success).toHaveBeenCalled(); + }); + }); +}); From 37455a8b6c8f768b5b8cc7a3f4877740b2ae44bd Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 5 Nov 2024 15:52:11 +0100 Subject: [PATCH 328/822] 119602: Make AccessibilitySettings cookie expiration configurable --- config/config.example.yml | 5 +++++ .../accessibility/accessibility-settings.config.ts | 11 +++++++++++ .../accessibility/accessibility-settings.service.ts | 8 ++------ src/config/app-config.interface.ts | 2 ++ src/config/default-app-config.ts | 6 ++++++ src/environments/environment.test.ts | 4 ++++ 6 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 src/app/accessibility/accessibility-settings.config.ts diff --git a/config/config.example.yml b/config/config.example.yml index 58eb6ff33d2..7b882958f24 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -394,3 +394,8 @@ liveRegion: messageTimeOutDurationMs: 30000 # The visibility of the live region. Setting this to true is only useful for debugging purposes. isVisible: false + +# Configuration for storing accessibility settings, used by the AccessibilitySettingsService +accessibility: + # The duration in days after which the accessibility settings cookie expires + cookieExpirationDuration: 7 diff --git a/src/app/accessibility/accessibility-settings.config.ts b/src/app/accessibility/accessibility-settings.config.ts new file mode 100644 index 00000000000..1852579c3d3 --- /dev/null +++ b/src/app/accessibility/accessibility-settings.config.ts @@ -0,0 +1,11 @@ +import { Config } from '../../config/config.interface'; + +/** + * Configuration interface used by the AccessibilitySettingsService + */ +export class AccessibilitySettingsConfig implements Config { + /** + * The duration in days after which the accessibility settings cookie expires + */ + cookieExpirationDuration: number; +} diff --git a/src/app/accessibility/accessibility-settings.service.ts b/src/app/accessibility/accessibility-settings.service.ts index 805d0d5a0b1..4089fd03b17 100644 --- a/src/app/accessibility/accessibility-settings.service.ts +++ b/src/app/accessibility/accessibility-settings.service.ts @@ -8,6 +8,7 @@ import { EPerson } from '../core/eperson/models/eperson.model'; import { EPersonDataService } from '../core/eperson/eperson-data.service'; import { getFirstCompletedRemoteData } from '../core/shared/operators'; import cloneDeep from 'lodash/cloneDeep'; +import { environment } from '../../environments/environment'; /** * Name of the cookie used to store the settings locally @@ -19,11 +20,6 @@ export const ACCESSIBILITY_COOKIE = 'dsAccessibilityCookie'; */ export const ACCESSIBILITY_SETTINGS_METADATA_KEY = 'dspace.accessibility.settings'; -/** - * The duration in days after which the accessibility settings cookie expires - */ -export const ACCESSIBILITY_SETTINGS_COOKIE_STORAGE_DURATION = 7; - /** * Enum containing all possible accessibility settings. * When adding new settings, the {@link AccessibilitySettingsService#getInputType} method and the i18n keys for the @@ -208,7 +204,7 @@ export class AccessibilitySettingsService { */ setSettingsInCookie(settings: AccessibilitySettings) { if (isNotEmpty(settings)) { - this.cookieService.set(ACCESSIBILITY_COOKIE, settings, { expires: ACCESSIBILITY_SETTINGS_COOKIE_STORAGE_DURATION }); + this.cookieService.set(ACCESSIBILITY_COOKIE, settings, { expires: environment.accessibility.cookieExpirationDuration }); } else { this.cookieService.remove(ACCESSIBILITY_COOKIE); } diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index aa3033ecec3..6cbcf782af9 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -23,6 +23,7 @@ import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; import { LiveRegionConfig } from '../app/shared/live-region/live-region.config'; +import { AccessibilitySettingsConfig } from '../app/accessibility/accessibility-settings.config'; interface AppConfig extends Config { ui: UIServerConfig; @@ -50,6 +51,7 @@ interface AppConfig extends Config { vocabularies: FilterVocabularyConfig[]; comcolSelectionSort: DiscoverySortConfig; liveRegion: LiveRegionConfig; + accessibility: AccessibilitySettingsConfig; } /** diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 1c0f88cf477..c7aac9a2d78 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -23,6 +23,7 @@ import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; import { DiscoverySortConfig } from './discovery-sort.config'; import { LiveRegionConfig } from '../app/shared/live-region/live-region.config'; +import { AccessibilitySettingsConfig } from '../app/accessibility/accessibility-settings.config'; export class DefaultAppConfig implements AppConfig { production = false; @@ -439,4 +440,9 @@ export class DefaultAppConfig implements AppConfig { messageTimeOutDurationMs: 30000, isVisible: false, }; + + // Accessibility settings configuration, used by the AccessibilitySettingsService + accessibility: AccessibilitySettingsConfig = { + cookieExpirationDuration: 7, + }; } diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 498799a454b..77094ada805 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -319,4 +319,8 @@ export const environment: BuildConfig = { messageTimeOutDurationMs: 30000, isVisible: false, }, + + accessibility: { + cookieExpirationDuration: 7, + }, }; From 04515591e2b1b5bd3d892556d195423913ee8779 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Tue, 5 Nov 2024 16:01:05 +0100 Subject: [PATCH 329/822] 119602: Add link to AccessibilitySettings on profile page --- src/app/profile-page/profile-page.component.html | 10 +++++++++- src/assets/i18n/en.json5 | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/app/profile-page/profile-page.component.html b/src/app/profile-page/profile-page.component.html index 44783da84e8..d8394ac5d4c 100644 --- a/src/app/profile-page/profile-page.component.html +++ b/src/app/profile-page/profile-page.component.html @@ -28,10 +28,18 @@

    {{'profile.head' | translate}}

    >
    -
    +
    +
    +
    {{'profile.card.accessibility.header' | translate}}
    +
    +
    {{'profile.card.accessibility.content' | translate}}
    + {{'profile.card.accessibility.link' | translate}} +
    +
    +

    {{'profile.groups.head' | translate}}

    diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 1316c8d3cf6..fc749377a98 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3274,6 +3274,12 @@ "profile.breadcrumbs": "Update Profile", + "profile.card.accessibility.content": "Accessibility settings can be configured on the accessibility settings page.", + + "profile.card.accessibility.header": "Accessibility", + + "profile.card.accessibility.link": "Accessibility Settings Page", + "profile.card.identify": "Identify", "profile.card.security": "Security", From bb7f0cd3a5adb0729a6b979ad0a4562f1ca52761 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Thu, 7 Nov 2024 10:18:11 +0100 Subject: [PATCH 330/822] 119602: Improve profile page link accessibility --- src/app/profile-page/profile-page.component.html | 2 +- src/assets/i18n/en.json5 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/profile-page/profile-page.component.html b/src/app/profile-page/profile-page.component.html index d8394ac5d4c..d2809a04b64 100644 --- a/src/app/profile-page/profile-page.component.html +++ b/src/app/profile-page/profile-page.component.html @@ -35,7 +35,7 @@

    {{'profile.head' | translate}}

    {{'profile.card.accessibility.header' | translate}}
    -
    {{'profile.card.accessibility.content' | translate}}
    + {{'profile.card.accessibility.content' | translate}} {{'profile.card.accessibility.link' | translate}}
    diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index fc749377a98..dc69f0fbe86 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3278,7 +3278,7 @@ "profile.card.accessibility.header": "Accessibility", - "profile.card.accessibility.link": "Accessibility Settings Page", + "profile.card.accessibility.link": "Go to Accessibility Settings Page", "profile.card.identify": "Identify", From 87f5b502010581ad4d8f3152aa126dbc6c6bbe62 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Thu, 7 Nov 2024 19:58:01 +0100 Subject: [PATCH 331/822] update comment to correctly describe component's purpose (cherry picked from commit 33dddc697fb86d449998900ab82e4f876631eaac) --- .../bitstream-authorizations.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts b/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts index adc06387804..90b4151a9dd 100644 --- a/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts +++ b/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts @@ -12,7 +12,7 @@ import { DSpaceObject } from '../../core/shared/dspace-object.model'; templateUrl: './bitstream-authorizations.component.html', }) /** - * Component that handles the Collection Authorizations + * Component that handles the Bitstream Authorizations */ export class BitstreamAuthorizationsComponent implements OnInit { From 9f879d38501f68e068350b567dafbe9b0a858d92 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Thu, 7 Nov 2024 20:02:39 +0100 Subject: [PATCH 332/822] fix invalid selector (cherry picked from commit 752951ce3b05436a13d689fc492fa0b95563862e) --- .../bitstream-authorizations.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts b/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts index 90b4151a9dd..72683f5d74f 100644 --- a/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts +++ b/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts @@ -8,7 +8,7 @@ import { RemoteData } from '../../core/data/remote-data'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; @Component({ - selector: 'ds-collection-authorizations', + selector: 'ds-bitstream-authorizations', templateUrl: './bitstream-authorizations.component.html', }) /** From 62a1443b755843787f3d95cb5d590b75863007e8 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Thu, 7 Nov 2024 19:58:01 +0100 Subject: [PATCH 333/822] update comment to correctly describe component's purpose (cherry picked from commit 33dddc697fb86d449998900ab82e4f876631eaac) --- .../bitstream-authorizations.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts b/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts index 4bb89a85f4d..158eafd0eb7 100644 --- a/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts +++ b/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts @@ -30,7 +30,7 @@ import { ResourcePoliciesComponent } from '../../shared/resource-policies/resour standalone: true, }) /** - * Component that handles the Collection Authorizations + * Component that handles the Bitstream Authorizations */ export class BitstreamAuthorizationsComponent implements OnInit { From fb57b72eca1347931e3682b8563b00b18b0f5bd0 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Thu, 7 Nov 2024 20:02:39 +0100 Subject: [PATCH 334/822] fix invalid selector (cherry picked from commit 752951ce3b05436a13d689fc492fa0b95563862e) --- .../bitstream-authorizations.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts b/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts index 158eafd0eb7..d6133f2a976 100644 --- a/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts +++ b/src/app/bitstream-page/bitstream-authorizations/bitstream-authorizations.component.ts @@ -19,7 +19,7 @@ import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { ResourcePoliciesComponent } from '../../shared/resource-policies/resource-policies.component'; @Component({ - selector: 'ds-collection-authorizations', + selector: 'ds-bitstream-authorizations', templateUrl: './bitstream-authorizations.component.html', imports: [ ResourcePoliciesComponent, From 6076423907e22707a4c31c7c96d1b74ca6b0d81c Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 29 Oct 2024 13:58:50 -0500 Subject: [PATCH 335/822] Fix Klaro translations by forcing Klaro to use a 'zy' language key which DSpace will translate --- .../cookies/browser-klaro.service.spec.ts | 6 +++--- .../shared/cookies/browser-klaro.service.ts | 8 +++---- src/app/shared/cookies/klaro-configuration.ts | 21 +++++++++++++------ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/app/shared/cookies/browser-klaro.service.spec.ts b/src/app/shared/cookies/browser-klaro.service.spec.ts index 953734d38c5..5cdd5275cd3 100644 --- a/src/app/shared/cookies/browser-klaro.service.spec.ts +++ b/src/app/shared/cookies/browser-klaro.service.spec.ts @@ -108,7 +108,7 @@ describe('BrowserKlaroService', () => { mockConfig = { translations: { - zz: { + zy: { purposes: {}, test: { testeritis: testKey, @@ -166,8 +166,8 @@ describe('BrowserKlaroService', () => { it('addAppMessages', () => { service.addAppMessages(); - expect(mockConfig.translations.zz[appName]).toBeDefined(); - expect(mockConfig.translations.zz.purposes[purpose]).toBeDefined(); + expect(mockConfig.translations.zy[appName]).toBeDefined(); + expect(mockConfig.translations.zy.purposes[purpose]).toBeDefined(); }); it('translateConfiguration', () => { diff --git a/src/app/shared/cookies/browser-klaro.service.ts b/src/app/shared/cookies/browser-klaro.service.ts index f673a417363..b7d00c4b464 100644 --- a/src/app/shared/cookies/browser-klaro.service.ts +++ b/src/app/shared/cookies/browser-klaro.service.ts @@ -111,7 +111,7 @@ export class BrowserKlaroService extends KlaroService { initialize() { if (!environment.info.enablePrivacyStatement) { delete this.klaroConfig.privacyPolicy; - this.klaroConfig.translations.zz.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy'; + this.klaroConfig.translations.zy.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy'; } const hideGoogleAnalytics$ = this.configService.findByPropertyName(this.GOOGLE_ANALYTICS_KEY).pipe( @@ -258,12 +258,12 @@ export class BrowserKlaroService extends KlaroService { */ addAppMessages() { this.klaroConfig.services.forEach((app) => { - this.klaroConfig.translations.zz[app.name] = { + this.klaroConfig.translations.zy[app.name] = { title: this.getTitleTranslation(app.name), description: this.getDescriptionTranslation(app.name), }; app.purposes.forEach((purpose) => { - this.klaroConfig.translations.zz.purposes[purpose] = this.getPurposeTranslation(purpose); + this.klaroConfig.translations.zy.purposes[purpose] = this.getPurposeTranslation(purpose); }); }); } @@ -277,7 +277,7 @@ export class BrowserKlaroService extends KlaroService { */ this.translateService.setDefaultLang(environment.defaultLanguage); - this.translate(this.klaroConfig.translations.zz); + this.translate(this.klaroConfig.translations.zy); } /** diff --git a/src/app/shared/cookies/klaro-configuration.ts b/src/app/shared/cookies/klaro-configuration.ts index c2fb7738a0c..85d24ce22cd 100644 --- a/src/app/shared/cookies/klaro-configuration.ts +++ b/src/app/shared/cookies/klaro-configuration.ts @@ -23,7 +23,7 @@ export const GOOGLE_ANALYTICS_KLARO_KEY = 'google-analytics'; /** * Klaro configuration - * For more information see https://kiprotect.com/docs/klaro/annotated-config + * For more information see https://klaro.org/docs/integration/annotated-configuration */ export const klaroConfiguration: any = { storageName: ANONYMOUS_STORAGE_NAME_KLARO, @@ -53,21 +53,30 @@ export const klaroConfiguration: any = { htmlTexts: true, + /* + Force Klaro to use our custom "zy" lang configs defined below. + */ + lang: 'zy', + /* You can overwrite existing translations and add translations for your app descriptions and purposes. See `src/translations/` for a full list of translations that can be overwritten: - https://github.com/KIProtect/klaro/tree/master/src/translations + https://github.com/klaro-org/klaro-js/tree/master/src/translations */ translations: { /* - The `zz` key contains default translations that will be used as fallback values. - This can e.g. be useful for defining a fallback privacy policy URL. - FOR DSPACE: We use 'zz' to map to our own i18n translations for klaro, see + For DSpace we use this custom 'zy' key to map to our own i18n translations for klaro, see translateConfiguration() in browser-klaro.service.ts. All the below i18n keys are specified in your /src/assets/i18n/*.json5 translation pack. + This 'zy' key has no special meaning to Klaro & is not a valid language code. It just + allows DSpace to override Klaro's own translations in favor of DSpace's i18n keys. + NOTE: we do not use 'zz' as that has special meaning to Klaro and is ONLY used as a "fallback" + if no other translations can be found within Klaro. Currently, a bug in Klaro means that + 'zz' is never used as there's no way to exclude translations: + https://github.com/klaro-org/klaro-js/issues/515 */ - zz: { + zy: { acceptAll: 'cookies.consent.accept-all', acceptSelected: 'cookies.consent.accept-selected', close: 'cookies.consent.close', From 4353c57cd045f912f27bf8c3dce2a73497ff7d42 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 29 Oct 2024 13:58:50 -0500 Subject: [PATCH 336/822] Fix Klaro translations by forcing Klaro to use a 'zy' language key which DSpace will translate (cherry picked from commit 6076423907e22707a4c31c7c96d1b74ca6b0d81c) --- .../cookies/browser-klaro.service.spec.ts | 6 +++--- .../shared/cookies/browser-klaro.service.ts | 8 +++---- src/app/shared/cookies/klaro-configuration.ts | 21 +++++++++++++------ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/app/shared/cookies/browser-klaro.service.spec.ts b/src/app/shared/cookies/browser-klaro.service.spec.ts index 7fd72b54b37..3da3a8b7a32 100644 --- a/src/app/shared/cookies/browser-klaro.service.spec.ts +++ b/src/app/shared/cookies/browser-klaro.service.spec.ts @@ -101,7 +101,7 @@ describe('BrowserKlaroService', () => { mockConfig = { translations: { - zz: { + zy: { purposes: {}, test: { testeritis: testKey @@ -159,8 +159,8 @@ describe('BrowserKlaroService', () => { it('addAppMessages', () => { service.addAppMessages(); - expect(mockConfig.translations.zz[appName]).toBeDefined(); - expect(mockConfig.translations.zz.purposes[purpose]).toBeDefined(); + expect(mockConfig.translations.zy[appName]).toBeDefined(); + expect(mockConfig.translations.zy.purposes[purpose]).toBeDefined(); }); it('translateConfiguration', () => { diff --git a/src/app/shared/cookies/browser-klaro.service.ts b/src/app/shared/cookies/browser-klaro.service.ts index 2b09c0bf155..adcb59e1463 100644 --- a/src/app/shared/cookies/browser-klaro.service.ts +++ b/src/app/shared/cookies/browser-klaro.service.ts @@ -91,7 +91,7 @@ export class BrowserKlaroService extends KlaroService { initialize() { if (!environment.info.enablePrivacyStatement) { delete this.klaroConfig.privacyPolicy; - this.klaroConfig.translations.zz.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy'; + this.klaroConfig.translations.zy.consentNotice.description = 'cookies.consent.content-notice.description.no-privacy'; } const hideGoogleAnalytics$ = this.configService.findByPropertyName(this.GOOGLE_ANALYTICS_KEY).pipe( @@ -238,12 +238,12 @@ export class BrowserKlaroService extends KlaroService { */ addAppMessages() { this.klaroConfig.services.forEach((app) => { - this.klaroConfig.translations.zz[app.name] = { + this.klaroConfig.translations.zy[app.name] = { title: this.getTitleTranslation(app.name), description: this.getDescriptionTranslation(app.name) }; app.purposes.forEach((purpose) => { - this.klaroConfig.translations.zz.purposes[purpose] = this.getPurposeTranslation(purpose); + this.klaroConfig.translations.zy.purposes[purpose] = this.getPurposeTranslation(purpose); }); }); } @@ -257,7 +257,7 @@ export class BrowserKlaroService extends KlaroService { */ this.translateService.setDefaultLang(environment.defaultLanguage); - this.translate(this.klaroConfig.translations.zz); + this.translate(this.klaroConfig.translations.zy); } /** diff --git a/src/app/shared/cookies/klaro-configuration.ts b/src/app/shared/cookies/klaro-configuration.ts index f527f7f0969..6ec4855e28e 100644 --- a/src/app/shared/cookies/klaro-configuration.ts +++ b/src/app/shared/cookies/klaro-configuration.ts @@ -17,7 +17,7 @@ export const GOOGLE_ANALYTICS_KLARO_KEY = 'google-analytics'; /** * Klaro configuration - * For more information see https://kiprotect.com/docs/klaro/annotated-config + * For more information see https://klaro.org/docs/integration/annotated-configuration */ export const klaroConfiguration: any = { storageName: ANONYMOUS_STORAGE_NAME_KLARO, @@ -47,21 +47,30 @@ export const klaroConfiguration: any = { htmlTexts: true, + /* + Force Klaro to use our custom "zy" lang configs defined below. + */ + lang: 'zy', + /* You can overwrite existing translations and add translations for your app descriptions and purposes. See `src/translations/` for a full list of translations that can be overwritten: - https://github.com/KIProtect/klaro/tree/master/src/translations + https://github.com/klaro-org/klaro-js/tree/master/src/translations */ translations: { /* - The `zz` key contains default translations that will be used as fallback values. - This can e.g. be useful for defining a fallback privacy policy URL. - FOR DSPACE: We use 'zz' to map to our own i18n translations for klaro, see + For DSpace we use this custom 'zy' key to map to our own i18n translations for klaro, see translateConfiguration() in browser-klaro.service.ts. All the below i18n keys are specified in your /src/assets/i18n/*.json5 translation pack. + This 'zy' key has no special meaning to Klaro & is not a valid language code. It just + allows DSpace to override Klaro's own translations in favor of DSpace's i18n keys. + NOTE: we do not use 'zz' as that has special meaning to Klaro and is ONLY used as a "fallback" + if no other translations can be found within Klaro. Currently, a bug in Klaro means that + 'zz' is never used as there's no way to exclude translations: + https://github.com/klaro-org/klaro-js/issues/515 */ - zz: { + zy: { acceptAll: 'cookies.consent.accept-all', acceptSelected: 'cookies.consent.accept-selected', close: 'cookies.consent.close', From 64628f7e0d92d8bbee3078719eabeea4aa4275a9 Mon Sep 17 00:00:00 2001 From: andreaNeki Date: Fri, 13 Sep 2024 16:34:16 -0300 Subject: [PATCH 337/822] DSpace#2668 - Adding and changing classes in global scss to make cookie settings more accessible --- src/styles/_custom_variables.scss | 1 + src/styles/_global-styles.scss | 34 +++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/styles/_custom_variables.scss b/src/styles/_custom_variables.scss index 7171aea6899..aa67acac1cc 100644 --- a/src/styles/_custom_variables.scss +++ b/src/styles/_custom_variables.scss @@ -137,4 +137,5 @@ --green1: #1FB300; // This variable represents the success color for the Klaro cookie banner --button-text-color-cookie: #333; // This variable represents the text color for buttons in the Klaro cookie banner + --very-dark-cyan: #215E50; // This variable represents the background color of the save cookies button } diff --git a/src/styles/_global-styles.scss b/src/styles/_global-styles.scss index b3120c08cd1..99cc075dbe7 100644 --- a/src/styles/_global-styles.scss +++ b/src/styles/_global-styles.scss @@ -43,17 +43,39 @@ body { .cm-btn.cm-btn-success { color: var(--button-text-color-cookie); background-color: var(--green1); - } - .cm-btn.cm-btn-success.cm-btn-accept-all { - color: var(--button-text-color-cookie); - background-color: var(--green1); + font-weight: 600; } } } -.klaro .cookie-modal a, .klaro .context-notice a, .klaro .cookie-notice a -{ +.klaro .cookie-modal .cm-btn.cm-btn-success.cm-btn-accept-all { + color: var(--button-text-color-cookie); + background-color: var(--green1); + font-weight: 600; +} + +.klaro .cookie-modal a, +.klaro .context-notice a, +.klaro .cookie-notice a { color: var(--green1); + text-decoration: underline !important; +} + +.klaro .cookie-modal .cm-modal .cm-body span, +.klaro + .cookie-modal + .cm-modal + .cm-body + ul.cm-purposes + li.cm-purpose + span.cm-required, +p.purposes, +.klaro .cookie-modal .cm-modal .cm-footer .cm-powered-by a { + color: var(--bs-light) !important; +} + +.klaro .cookie-modal .cm-btn.cm-btn-info { + background-color: var(--very-dark-cyan) !important; } .media-viewer From cdeb0473daa19dae455b35738f648b7119408fd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:30:30 +0000 Subject: [PATCH 338/822] Bump sass from 1.80.4 to 1.80.6 in the sass group Bumps the sass group with 1 update: [sass](https://github.com/sass/dart-sass). Updates `sass` from 1.80.4 to 1.80.6 - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.80.4...1.80.6) --- updated-dependencies: - dependency-name: sass dependency-type: direct:development update-type: version-update:semver-patch dependency-group: sass ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index af64e000e32..0869841d5d0 100644 --- a/package.json +++ b/package.json @@ -194,7 +194,7 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^16.14.0", "rimraf": "^3.0.2", - "sass": "~1.80.4", + "sass": "~1.80.6", "sass-loader": "^12.6.0", "sass-resources-loader": "^2.2.5", "ts-node": "^8.10.2", diff --git a/yarn.lock b/yarn.lock index d3695ed47f6..5c8f24ec62f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9753,15 +9753,16 @@ sass@1.71.1: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" -sass@^1.25.0, sass@~1.80.4: - version "1.80.4" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.80.4.tgz#bc0418fd796cad2f1a1309d8b4d7fe44b7027de0" - integrity sha512-rhMQ2tSF5CsuuspvC94nPM9rToiAFw2h3JTrLlgmNw1MH79v8Cr3DH6KF6o6r+8oofY3iYVPUf66KzC8yuVN1w== +sass@^1.25.0, sass@~1.80.6: + version "1.80.6" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.80.6.tgz#5d0aa55763984effe41e40019c9571ab73e6851f" + integrity sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg== dependencies: - "@parcel/watcher" "^2.4.1" chokidar "^4.0.0" immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" + optionalDependencies: + "@parcel/watcher" "^2.4.1" sax@^1.2.4: version "1.4.1" From 59ab2aa35619c45cfac409a534e36476ab525b21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:34:18 +0000 Subject: [PATCH 339/822] Bump core-js from 3.38.1 to 3.39.0 Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.38.1 to 3.39.0. - [Release notes](https://github.com/zloirock/core-js/releases) - [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/zloirock/core-js/commits/v3.39.0/packages/core-js) --- updated-dependencies: - dependency-name: core-js dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 6f797af901f..5b68e2e3c7d 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "colors": "^1.4.0", "compression": "^1.7.5", "cookie-parser": "1.4.7", - "core-js": "^3.30.1", + "core-js": "^3.39.0", "date-fns": "^2.29.3", "date-fns-tz": "^1.3.7", "deepmerge": "^4.3.1", diff --git a/yarn.lock b/yarn.lock index 0c14aee3690..1b9e35a4651 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4417,10 +4417,10 @@ core-js-compat@^3.31.0, core-js-compat@^3.34.0: dependencies: browserslist "^4.23.3" -core-js@^3.30.1: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e" - integrity sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw== +core-js@^3.39.0: + version "3.39.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.39.0.tgz#57f7647f4d2d030c32a72ea23a0555b2eaa30f83" + integrity sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g== core-util-is@1.0.2: version "1.0.2" From bc50efec5e4387bfbae6f1405717d9d2c5bed0eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:35:42 +0000 Subject: [PATCH 340/822] Bump core-js from 3.38.1 to 3.39.0 Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.38.1 to 3.39.0. - [Release notes](https://github.com/zloirock/core-js/releases) - [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/zloirock/core-js/commits/v3.39.0/packages/core-js) --- updated-dependencies: - dependency-name: core-js dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index b3dbb921159..c4fad1e06ae 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "colors": "^1.4.0", "compression": "^1.7.5", "cookie-parser": "1.4.7", - "core-js": "^3.38.1", + "core-js": "^3.39.0", "date-fns": "^2.30.0", "date-fns-tz": "^1.3.7", "deepmerge": "^4.3.1", diff --git a/yarn.lock b/yarn.lock index e6c67e0e80d..eedca951f50 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4272,10 +4272,10 @@ core-js-compat@^3.25.1: dependencies: browserslist "^4.21.5" -core-js@^3.38.1: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e" - integrity sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw== +core-js@^3.39.0: + version "3.39.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.39.0.tgz#57f7647f4d2d030c32a72ea23a0555b2eaa30f83" + integrity sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g== core-util-is@1.0.2: version "1.0.2" From d50af8afb66a74fa0b6156957fc21ac1e41d76e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 02:34:27 +0000 Subject: [PATCH 341/822] Bump express-static-gzip from 2.1.8 to 2.2.0 Bumps [express-static-gzip](https://github.com/tkoenig89/express-static-gzip) from 2.1.8 to 2.2.0. - [Release notes](https://github.com/tkoenig89/express-static-gzip/releases) - [Commits](https://github.com/tkoenig89/express-static-gzip/compare/v2.1.8...v2.2.0) --- updated-dependencies: - dependency-name: express-static-gzip dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index df31c202044..488fd1a729f 100644 --- a/package.json +++ b/package.json @@ -172,7 +172,7 @@ "eslint-plugin-rxjs": "^5.0.3", "eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-unused-imports": "^3.2.0", - "express-static-gzip": "^2.1.8", + "express-static-gzip": "^2.2.0", "jasmine": "^3.8.0", "jasmine-core": "^3.8.0", "jasmine-marbles": "0.9.2", diff --git a/yarn.lock b/yarn.lock index fc71ba33789..bcc50505998 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5601,11 +5601,12 @@ express-rate-limit@^5.1.3: resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-5.5.1.tgz#110c23f6a65dfa96ab468eda95e71697bc6987a2" integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg== -express-static-gzip@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/express-static-gzip/-/express-static-gzip-2.1.8.tgz#f37f0fe9e8113e56cfac63a98c0197ee6bd6458f" - integrity sha512-g8tiJuI9Y9Ffy59ehVXvqb0hhP83JwZiLxzanobPaMbkB5qBWA8nuVgd+rcd5qzH3GkgogTALlc0BaADYwnMbQ== +express-static-gzip@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/express-static-gzip/-/express-static-gzip-2.2.0.tgz#7c3f7dd89da68e51c591edf02e6de6169c017f5f" + integrity sha512-4ZQ0pHX0CAauxmzry2/8XFLM6aZA4NBvg9QezSlsEO1zLnl7vMFa48/WIcjzdfOiEUS4S1npPPKP2NHHYAp6qg== dependencies: + parseurl "^1.3.3" serve-static "^1.16.2" express@^4.17.3, express@^4.21.1: @@ -8510,7 +8511,7 @@ parse5@^7.0.0, parse5@^7.1.2: dependencies: entities "^4.4.0" -parseurl@~1.3.2, parseurl@~1.3.3: +parseurl@^1.3.3, parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== From 06783364c41f66dc237f606ad294ef67fc87c89f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 03:15:03 +0000 Subject: [PATCH 342/822] Bump express-static-gzip from 2.1.8 to 2.2.0 Bumps [express-static-gzip](https://github.com/tkoenig89/express-static-gzip) from 2.1.8 to 2.2.0. - [Release notes](https://github.com/tkoenig89/express-static-gzip/releases) - [Commits](https://github.com/tkoenig89/express-static-gzip/compare/v2.1.8...v2.2.0) --- updated-dependencies: - dependency-name: express-static-gzip dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f8f725fafc2..7381cdfa97b 100644 --- a/package.json +++ b/package.json @@ -165,7 +165,7 @@ "eslint-plugin-jsonc": "^2.16.0", "eslint-plugin-lodash": "^7.4.0", "eslint-plugin-unused-imports": "^2.0.0", - "express-static-gzip": "^2.1.8", + "express-static-gzip": "^2.2.0", "jasmine-core": "^3.8.0", "jasmine-marbles": "0.9.2", "karma": "^6.4.4", diff --git a/yarn.lock b/yarn.lock index 01064279524..aa4fb3ed3ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5609,11 +5609,12 @@ express-rate-limit@^5.1.3: resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.1.tgz" integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg== -express-static-gzip@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/express-static-gzip/-/express-static-gzip-2.1.8.tgz#f37f0fe9e8113e56cfac63a98c0197ee6bd6458f" - integrity sha512-g8tiJuI9Y9Ffy59ehVXvqb0hhP83JwZiLxzanobPaMbkB5qBWA8nuVgd+rcd5qzH3GkgogTALlc0BaADYwnMbQ== +express-static-gzip@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/express-static-gzip/-/express-static-gzip-2.2.0.tgz#7c3f7dd89da68e51c591edf02e6de6169c017f5f" + integrity sha512-4ZQ0pHX0CAauxmzry2/8XFLM6aZA4NBvg9QezSlsEO1zLnl7vMFa48/WIcjzdfOiEUS4S1npPPKP2NHHYAp6qg== dependencies: + parseurl "^1.3.3" serve-static "^1.16.2" express@^4.17.3, express@^4.18.2, express@^4.21.1: @@ -8988,7 +8989,7 @@ parse5@^7.0.0, parse5@^7.1.1, parse5@^7.1.2: dependencies: entities "^4.4.0" -parseurl@~1.3.2, parseurl@~1.3.3: +parseurl@^1.3.3, parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== From 6b32d04aecc57586318b919fa5fadaeb032772a8 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Fri, 26 Jul 2024 15:32:57 +0200 Subject: [PATCH 343/822] Updated some messages following the lindat v5 and clarin-dspace v7 instance. (cherry picked from commit b10563ea5388e8c398ec8927dc562d6f841473db) --- src/assets/i18n/cs.json5 | 101 +++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 0b4168cca94..3824e9741a5 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -1477,8 +1477,8 @@ // "bitstream.download.page": "Now downloading {{bitstream}}...", "bitstream.download.page": "Nyní se stahuje {{bitstream}}..." , - // "bitstream.download.page.back": "Back", - "bitstream.download.page.back": "Zpět" , + // "bitstream.download.page.back": "Back" , + "bitstream.download.page.back": "Zpět", // "bitstream.edit.authorizations.link": "Edit bitstream's Policies", "bitstream.edit.authorizations.link": "Upravit politiky souboru", @@ -1797,7 +1797,7 @@ // "claimed-declined-task-search-result-list-element.title": "Declined, sent back to Review Manager's workflow", "claimed-declined-task-search-result-list-element.title": "Zamítnuto, posláno zpět správci schvalovacího workflow", - // "collection.create.breadcrumbs": "Create collection", + // "collection.create.breadcrumbs": "Create collection", // TODO New key - Add a translation "collection.create.breadcrumbs": "Create collection", @@ -2210,8 +2210,7 @@ "collection.source.controls.harvest.last": "Naposledy harvestováno:", // "collection.source.controls.harvest.message": "Harvest info:", - "collection.source.controls.harvest.message": "Informace o harevstu:", - + "collection.source.controls.harvest.message": "Informace o harvestu:", // "collection.source.controls.harvest.no-information": "N/A", "collection.source.controls.harvest.no-information": "Není k dispozi", @@ -2703,7 +2702,7 @@ "dso-selector.create.community.head": "Nová komunita", // "dso-selector.create.community.or-divider": "or", - "dso-selector.create.community.or-divider": "or", + "dso-selector.create.community.or-divider": "nebo", // "dso-selector.create.community.sub-level": "Create a new community in", "dso-selector.create.community.sub-level": "Vytvořit novou komunitu v", @@ -2940,7 +2939,7 @@ "error.top-level-communities": "Chyba při načítání komunit nejvyšší úrovně", // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", - "error.validation.license.notgranted": "eslání. Pokud tuto licenci v tuto chvíli nemůžete udělit, můžete svou práci uložit a vrátit se k ní později nebo podání odstranit.", + "error.validation.license.notgranted": "Pro dokončení zaslání musíte udělit licenci. Pokud v tuto chvíli tuto licenci nemůžete udělit, můžete svou práci uložit a později se k svému příspěveku vrátit nebo jej smazat.", // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", "error.validation.pattern": "Toto zadání je omezeno aktuálním vzorcem: {{ pattern }}.", @@ -3252,7 +3251,7 @@ "grant-deny-request-copy.intro2": "Po výběru možnosti se zobrazí návrh e-mailové odpovědi, který můžete upravit.", // "grant-deny-request-copy.processed": "This request has already been processed. You can use the button below to get back to the home page.", - "grant-deny-request-copy.processed": " Tato žádost již byla zpracována. Pomocí níže uvedeného tlačítka se můžete vrátit na domovskou stránku.", + "grant-deny-request-copy.processed": "Tato žádost již byla zpracována. Pomocí níže uvedeného tlačítka se můžete vrátit na domovskou stránku.", // "grant-request-copy.email.subject": "Request copy of document", "grant-request-copy.email.subject": "Žádost o kopii dokumentu", @@ -3432,8 +3431,7 @@ "info.coar-notify-support.breadcrumbs": "COAR Notify Support", // "item.alerts.private": "This item is non-discoverable", - // TODO Source message changed - Revise the translation - "item.alerts.private": "Tento záznam je nezobrazitelný", + "item.alerts.private": "Tento záznam je nevyhledatelný", // "item.alerts.withdrawn": "This item has been withdrawn", "item.alerts.withdrawn": "Tento záznam byl stažen", @@ -4168,7 +4166,7 @@ "item.page.journal-title": "Název časopisu", // "item.page.publisher": "Publisher", - "item.page.publisher": "Vydavatel", + "item.page.publisher": "Nakladatel", // "item.page.titleprefix": "Item: ", "item.page.titleprefix": "Záznam: ", @@ -4268,7 +4266,7 @@ "item.page.abstract": "Abstrakt", // "item.page.author": "Authors", - "item.page.author": "Autor", + "item.page.author": "Autoři", // "item.page.citation": "Citation", "item.page.citation": "Citace", @@ -4310,10 +4308,10 @@ "item.page.journal.search.title": "Články v tomto časopise", // "item.page.link.full": "Full item page", - "item.page.link.full": "Úplný záznam", + "item.page.link.full": "Zobrazit celý záznam", // "item.page.link.simple": "Simple item page", - "item.page.link.simple": "Jednoduchý záznam", + "item.page.link.simple": "Zobrazit minimální záznam", // "item.page.orcid.title": "ORCID", "item.page.orcid.title": "ORCID", @@ -4346,7 +4344,7 @@ "item.page.subject": "Klíčová slova", // "item.page.uri": "URI", - "item.page.uri": "URI", + "item.page.uri": "Identifikátor", // "item.page.bitstreams.view-more": "Show more", "item.page.bitstreams.view-more": "Zobrazit více", @@ -4461,10 +4459,10 @@ "item.preview.oaire.awardNumber": "Identifikátor zdroje financování:", // "item.preview.dc.title.alternative": "Acronym:", - "item.preview.dc.title.alternative": "Akronym:", + "item.preview.dc.title.alternative": "Zkratka:", // "item.preview.dc.coverage.spatial": "Jurisdiction:", - "item.preview.dc.coverage.spatial": "Jurisdikce:", + "item.preview.dc.coverage.spatial": "Příslušnost:", // "item.preview.oaire.fundingStream": "Funding Stream:", "item.preview.oaire.fundingStream": "Tok finančních prostředků:", @@ -4841,7 +4839,7 @@ "journal.page.issn": "ISSN", // "journal.page.publisher": "Publisher", - "journal.page.publisher": "Vydavatel", + "journal.page.publisher": "Nakladatel", // "journal.page.titleprefix": "Journal: ", "journal.page.titleprefix": "Časopis: ", @@ -4936,7 +4934,7 @@ "iiif.page.doi": "Trvalý odkaz: ", // "iiif.page.issue": "Issue: ", - "iiif.page.issue": "Číslo: ", + "iiif.page.issue": "Problém:", // "iiif.page.description": "Description: ", "iiif.page.description": "Popis: ", @@ -5042,8 +5040,7 @@ "menu.header.nav.description": "Admin navigation bar", // "menu.header.admin": "Management", - // TODO Source message changed - Revise the translation - "menu.header.admin": "Management", + "menu.header.admin": "Admin", // "menu.header.image.logo": "Repository logo", "menu.header.image.logo": "Logo úložiště", @@ -5378,7 +5375,7 @@ "mydspace.new-submission-external-short": "Importovat metadata", // "mydspace.results.head": "Your submissions", - "mydspace.results.head": "Váš příspěvek", + "mydspace.results.head": "Vaše zázmany", // "mydspace.results.no-abstract": "No Abstract", "mydspace.results.no-abstract": "Žádný abstrakt", @@ -5390,7 +5387,7 @@ "mydspace.results.no-collections": "Žádné kolekce", // "mydspace.results.no-date": "No Date", - "mydspace.results.no-date": "Žádné datum", + "mydspace.results.no-date": "Žádny datum", // "mydspace.results.no-files": "No Files", "mydspace.results.no-files": "Žádné soubory", @@ -5412,9 +5409,9 @@ // TODO Source message changed - Revise the translation "mydspace.show.workflow": "Úlohy workflow", - // "mydspace.show.workspace": "Your submissions", + // "mydspace.show.workspace": "Your Submissions", // TODO Source message changed - Revise the translation - "mydspace.show.workspace": "Váš příspěvek", + "mydspace.show.workspace": "Vaše záznamy", // "mydspace.show.supervisedWorkspace": "Supervised items", "mydspace.show.supervisedWorkspace": "Zkontrolované záznamy", @@ -5488,7 +5485,7 @@ "nav.user-profile-menu-and-logout": "Menu uživatelského profilu a odhlášení", // "nav.logout": "Log Out", - "nav.logout": "Menu uživatelského profilu a odhlášení", + "nav.logout": "Odhlásit se", // "nav.main.description": "Main navigation bar", "nav.main.description": "Hlavní navigační panel", @@ -6289,7 +6286,7 @@ "publication.page.journal-title": "Název časopisu", // "publication.page.publisher": "Publisher", - "publication.page.publisher": "Vydavatel", + "publication.page.publisher": "Nakladatel", // "publication.page.titleprefix": "Publication: ", "publication.page.titleprefix": "Publikace: ", @@ -6913,7 +6910,7 @@ "search.filters.applied.f.subject": "Předmět", // "search.filters.applied.f.submitter": "Submitter", - "search.filters.applied.f.submitter": "Vkladatel", + "search.filters.applied.f.submitter": "Předkladatel", // "search.filters.applied.f.jobTitle": "Job Title", "search.filters.applied.f.jobTitle": "Název pracovní pozice", @@ -7019,10 +7016,10 @@ "search.filters.filter.creativeWorkKeywords.label": "Předmět hledání", // "search.filters.filter.creativeWorkPublisher.head": "Publisher", - "search.filters.filter.creativeWorkPublisher.head": "Vydavatel", + "search.filters.filter.creativeWorkPublisher.head": "Nakladatel", // "search.filters.filter.creativeWorkPublisher.placeholder": "Publisher", - "search.filters.filter.creativeWorkPublisher.placeholder": "Vydavatel", + "search.filters.filter.creativeWorkPublisher.placeholder": "Nakladatel", // "search.filters.filter.creativeWorkPublisher.label": "Search publisher", "search.filters.filter.creativeWorkPublisher.label": "Hledat vydavatele", @@ -7058,7 +7055,7 @@ "search.filters.filter.discoverable.head": "Nedohledatelné", // "search.filters.filter.withdrawn.head": "Withdrawn", - "search.filters.filter.withdrawn.head": "Zrušeno", + "search.filters.filter.withdrawn.head": "Vyřazeno", // "search.filters.filter.entityType.head": "Item Type", "search.filters.filter.entityType.head": "Typ záznamu", @@ -7142,7 +7139,7 @@ "search.filters.filter.objectpeople.placeholder": "Lidé", // "search.filters.filter.objectpeople.label": "Search people", - "search.filters.filter.objectpeople.label": "Hledat lidi", + "search.filters.filter.objectpeople.label": "Hledat osoby", // "search.filters.filter.organizationAddressCountry.head": "Country", "search.filters.filter.organizationAddressCountry.head": "Stát", @@ -7178,7 +7175,7 @@ "search.filters.filter.scope.placeholder": "Filtr rozsahu", // "search.filters.filter.scope.label": "Search scope filter", - "search.filters.filter.scope.label": "Hledat filtr rozsahu", + "search.filters.filter.scope.label": "Filtr rozsahu hledání", // "search.filters.filter.show-less": "Collapse", "search.filters.filter.show-less": "Sbalit", @@ -7196,13 +7193,13 @@ "search.filters.filter.subject.label": "Hledat předmět", // "search.filters.filter.submitter.head": "Submitter", - "search.filters.filter.submitter.head": "Vkladatel", + "search.filters.filter.submitter.head": "Předkladatel", // "search.filters.filter.submitter.placeholder": "Submitter", - "search.filters.filter.submitter.placeholder": "Vkladatel", + "search.filters.filter.submitter.placeholder": "Předkladatel", // "search.filters.filter.submitter.label": "Search submitter", - "search.filters.filter.submitter.label": "Hledat vkladatele", + "search.filters.filter.submitter.label": "Hledat předkladatele", // "search.filters.filter.show-tree": "Browse {{ name }} tree", "search.filters.filter.show-tree": "Procházet {{ name }} podle", @@ -7286,8 +7283,8 @@ // "search.filters.withdrawn.false": "No", "search.filters.withdrawn.false": "Ne", - // "search.filters.head": "Filters", - "search.filters.head": "Filtry", + // "search.filters.head": "Limit your search", + "search.filters.head": "Zúžit hledání", // "search.filters.reset": "Reset filters", "search.filters.reset": "Resetovat filtry", @@ -7526,7 +7523,7 @@ "submission.general.cannot_submit": "Nemáte oprávnění k vytvoření nového příspěvku.", // "submission.general.deposit": "Deposit", - "submission.general.deposit": "Vložit do repozitáře", + "submission.general.deposit": "Nahrát", // "submission.general.discard.confirm.cancel": "Cancel", "submission.general.discard.confirm.cancel": "Zrušit", @@ -7554,7 +7551,7 @@ "submission.general.info.pending-changes": "Neuložené změny", // "submission.general.save": "Save", - "submission.general.save": "Průběžně uložit záznam", + "submission.general.save": "Uložit", // "submission.general.save-later": "Save for later", "submission.general.save-later": "Uložit na později", @@ -7709,10 +7706,10 @@ "submission.import-external.preview.subtitle": "Níže uvedená metadata byla importována z externího zdroje. Budou předvyplněna při zahájení odesílání..", // "submission.import-external.preview.button.import": "Start submission", - "submission.import-external.preview.button.import": "Zahájit odesílání", + "submission.import-external.preview.button.import": "Začít nový příspěvek", // "submission.import-external.preview.error.import.title": "Submission error", - "submission.import-external.preview.error.import.title": "Chyba při odesílání", + "submission.import-external.preview.error.import.title": "Chyba při vytváření nového příspěvku", // "submission.import-external.preview.error.import.body": "An error occurs during the external source entry import process.", "submission.import-external.preview.error.import.body": "Během procesu importu externí zdrojového záznamu došlo k chybě.", @@ -7893,7 +7890,7 @@ "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Vyhledávací dotaz", // "submission.sections.describe.relationship-lookup.search-tab.search": "Go", - "submission.sections.describe.relationship-lookup.search-tab.search": "Hledání", + "submission.sections.describe.relationship-lookup.search-tab.search": "Přejít na", // "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "Search...", "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "Hledání...", @@ -8080,7 +8077,7 @@ "submission.sections.describe.relationship-lookup.title.Funding Agency": "Financující agentura", // "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", - "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Projekt, ke kterému publikace náleží", + "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Financování", // "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Nadřazená organizační jednotka", @@ -8311,7 +8308,7 @@ "submission.sections.submit.progressbar.describe.recycle": "Opětovně použít", // "submission.sections.submit.progressbar.describe.stepcustom": "Describe", - "submission.sections.submit.progressbar.describe.stepcustom": "Popsat", + "submission.sections.submit.progressbar.describe.stepcustom": "Popis", // "submission.sections.submit.progressbar.describe.stepone": "Describe", "submission.sections.submit.progressbar.describe.stepone": "Základní informace o dokumentu", @@ -8627,8 +8624,8 @@ "submission.submit.breadcrumbs": "Nově podaný záznam", // "submission.submit.title": "New submission", - // TODO Source message changed - Revise the translation - "submission.submit.title": "Nově podaný záznam", + "submission.submit.title": "Nový příspěvek", + // "submission.workflow.generic.delete": "Delete", "submission.workflow.generic.delete": "Smazat", @@ -8710,7 +8707,7 @@ "submission.workflow.tasks.generic.processing": "Zpracování...", // "submission.workflow.tasks.generic.submitter": "Submitter", - "submission.workflow.tasks.generic.submitter": "Zadavatel", + "submission.workflow.tasks.generic.submitter": "Předkladatel", // "submission.workflow.tasks.generic.success": "Operation successful", "submission.workflow.tasks.generic.success": "Operace proběhla úspěšně", @@ -9074,10 +9071,10 @@ "workflow-item.scorereviewaction.notification.error.content": "Nebylo možné zkontrolovat tento záznam", // "workflow-item.scorereviewaction.title": "Rate this item", - "workflow-item.scorereviewaction.title": "Zkontrolovat tento záznam", + "workflow-item.scorereviewaction.title": "Ohodnotit tento záznam", // "workflow-item.scorereviewaction.header": "Rate this item", - "workflow-item.scorereviewaction.header": "Zkontrolovat tento záznam", + "workflow-item.scorereviewaction.header": "Ohodnotit tento záznam", // "workflow-item.scorereviewaction.button.cancel": "Cancel", "workflow-item.scorereviewaction.button.cancel": "Zrušit", @@ -11034,6 +11031,4 @@ // "item.page.cc.license.disclaimer": "Except where otherwised noted, this item's license is described as", // TODO New key - Add a translation "item.page.cc.license.disclaimer": "Except where otherwised noted, this item's license is described as", - - -} \ No newline at end of file +} From e5ea435cbe58186e6dc42d56753147ade7ce3d5a Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Fri, 26 Jul 2024 15:49:37 +0200 Subject: [PATCH 344/822] Fixed linting error. (cherry picked from commit 7e864d27b45c58ef566d31c5d0e2a478a540ecdd) --- src/assets/i18n/cs.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 3824e9741a5..a957232a893 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -1797,7 +1797,7 @@ // "claimed-declined-task-search-result-list-element.title": "Declined, sent back to Review Manager's workflow", "claimed-declined-task-search-result-list-element.title": "Zamítnuto, posláno zpět správci schvalovacího workflow", - // "collection.create.breadcrumbs": "Create collection", + // "collection.create.breadcrumbs": "Create collection", // TODO New key - Add a translation "collection.create.breadcrumbs": "Create collection", From 865268e820fafcfe047a752d9effb9fcfd99c160 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 9 Oct 2024 15:08:31 +0200 Subject: [PATCH 345/822] Updated cs messages following review requirements (cherry picked from commit 813d644b32a28685f8a4205bc383268b2502afdb) --- src/assets/i18n/cs.json5 | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index a957232a893..5e52f751ec5 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -1475,9 +1475,9 @@ "auth.messages.token-refresh-failed": "Nepodařilo se obnovit váš přístupový token. Prosím přihlašte se znovu.", // "bitstream.download.page": "Now downloading {{bitstream}}...", - "bitstream.download.page": "Nyní se stahuje {{bitstream}}..." , + "bitstream.download.page": "Nyní se stahuje {{bitstream}}...", - // "bitstream.download.page.back": "Back" , + // "bitstream.download.page.back": "Back", "bitstream.download.page.back": "Zpět", // "bitstream.edit.authorizations.link": "Edit bitstream's Policies", @@ -2939,7 +2939,7 @@ "error.top-level-communities": "Chyba při načítání komunit nejvyšší úrovně", // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", - "error.validation.license.notgranted": "Pro dokončení zaslání musíte udělit licenci. Pokud v tuto chvíli tuto licenci nemůžete udělit, můžete svou práci uložit a později se k svému příspěveku vrátit nebo jej smazat.", + "error.validation.license.notgranted": "Bez udělení licence nelze záznam dokončit. Pokud v tuto chvíli nemůžete licenci udělit, uložte svou práci a vraťte se k příspěveku později nebo jej smažte.", // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", "error.validation.pattern": "Toto zadání je omezeno aktuálním vzorcem: {{ pattern }}.", @@ -4308,7 +4308,7 @@ "item.page.journal.search.title": "Články v tomto časopise", // "item.page.link.full": "Full item page", - "item.page.link.full": "Zobrazit celý záznam", + "item.page.link.full": "Zobrazit úplný záznam", // "item.page.link.simple": "Simple item page", "item.page.link.simple": "Zobrazit minimální záznam", @@ -4344,7 +4344,7 @@ "item.page.subject": "Klíčová slova", // "item.page.uri": "URI", - "item.page.uri": "Identifikátor", + "item.page.uri": "Permanentní identifikátor", // "item.page.bitstreams.view-more": "Show more", "item.page.bitstreams.view-more": "Zobrazit více", @@ -4934,7 +4934,7 @@ "iiif.page.doi": "Trvalý odkaz: ", // "iiif.page.issue": "Issue: ", - "iiif.page.issue": "Problém:", + "iiif.page.issue": "Číslo:", // "iiif.page.description": "Description: ", "iiif.page.description": "Popis: ", @@ -5375,7 +5375,7 @@ "mydspace.new-submission-external-short": "Importovat metadata", // "mydspace.results.head": "Your submissions", - "mydspace.results.head": "Vaše zázmany", + "mydspace.results.head": "Vaše záznamy", // "mydspace.results.no-abstract": "No Abstract", "mydspace.results.no-abstract": "Žádný abstrakt", @@ -5387,7 +5387,7 @@ "mydspace.results.no-collections": "Žádné kolekce", // "mydspace.results.no-date": "No Date", - "mydspace.results.no-date": "Žádny datum", + "mydspace.results.no-date": "Žádné datum", // "mydspace.results.no-files": "No Files", "mydspace.results.no-files": "Žádné soubory", @@ -6910,7 +6910,7 @@ "search.filters.applied.f.subject": "Předmět", // "search.filters.applied.f.submitter": "Submitter", - "search.filters.applied.f.submitter": "Předkladatel", + "search.filters.applied.f.submitter": "Odesílatel", // "search.filters.applied.f.jobTitle": "Job Title", "search.filters.applied.f.jobTitle": "Název pracovní pozice", @@ -7193,13 +7193,13 @@ "search.filters.filter.subject.label": "Hledat předmět", // "search.filters.filter.submitter.head": "Submitter", - "search.filters.filter.submitter.head": "Předkladatel", + "search.filters.filter.submitter.head": "Odesílatel", // "search.filters.filter.submitter.placeholder": "Submitter", - "search.filters.filter.submitter.placeholder": "Předkladatel", + "search.filters.filter.submitter.placeholder": "Odesílatel", // "search.filters.filter.submitter.label": "Search submitter", - "search.filters.filter.submitter.label": "Hledat předkladatele", + "search.filters.filter.submitter.label": "Hledat odesílatele", // "search.filters.filter.show-tree": "Browse {{ name }} tree", "search.filters.filter.show-tree": "Procházet {{ name }} podle", @@ -8626,7 +8626,6 @@ // "submission.submit.title": "New submission", "submission.submit.title": "Nový příspěvek", - // "submission.workflow.generic.delete": "Delete", "submission.workflow.generic.delete": "Smazat", @@ -8692,7 +8691,7 @@ "submission.workflow.tasks.claimed.reject.submit": "Odmítnout", // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", - "submission.workflow.tasks.claimed.reject_help": "Pokud jste záznam zkontrolovali a zjistili, že není vhodný pro zařazení do kolekce, vyberte \"Odmítnout\". Poté budete vyzváni k zadání zprávy, ve které uvedete, proč je záznam nevhodný, a zda by měl vkladatel něco změnit a znovu předložit.", + "submission.workflow.tasks.claimed.reject_help": "Pokud jste záznam zkontrolovali a zjistili, že není vhodný pro zařazení do kolekce, vyberte \"Odmítnout\". Poté budete vyzváni k zadání zprávy, ve které uvedete, proč je záznam nevhodný, a zda by měl vkladatel něco změnit a znovu odeslat.", // "submission.workflow.tasks.claimed.return": "Return to pool", "submission.workflow.tasks.claimed.return": "Vrátit do fondu", @@ -8707,7 +8706,7 @@ "submission.workflow.tasks.generic.processing": "Zpracování...", // "submission.workflow.tasks.generic.submitter": "Submitter", - "submission.workflow.tasks.generic.submitter": "Předkladatel", + "submission.workflow.tasks.generic.submitter": "Odesílatel", // "submission.workflow.tasks.generic.success": "Operation successful", "submission.workflow.tasks.generic.success": "Operace proběhla úspěšně", From 33bc8ba1a3fe5934c10f648c2a756e65a6c59e27 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 9 Oct 2024 16:09:51 +0200 Subject: [PATCH 346/822] Fixed messages following the PR from the UFAL - https://github.com/dataquest-dev/dspace-angular/pull/669/commits/f18d45ce23ea9c42778885f59e5f7d25e548b2e9 (cherry picked from commit 5e5c627b8b4dbafc5454d91e24797f3ef6ef76aa) --- src/assets/i18n/cs.json5 | 220 +++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 5e52f751ec5..2cb95f10d3b 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -13,7 +13,7 @@ "403.help": "Nemáte povolení k přístupu na tuto stránku. Pro návrat na domovskou stránku můžete použít tlačítko níže.", // "403.link.home-page": "Take me to the home page", - "403.link.home-page": "Přesměrujte mě na domovskou stránku", + "403.link.home-page": "Návrat na domovskou stránku", // "403.forbidden": "Forbidden", "403.forbidden": "Přístup zakázán", @@ -46,7 +46,7 @@ "error-page.description.500": "Služba je nedostupná", // "error-page.description.404": "Page not found", - "error-page.description.404": "Stránka nebyla nenalezena", + "error-page.description.404": "Stránka nebyla nalezena", // "error-page.orcid.generic-error": "An error occurred during login via ORCID. Make sure you have shared your ORCID account email address with DSpace. If the error persists, contact the administrator", "error-page.orcid.generic-error": "Při přihlašování přes ORCID došlo k chybě. Ujistěte se, že jste sdíleli e-mailovou adresu připojenou ke svému účtu ORCID s DSpace. Pokud chyba přetrvává, kontaktujte správce", @@ -67,13 +67,13 @@ "access-status.unknown.listelement.badge": "Status neznámý", // "admin.curation-tasks.breadcrumbs": "System curation tasks", - "admin.curation-tasks.breadcrumbs": "Kurátorská úloha systému", + "admin.curation-tasks.breadcrumbs": "Systémové úlohy správy", // "admin.curation-tasks.title": "System curation tasks", - "admin.curation-tasks.title": "Kurátorská úloha systému", + "admin.curation-tasks.title": "Systémové úlohy správy", // "admin.curation-tasks.header": "System curation tasks", - "admin.curation-tasks.header": "Kurátorská úloha systému", + "admin.curation-tasks.header": "Systémové úlohy správy", // "admin.registries.bitstream-formats.breadcrumbs": "Format registry", "admin.registries.bitstream-formats.breadcrumbs": "Registr formátů", @@ -172,7 +172,7 @@ "admin.registries.bitstream-formats.edit.supportLevel.label": "Úroveň podpory", // "admin.registries.bitstream-formats.head": "Bitstream Format Registry", - "admin.registries.bitstream-formats.head": "Registr formátu souboru", + "admin.registries.bitstream-formats.head": "Registr formátů souboru", // "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", "admin.registries.bitstream-formats.no-items": "Žádné formáty souboru k zobrazení.", @@ -373,7 +373,7 @@ "admin.access-control.bulk-access.breadcrumbs": "Hromadná správa přístupu", // "administrativeBulkAccess.search.results.head": "Search Results", - "administrativeBulkAccess.search.results.head": "Prohledávat výsledky", + "administrativeBulkAccess.search.results.head": "Výsledky vyhledávání", // "admin.access-control.bulk-access": "Bulk Access Management", "admin.access-control.bulk-access": "Hromadná správa přístupu", @@ -403,7 +403,7 @@ "admin.access-control.epeople.actions.reset": "Resetovat heslo", // "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", - "admin.access-control.epeople.actions.stop-impersonating": "Přestat simulovat jiného uživatele", + "admin.access-control.epeople.actions.stop-impersonating": "Přestat vystupovat jako jiný uživatel", // "admin.access-control.epeople.breadcrumbs": "EPeople", "admin.access-control.epeople.breadcrumbs": "Uživatelé", @@ -612,7 +612,7 @@ "admin.access-control.groups.table.edit.buttons.remove": "Odstranit \"{{name}}\"", // "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", - "admin.access-control.groups.no-items": "Nebyly nalezeny žádné skupiny, které by měly toto ve svém názvu nebo toto jako UUID,", + "admin.access-control.groups.no-items": "Nebyla nalezena žádná skupina s tímto v návzvu nebo UUID", // "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", "admin.access-control.groups.notification.deleted.success": "Úspěšně odstraněna skupina \"{{name}}\"", @@ -696,7 +696,7 @@ "admin.access-control.groups.form.members-list.button.see-all": "Procházet vše", // "admin.access-control.groups.form.members-list.headMembers": "Current Members", - "admin.access-control.groups.form.members-list.headMembers": "Aktuální členové", + "admin.access-control.groups.form.members-list.headMembers": "Současní členové", // "admin.access-control.groups.form.members-list.search.button": "Search", "admin.access-control.groups.form.members-list.search.button": "Hledat", @@ -738,13 +738,13 @@ "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Přidat člena jménem \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", - "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "Žádná aktuální aktivní skupina, nejprve zadejte jméno.", + "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "Žádná aktuální aktivní skupina, nejprve zadejte název.", // "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", "admin.access-control.groups.form.members-list.no-members-yet": "Ve skupině zatím nejsou žádní členové, vyhledejte je a přidejte.", // "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", - "admin.access-control.groups.form.members-list.no-items": "V tomto vyhledávání nebyly nalezeni žádní uživatelé", + "admin.access-control.groups.form.members-list.no-items": "V tomto vyhledávání nebyli nalezeni žádní uživatelé", // "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", "admin.access-control.groups.form.subgroups-list.notification.failure": "Neúspěch: Něco se pokazilo: \"{{cause}}\"", @@ -801,7 +801,7 @@ "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "Toto je aktuální skupina, nelze přidat.", // "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", - "admin.access-control.groups.form.subgroups-list.no-items": "Nebyly nalezeny žádné skupiny, které by měly toto ve svém názvu nebo toto UUID", + "admin.access-control.groups.form.subgroups-list.no-items": "Nebyla nalezena žádná skupina s tímto v návzvu nebo UUID", // "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "Ve skupině zatím nejsou žádné podskupiny.", @@ -831,7 +831,7 @@ "admin.notifications.source.breadcrumbs": "Quality Assurance", // "admin.access-control.groups.form.tooltip.editGroupPage": "On this page, you can modify the properties and members of a group. In the top section, you can edit the group name and description, unless this is an admin group for a collection or community, in which case the group name and description are auto-generated and cannot be edited. In the following sections, you can edit group membership. See [the wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group) for more details.", - "admin.access-control.groups.form.tooltip.editGroupPage": "Na této stránce můžete upravit vlastnosti a členy skupiny. V horní části můžete upravit název a popis skupiny, pokud se nejedá o skupinu admin pro kolekci nebo komunitu. V takovém případě jsou název a popis skupiny vygenerovány automaticky a nelze je upravovat. V následujících částech můžete upravovat členství ve skupině. Další podrobnosti naleznete v části [the wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group).", + "admin.access-control.groups.form.tooltip.editGroupPage": "Na této stránce můžete upravit vlastnosti a členy skupiny. V horní části můžete upravit název a popis skupiny, pokud se nejedá o skupinu admin pro kolekci nebo komunitu. V takovém případě jsou název a popis skupiny vygenerovány automaticky a nelze je upravovat. V následujících částech můžete upravovat členství ve skupině. Další podrobnosti naleznete v části [wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group).", // "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "To add or remove an EPerson to/from this group, either click the 'Browse All' button or use the search bar below to search for users (use the dropdown to the left of the search bar to choose whether to search by metadata or by email). Then click the plus icon for each user you wish to add in the list below, or the trash can icon for each user you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages.", "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "Pro přidání nebo odebrání uživatele z této skupiny, buď klikněte na „Prohledávat všechny“ nebo použijte vyhledávací okno pro vyhledání uživatele (použijte roletku na levé straně vyhledávacího okna a vyberte, zda chcete prohledávat pomocí metadat nebo e-mailu). Potom klikněte na tlačítko plus u každého uživatele, kterého chcete přidat, nebo na ikonu odpadkového koše u každého uživatele, kterého chcete odebrat. Seznam níže může obsahovat několik stránek: k přechodu na další stránku použijte ovládací prvky pod seznamem. Až budete hotovi, uložte změny pomocí tlačítka „Uložit“ v horní části.", @@ -1406,7 +1406,7 @@ "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.button.see-all": "Prohledávat vše", // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Current Members", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Aktuální členové", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Současní členové", // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "Search", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "Hledat", @@ -1448,7 +1448,7 @@ "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit.buttons.add": "Přidat uživatele jménem \"{{name}}\"", // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "Žádná aktivní skupina, nejdříve vložte název.", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "Žádná aktuální aktivní skupina, nejprve zadejte název.", // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-members-yet": "No members in group yet, search and add.", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-members-yet": "Žádní členové ve skupině, nejdříve vyhledejte a přidejte.", @@ -1792,7 +1792,7 @@ "claimed-approved-search-result-list-element.title": "Schváleno", // "claimed-declined-search-result-list-element.title": "Rejected, sent back to submitter", - "claimed-declined-search-result-list-element.title": "Zamítnuto, posláno zpět vkladateli", + "claimed-declined-search-result-list-element.title": "Zamítnuto, posláno zpět odesílateli", // "claimed-declined-task-search-result-list-element.title": "Declined, sent back to Review Manager's workflow", "claimed-declined-task-search-result-list-element.title": "Zamítnuto, posláno zpět správci schvalovacího workflow", @@ -1815,7 +1815,7 @@ "collection.create.sub-head": "Vytvořit kolekci pro komunitu {{ parent }}", // "collection.curate.header": "Curate Collection: {{collection}}", - "collection.curate.header": "Kurátorovat kolekci: {{collection}}", + "collection.curate.header": "Spravovat kolekci: {{collection}}", // "collection.delete.cancel": "Cancel", "collection.delete.cancel": "Zrušit", @@ -1923,7 +1923,7 @@ "collection.edit.logo.notifications.add.success": "Nahrání loga kolekce proběhlo úspěšně.", // "collection.edit.logo.notifications.delete.success.title": "Logo deleted", - "collection.edit.logo.notifications.delete.success.title": "Logo odstraněno", + "collection.edit.logo.notifications.delete.success.title": "Logo smazáno", // "collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo", "collection.edit.logo.notifications.delete.success.content": "Úspěšně odstraněno logo kolekce", @@ -1948,10 +1948,10 @@ "collection.edit.tabs.access-control.title": "Úprava kolekce - Řízení přístupu", // "collection.edit.tabs.curate.head": "Curate", - "collection.edit.tabs.curate.head": "Kurátorovat", + "collection.edit.tabs.curate.head": "Spravovat", // "collection.edit.tabs.curate.title": "Collection Edit - Curate", - "collection.edit.tabs.curate.title": "Upravit kolekci - kurátorovat", + "collection.edit.tabs.curate.title": "Upravit kolekci - správa", // "collection.edit.tabs.authorizations.head": "Authorizations", "collection.edit.tabs.authorizations.head": "Oprávnění", @@ -2014,7 +2014,7 @@ "collection.edit.tabs.source.head": "Zdroj obsahu", // "collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "collection.edit.tabs.source.notifications.discarded.content": "Vaše změny byly vyřazeny. Chcete-li své změny obnovit, klikněte na tlačítko Zpět", + "collection.edit.tabs.source.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "collection.edit.tabs.source.notifications.discarded.title": "Changes discarded", // TODO Source message changed - Revise the translation @@ -2024,7 +2024,7 @@ "collection.edit.tabs.source.notifications.invalid.content": "Vaše změny nebyly uloženy. Před uložením se prosím ujistěte, že jsou všechna pole platná.", // "collection.edit.tabs.source.notifications.invalid.title": "Metadata invalid", - "collection.edit.tabs.source.notifications.invalid.title": "Metadata neplatná", + "collection.edit.tabs.source.notifications.invalid.title": "Neplatná metadata", // "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", "collection.edit.tabs.source.notifications.saved.content": "Vaše změny ve zdroji obsahu této kolekce byly uloženy.", @@ -2215,7 +2215,7 @@ "collection.source.controls.harvest.no-information": "Není k dispozi", // "collection.source.update.notifications.error.content": "The provided settings have been tested and didn't work.", - "collection.source.update.notifications.error.content": "Zadané nastavení bylo testováno a nefungovalo.", + "collection.source.update.notifications.error.content": "Zadané nastavení bylo otestováno a nefungovalo.", // "collection.source.update.notifications.error.title": "Server Error", "collection.source.update.notifications.error.title": "Chyba serveru", @@ -2262,7 +2262,7 @@ "community.create.sub-head": "Vytvořit dílčí komunitu pro komunitu {{ parent }}", // "community.curate.header": "Curate Community: {{community}}", - "community.curate.header": "Kurátorství komunity: {{ community }}", + "community.curate.header": "Spravovat komunitu: {{ community }}", // "community.delete.cancel": "Cancel", "community.delete.cancel": "Zrušit", @@ -2295,7 +2295,7 @@ "community.edit.breadcrumbs": "Upravit komunitu", // "community.edit.logo.delete.title": "Delete logo", - "community.edit.logo.delete.title": "Odstranit logo", + "community.edit.logo.delete.title": "Smazat logo", // "community.edit.logo.delete-undo.title": "Undo delete", "community.edit.logo.delete-undo.title": "Zrušit odstranění", @@ -2310,7 +2310,7 @@ "community.edit.logo.notifications.add.success": "Nahrání loga komunity proběhlo úspěšně.", // "community.edit.logo.notifications.delete.success.title": "Logo deleted", - "community.edit.logo.notifications.delete.success.title": "Logo odstraněno", + "community.edit.logo.notifications.delete.success.title": "Logo smazáno", // "community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo", "community.edit.logo.notifications.delete.success.content": "Úspěšně odstraněno logo komunity", @@ -2335,10 +2335,10 @@ "community.edit.return": "Zpět", // "community.edit.tabs.curate.head": "Curate", - "community.edit.tabs.curate.head": "Kurátorovat", + "community.edit.tabs.curate.head": "Spravovat", // "community.edit.tabs.curate.title": "Community Edit - Curate", - "community.edit.tabs.curate.title": "Upravit komunitu - kurátorovat", + "community.edit.tabs.curate.title": "Upravit komunitu - správa", // "community.edit.tabs.access-control.head": "Access Control", "community.edit.tabs.access-control.head": "Řízení přístupu", @@ -2396,13 +2396,13 @@ "comcol-role.edit.collection-admin.name": "Správci", // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", - "comcol-role.edit.community-admin.description": "Správci komunit mohou vytvářet dílčí komunity nebo kolekce a spravovat nebo přidělovat správu těmto dílčím komunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do všech dílčích kolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", + "comcol-role.edit.community-admin.description": "Administrátoři komunit mohou vytvářet dílčí komunity nebo kolekce a spravovat nebo přidělovat správu těmto dílčím komunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do všech dílčích kolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", // "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", "comcol-role.edit.collection-admin.description": "Správci kolekcí rozhodují o tom, kdo může do kolekce vkládat záznamy, upravovat metadata záznamů (po vložení) a přidávat (mapovat) existující záznamy z jiných kolekcí do této kolekce (podléhá autorizaci pro danou kolekci).", // "comcol-role.edit.submitters.name": "Submitters", - "comcol-role.edit.submitters.name": "Vkladatelé", + "comcol-role.edit.submitters.name": "Odesílatelé", // "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", "comcol-role.edit.submitters.description": "Uživatelé a skupiny, které mají oprávnění ke vkládání nových záznamů do této kolekce.", @@ -2460,7 +2460,7 @@ "community.form.errors.title.required": "Zadejte název komunity", // "community.form.rights": "Copyright text (HTML)", - "community.form.rights": "Text autorských práv (HTML)", + "community.form.rights": "Copyright (HTML)", // "community.form.tableofcontents": "News (HTML)", "community.form.tableofcontents": "Novinky (HTML)", @@ -2640,16 +2640,16 @@ "curation.form.submit": "Start", // "curation.form.submit.success.head": "The curation task has been started successfully", - "curation.form.submit.success.head": "Kurátorská úloha byla úspěšně spuštěna", + "curation.form.submit.success.head": "Úloha správy byla úspěšně spuštěna", // "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", "curation.form.submit.success.content": "Budete přesměrováni na příslušnou stránku procesu.", // "curation.form.submit.error.head": "Running the curation task failed", - "curation.form.submit.error.head": "Spuštění kurátorské úlohy se nezdařilo.", + "curation.form.submit.error.head": "Spuštění úlohy správy se nezdařilo.", // "curation.form.submit.error.content": "An error occured when trying to start the curation task.", - "curation.form.submit.error.content": "Při pokusu o spuštění kurátorské úlohy došlo k chybě.", + "curation.form.submit.error.content": "Při pokusu o spuštění úlohy správy došlo k chybě.", // "curation.form.submit.error.invalid-handle": "Couldn't determine the handle for this object", "curation.form.submit.error.invalid-handle": "Nepodařilo se určit handle pro tento objekt", @@ -3044,7 +3044,7 @@ "forgot-email.form.success.head": "E-mail pro obnovení hesla odeslán", // "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", - "forgot-email.form.success.content": "Na adresu {{ email }} byl odeslán e-mail obsahující speciální adresu URL a další pokyny.", + "forgot-email.form.success.content": "Na adresu {{ email }} byl odeslán e-mail obsahující speciální URL a další instrukce.", // "forgot-email.form.error.head": "Error when trying to reset password", // TODO Source message changed - Revise the translation @@ -3242,7 +3242,7 @@ "grant-deny-request-copy.header": "Žádost o kopii dokumentu", // "grant-deny-request-copy.home-page": "Take me to the home page", - "grant-deny-request-copy.home-page": "Přesměrujte mne na domovskou stránku", + "grant-deny-request-copy.home-page": "Návrat na domovskou stránku", // "grant-deny-request-copy.intro1": "If you are one of the authors of the document {{ name }}, then please use one of the options below to respond to the user's request.", "grant-deny-request-copy.intro1": "Pokud jste jedním z autorů dokumentu {{ name }}, použijte prosím jednu z níže uvedených možností, abyste odpověděli na žádost uživatele.", @@ -3278,13 +3278,13 @@ "health-page.info-tab": "Informace", // "health-page.status-tab": "Status", - "health-page.status-tab": "Status", + "health-page.status-tab": "Stav", // "health-page.error.msg": "The health check service is temporarily unavailable", "health-page.error.msg": "Služba kontrolující stav systému je momentálně nedostupná.", // "health-page.property.status": "Status code", - "health-page.property.status": "Kód statusu", + "health-page.property.status": "Stavový kód", // "health-page.section.db.title": "Database", "health-page.section.db.title": "Databáze", @@ -3455,7 +3455,7 @@ "item.badge.private": "Nedohledatelné", // "item.badge.withdrawn": "Withdrawn", - "item.badge.withdrawn": "Zrušeno", + "item.badge.withdrawn": "Vyřazeno", // "item.bitstreams.upload.bundle": "Bundle", "item.bitstreams.upload.bundle": "Svazek", @@ -3543,10 +3543,10 @@ "item.edit.bitstreams.headers.name": "Název", // "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.bitstreams.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Undo'", + "item.edit.bitstreams.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", - "item.edit.bitstreams.notifications.discarded.title": "Změny zahozeny", + "item.edit.bitstreams.notifications.discarded.title": "Zahozené změny", // "item.edit.bitstreams.notifications.move.failed.title": "Error moving bitstreams", "item.edit.bitstreams.notifications.move.failed.title": "Chyba při přesunu souborů", @@ -3558,7 +3558,7 @@ "item.edit.bitstreams.notifications.move.saved.title": "Změny uloženy", // "item.edit.bitstreams.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.bitstreams.notifications.outdated.content": "Záznam, na které právě pracujete, byl změněn jiným uživatelem. Vaše aktuální změny jsou zahozeny, aby se zabránilo konfliktům", + "item.edit.bitstreams.notifications.outdated.content": "Záznam, na kterém právě pracujete, byl změněn jiným uživatelem. Vaše aktuální změny byly zahozeny, aby se zabránilo konfliktům", // "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", "item.edit.bitstreams.notifications.outdated.title": "Změny jsou zastaralé", @@ -3651,13 +3651,13 @@ "item.edit.identifiers.doi.status.MINTED": "Vydáno (nezaregistrováno)", // "item.edit.tabs.status.buttons.register-doi.label": "Register a new or pending DOI", - "item.edit.tabs.status.buttons.register-doi.label": "Registrace nového nebo čekání na nové DOI", + "item.edit.tabs.status.buttons.register-doi.label": "Registrovat nové nebo čekající DOI", // "item.edit.tabs.status.buttons.register-doi.button": "Register DOI...", "item.edit.tabs.status.buttons.register-doi.button": "Zaregistrujte DOI...", // "item.edit.register-doi.header": "Register a new or pending DOI", - "item.edit.register-doi.header": "Zaregistrujte nové DOI nebo čekající k registraci", + "item.edit.register-doi.header": "Registrovat nové nebo čekající DOI", // "item.edit.register-doi.description": "Review any pending identifiers and item metadata below and click Confirm to proceed with DOI registration, or Cancel to back out", "item.edit.register-doi.description": "Níže zkontrolujte všechny identifikátory a metadata ve frontě. Zvolte \"Potvrdit\" pro pokračování v registraci DOI nebo \"Zrušit\" pro přerušení procesu.", @@ -3687,7 +3687,7 @@ "item.edit.item-mapper.cancel": "Zrušit", // "item.edit.item-mapper.description": "This is the item mapper tool that allows administrators to map this item to other collections. You can search for collections and map them, or browse the list of collections the item is currently mapped to.", - "item.edit.item-mapper.description": "Toto je nástroj pro mapování záznamů, který umožňuje správcům mapovat tuto záznam na jiné kolekce. Můžete vyhledávat kolekce a mapovat je nebo procházet seznam kolekcí, ke kterým je záznam aktuálně mapována.", + "item.edit.item-mapper.description": "Toto je nástroj pro mapování záznamů, který umožňuje správcům mapovat tento záznam do jiné kolekce. Můžete vyhledávat kolekce a mapovat je nebo procházet seznam kolekcí, ke kterým je záznam aktuálně mapována.", // "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", "item.edit.item-mapper.head": "Mapování do jiných kolekcí - mapovat záznam do kolekcí", @@ -3768,7 +3768,7 @@ "item.edit.metadata.edit.buttons.unedit": "Zastavit úpravy", // "item.edit.metadata.edit.buttons.virtual": "This is a virtual metadata value, i.e. a value inherited from a related entity. It can’t be modified directly. Add or remove the corresponding relationship in the \"Relationships\" tab", - "item.edit.metadata.edit.buttons.virtual": "Tato hodnota metadat je virtuální, tedy děděná z příbuzné entity. Nemůže být zděděna napřímo. Přidejte či odeberte příslušný vztah na záložce \"Vztahy\".", + "item.edit.metadata.edit.buttons.virtual": "Tato hodnota metadat je virtuální, tedy děděná z provázané entity. Nemůže být změněna napřímo. Přidejte či odeberte příslušný vztah na záložce \"Vztahy\".", // "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", "item.edit.metadata.empty": "Záznam aktuálně neobsahuje žádná metadata. Kliknutím na tlačítko Přidat začněte přidávat hodnotu metadat.", @@ -3796,11 +3796,11 @@ "item.edit.metadata.metadatafield.invalid": "Prosím, vyberte platné metadatové pole", // "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.metadata.notifications.discarded.content": "Vaše změny byly vyřazeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", + "item.edit.metadata.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "item.edit.metadata.notifications.discarded.title": "Changes discarded", // TODO Source message changed - Revise the translation - "item.edit.metadata.notifications.discarded.title": "Změny zahozeny", + "item.edit.metadata.notifications.discarded.title": "Zahozené změny", // "item.edit.metadata.notifications.error.title": "An error occurred", "item.edit.metadata.notifications.error.title": "Došlo k chybě", @@ -3809,17 +3809,17 @@ "item.edit.metadata.notifications.invalid.content": "Vaše změny nebyly uloženy. Před uložením se prosím ujistěte, že jsou všechna pole platná.", // "item.edit.metadata.notifications.invalid.title": "Metadata invalid", - "item.edit.metadata.notifications.invalid.title": "Metadata neplatná", + "item.edit.metadata.notifications.invalid.title": "Neplatná metadata", // "item.edit.metadata.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.metadata.notifications.outdated.content": "Záznam, na které právě pracujete, byl změněna jiným uživatelem. Vaše aktuální změny jsou zahozeny, aby se zabránilo konfliktům", + "item.edit.metadata.notifications.outdated.content": "Záznam, na kterém právě pracujete, byl změněn jiným uživatelem. Vaše aktuální změny byly zahozeny, aby se zabránilo konfliktům", // "item.edit.metadata.notifications.outdated.title": "Changes outdated", // TODO Source message changed - Revise the translation "item.edit.metadata.notifications.outdated.title": "Změny jsou zastaralé", // "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", - "item.edit.metadata.notifications.saved.content": "Vaše změny metadat této záznamu byly uloženy.", + "item.edit.metadata.notifications.saved.content": "Vaše změny metadat tohoto záznamu byly uloženy.", // "item.edit.metadata.notifications.saved.title": "Metadata saved", "item.edit.metadata.notifications.saved.title": "Metadata uložena", @@ -3976,16 +3976,16 @@ "item.edit.relationships.no-relationships": "Žádné vztahy", // "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.relationships.notifications.discarded.content": "Vaše změny byly vyřazeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", + "item.edit.relationships.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "item.edit.relationships.notifications.discarded.title": "Changes discarded", - "item.edit.relationships.notifications.discarded.title": "Změny vyřazeny", + "item.edit.relationships.notifications.discarded.title": "Zahozené změny", // "item.edit.relationships.notifications.failed.title": "Error editing relationships", "item.edit.relationships.notifications.failed.title": "Chyba při úpravě vztahů", // "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.relationships.notifications.outdated.content": "Záznam, na které právě pracujete, byl změněna jiným uživatelem. Vaše aktuální změny jsou vyřazeny, aby se zabránilo konfliktům", + "item.edit.relationships.notifications.outdated.content": "Záznam, na kterém právě pracujete, byl změněn jiným uživatelem. Vaše aktuální změny byly zahozeny, aby se zabránilo konfliktům", // "item.edit.relationships.notifications.outdated.title": "Changes outdated", "item.edit.relationships.notifications.outdated.title": "Změny jsou zastaralé", @@ -4009,25 +4009,25 @@ "item.edit.return": "Zpět", // "item.edit.tabs.bitstreams.head": "Bitstreams", - "item.edit.tabs.bitstreams.head": "Soubor", + "item.edit.tabs.bitstreams.head": "Soubory", // "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", "item.edit.tabs.bitstreams.title": "Úprava záznamu - soubor", // "item.edit.tabs.curate.head": "Curate", - "item.edit.tabs.curate.head": "Kurátorovat", + "item.edit.tabs.curate.head": "Spravovat", // "item.edit.tabs.curate.title": "Item Edit - Curate", - "item.edit.tabs.curate.title": "Úprava záznamu - Kurátorovat", + "item.edit.tabs.curate.title": "Úprava záznamu - spravovat", // "item.edit.curate.title": "Curate Item: {{item}}", - "item.edit.curate.title": "Kurátorovat záznam: {{item}}", + "item.edit.curate.title": "Spravovat záznam: {{item}}", // "item.edit.tabs.access-control.head": "Access Control", - "item.edit.tabs.access-control.head": "Kontrola přístupu", + "item.edit.tabs.access-control.head": "Řízení přístupu", // "item.edit.tabs.access-control.title": "Item Edit - Access Control", - "item.edit.tabs.access-control.title": "Úprava záznamu - Kontrola přístupu", + "item.edit.tabs.access-control.title": "Úprava záznamu - Řízení přístupu", // "item.edit.tabs.metadata.head": "Metadata", "item.edit.tabs.metadata.head": "Metadata", @@ -4275,7 +4275,7 @@ "item.page.collections": "Kolekce", // "item.page.collections.loading": "Loading...", - "item.page.collections.loading": "Načítání...", + "item.page.collections.loading": "Načítá se...", // "item.page.collections.load-more": "Load more", "item.page.collections.load-more": "Načíst další", @@ -4377,7 +4377,7 @@ "item.page.reinstate": "Request reinstatement", // "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history", - "item.page.version.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí právě probíhá zadání nové verze.", + "item.page.version.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí už další rozpracovaná verze existuje.", // "item.page.claim.button": "Claim", "item.page.claim.button": "Prohlásit", @@ -4585,7 +4585,7 @@ "item.version.history.table.action.deleteVersion": "Smazat verzi", // "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history", - "item.version.history.table.action.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí probíhá odesílání.", + "item.version.history.table.action.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí už další rozpracovaná verze existuje.", // "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", "item.version.notice": "Toto není nejnovější verze tohoto záznamu. Nejnovější verzi naleznete zde.", @@ -4698,7 +4698,7 @@ "item.version.create.notification.failure": "Nová verze nebyla vytvořena", // "item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history", - "item.version.create.notification.inProgress": "Nová verze nemůže být vytvořena, protože v historii verzí probíhá odesílání.", + "item.version.create.notification.inProgress": "Nová verze nemůže být vytvořena, protože v historii verzí už další rozpracovaná verze existuje.", // "item.version.delete.modal.header": "Delete version", "item.version.delete.modal.header": "Smazat verzi", @@ -4788,7 +4788,7 @@ "itemtemplate.edit.metadata.metadatafield.invalid": "Prosím zvolte platné metadatové pole", // "itemtemplate.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "itemtemplate.edit.metadata.notifications.discarded.content": "Vaše změny byly zahozeny. Chcete-li obnovit své změny, klikněte na tlačítko 'Zpět'.", + "itemtemplate.edit.metadata.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "itemtemplate.edit.metadata.notifications.discarded.title": "Changes discarded", "itemtemplate.edit.metadata.notifications.discarded.title": "Změny byly zahozeny", @@ -4797,7 +4797,7 @@ "itemtemplate.edit.metadata.notifications.error.title": "Vyskytla se chyba", // "itemtemplate.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", - "itemtemplate.edit.metadata.notifications.invalid.content": "Vaše změny nebyly uloženy. Před uložením se ujistěte, že všechna pole jsou platná.", + "itemtemplate.edit.metadata.notifications.invalid.content": "Vaše změny nebyly uloženy. Před uložením se prosím ujistěte, že jsou všechna pole platná.", // "itemtemplate.edit.metadata.notifications.invalid.title": "Metadata invalid", "itemtemplate.edit.metadata.notifications.invalid.title": "Neplatná metadata", @@ -4812,7 +4812,7 @@ "itemtemplate.edit.metadata.notifications.saved.content": "Vaše změny v šabloně metadat tohoto záznamu byly uloženy.", // "itemtemplate.edit.metadata.notifications.saved.title": "Metadata saved", - "itemtemplate.edit.metadata.notifications.saved.title": "Metadata uloženy", + "itemtemplate.edit.metadata.notifications.saved.title": "Metadata uložena", // "itemtemplate.edit.metadata.reinstate-button": "Undo", "itemtemplate.edit.metadata.reinstate-button": "Vrátit zpět", @@ -5043,7 +5043,7 @@ "menu.header.admin": "Admin", // "menu.header.image.logo": "Repository logo", - "menu.header.image.logo": "Logo úložiště", + "menu.header.image.logo": "Logo repozitáře", // "menu.header.admin.description": "Management menu", "menu.header.admin.description": "Management menu", @@ -5119,7 +5119,7 @@ "menu.section.control_panel": "Ovládací panel", // "menu.section.curation_task": "Curation Task", - "menu.section.curation_task": "Kurátorská úloha", + "menu.section.curation_task": "Úloha správy", // "menu.section.edit": "Edit", "menu.section.edit": "Upravit", @@ -5165,25 +5165,25 @@ "menu.section.icon.control_panel": "Sekce menu Ovládací panel", // "menu.section.icon.curation_tasks": "Curation Task menu section", - "menu.section.icon.curation_tasks": "Sekce menu Kurátorská úloha", + "menu.section.icon.curation_tasks": "Sekce menu úloha správy", // "menu.section.icon.edit": "Edit menu section", "menu.section.icon.edit": "Sekce menu Upravit", // "menu.section.icon.export": "Export menu section", - "menu.section.icon.export": "Exportovat sekci menu", + "menu.section.icon.export": "Sekce menu Exportovat", // "menu.section.icon.find": "Find menu section", - "menu.section.icon.find": "Najít sekci menu", + "menu.section.icon.find": "Sekce menu Najít", // "menu.section.icon.health": "Health check menu section", - "menu.section.icon.health": "Kontrola stavu sekce menu", + "menu.section.icon.health": "Sekce menu Kontrola stavu", // "menu.section.icon.import": "Import menu section", - "menu.section.icon.import": "Importovat sekci menu", + "menu.section.icon.import": "Sekce menu Importovat", // "menu.section.icon.new": "New menu section", - "menu.section.icon.new": "Nová sekce menu", + "menu.section.icon.new": "Sekce menu Nový", // "menu.section.icon.pin": "Pin sidebar", "menu.section.icon.pin": "Připnout postranní panel", @@ -5260,7 +5260,7 @@ "menu.section.health": "Stav systému", // "menu.section.registries": "Registries", - "menu.section.registries": "Rejstřík", + "menu.section.registries": "Registry", // "menu.section.registries_format": "Format", "menu.section.registries_format": "Formát", @@ -5285,7 +5285,7 @@ "menu.section.toggle.control_panel": "Přepnout sekci ovládacího panelu", // "menu.section.toggle.curation_task": "Toggle Curation Task section", - "menu.section.toggle.curation_task": "Přepnout sekci Kurátorská úloha", + "menu.section.toggle.curation_task": "Přepnout sekci úloha správy", // "menu.section.toggle.edit": "Toggle Edit section", "menu.section.toggle.edit": "Přepnout sekci Úpravy", @@ -5303,7 +5303,7 @@ "menu.section.toggle.new": "Přepnout sekci Nová", // "menu.section.toggle.registries": "Toggle Registries section", - "menu.section.toggle.registries": "Přepnout sekci Rejstříky", + "menu.section.toggle.registries": "Přepnout sekci Registry", // "menu.section.toggle.statistics_task": "Toggle Statistics Task section", "menu.section.toggle.statistics_task": "Přepnout sekci Statistická úloha", @@ -5327,7 +5327,7 @@ "mydspace.description": "", // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", - "mydspace.messages.controller-help": "Zvolte tuto možnost, chcete-li odeslat zprávu vkladateli záznamu.", + "mydspace.messages.controller-help": "Zvolte tuto možnost, chcete-li odeslat zprávu odesílateli záznamu.", // "mydspace.messages.description-placeholder": "Insert your message here...", "mydspace.messages.description-placeholder": "Zde vložte svou zprávu...", @@ -5506,7 +5506,7 @@ "nav.statistics.header": "Statistika", // "nav.stop-impersonating": "Stop impersonating EPerson", - "nav.stop-impersonating": "Přestat simulovat jiného uživatele", + "nav.stop-impersonating": "Přestat vystupovat jako jiný uživatel", // "nav.subscriptions": "Subscriptions", "nav.subscriptions": "Nastavení notifikací", @@ -5810,7 +5810,7 @@ "orgunit.page.city": "Město", // "orgunit.page.country": "Country", - "orgunit.page.country": "Stát", + "orgunit.page.country": "Země", // "orgunit.page.dateestablished": "Date established", "orgunit.page.dateestablished": "Datum založení.", @@ -5892,7 +5892,7 @@ "person-relationships.search.results.head": "Výsledky vyhledávání osob", // "person.search.title": "Person Search", - "person.search.title": "Vyledatávání osob", + "person.search.title": "Vyhledávání osob", // "process.new.select-parameters": "Parameters", "process.new.select-parameters": "Parametry", @@ -6121,7 +6121,7 @@ "process.overview.delete.clear": "Zrušit výběr mazání", // "process.overview.delete.processing": "{{count}} process(es) are being deleted. Please wait for the deletion to fully complete. Note that this can take a while.", - "process.overview.delete.processing": "Smazává se {{count}} procesů. Počkejte prosím na úplné dokončení mazání. To může chvíli trvat.", + "process.overview.delete.processing": "Maže se {{count}} procesů. Počkejte prosím na úplné dokončení mazání. To může chvíli trvat.", // "process.overview.delete.body": "Are you sure you want to delete {{count}} process(es)?", "process.overview.delete.body": "Určitě chcete smazat {{count}} procesů", @@ -6512,7 +6512,7 @@ "register-page.registration.header": "Registrace nového uživatele", // "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", - "register-page.registration.info": "Zaregistrujte si účet a přihlaste se k odběru sbírek pro e-mailové aktualizace a odesílejte nové záznamy do systému DSpace", + "register-page.registration.info": "Zaregistrujte si účet a přihlaste se k odběru kolekcí pro e-mailové aktualizace a odesílejte nové záznamy do systému DSpace", // "register-page.registration.email": "Email Address *", "register-page.registration.email": "E-mailová adresa *", @@ -6880,7 +6880,7 @@ "search.filters.applied.f.dateIssued.min": "Datum zahájení", // "search.filters.applied.f.dateSubmitted": "Date submitted", - "search.filters.applied.f.dateSubmitted": "Date vložení", + "search.filters.applied.f.dateSubmitted": "Datum vložení", // "search.filters.applied.f.discoverable": "Non-discoverable", // TODO Source message changed - Revise the translation @@ -6925,7 +6925,7 @@ "search.filters.applied.f.supervisedBy": "Zkontrolováno", // "search.filters.applied.f.withdrawn": "Withdrawn", - "search.filters.applied.f.withdrawn": "Zrušeno", + "search.filters.applied.f.withdrawn": "Vyřazeno", // "search.filters.applied.operator.equals": "", // TODO New key - Add a translation @@ -7142,10 +7142,10 @@ "search.filters.filter.objectpeople.label": "Hledat osoby", // "search.filters.filter.organizationAddressCountry.head": "Country", - "search.filters.filter.organizationAddressCountry.head": "Stát", + "search.filters.filter.organizationAddressCountry.head": "Země", // "search.filters.filter.organizationAddressCountry.placeholder": "Country", - "search.filters.filter.organizationAddressCountry.placeholder": "Stát", + "search.filters.filter.organizationAddressCountry.placeholder": "Země", // "search.filters.filter.organizationAddressCountry.label": "Search country", "search.filters.filter.organizationAddressCountry.label": "Hledat stát", @@ -7438,10 +7438,10 @@ "sorting.dc.date.issued.DESC": "Datum vydání sestupně", // "sorting.dc.date.accessioned.ASC": "Accessioned Date Ascending", - "sorting.dc.date.accessioned.ASC": "Datum přírůstku vzestupně", + "sorting.dc.date.accessioned.ASC": "Datum odeslání vzestupně", // "sorting.dc.date.accessioned.DESC": "Accessioned Date Descending", - "sorting.dc.date.accessioned.DESC": "Datum přírůstku sestupně", + "sorting.dc.date.accessioned.DESC": "Datum odeslání sestupně", // "sorting.lastModified.ASC": "Last modified Ascending", "sorting.lastModified.ASC": "Naposledy upraveno vzestupně", @@ -8284,7 +8284,7 @@ "submission.sections.identifiers.info": "Pro tento záznam budou vytvořeny následující identifikátory:", // "submission.sections.identifiers.no_handle": "No handles have been minted for this item.", - "submission.sections.identifiers.no_handle": "Tomuto záznamu nybyl přidělen žádný handle.", + "submission.sections.identifiers.no_handle": "Tomuto záznamu nebyl přidělen žádný handle.", // "submission.sections.identifiers.no_doi": "No DOIs have been minted for this item.", "submission.sections.identifiers.no_doi": "Tomuto záznamu nebylo přiděleno žádné DOI.", @@ -8446,10 +8446,10 @@ "submission.sections.upload.form.until-placeholder": "Až do", // "submission.sections.upload.header.policy.default.nolist": "Uploaded files in the {{collectionName}} collection will be accessible according to the following group(s):", - "submission.sections.upload.header.policy.default.nolist": "Nahrané soubory v kolekci {{collectionName}} budou přístupné podle následující skupiny (skupin):", + "submission.sections.upload.header.policy.default.nolist": "Nahrané soubory v kolekci {{collectionName}} budou přístupné podle následujících skupin:", // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - "submission.sections.upload.header.policy.default.withlist": "Vezměte prosím na vědomí, že nahrané soubory v kolekci {{collectionName}} budou kromě toho, co je explicitně rozhodnuto pro jednotlivý soubor, přístupné podle následující skupiny (skupin):", + "submission.sections.upload.header.policy.default.withlist": "Vezměte prosím na vědomí, že nahrané soubory v kolekci {{collectionName}} budou kromě toho, co je explicitně rozhodnuto pro jednotlivý soubor, přístupné podle následujících skupin:", // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Zde najdete všechny soubory, které jsou aktuálně v záznamu. Můžete aktualizovat metadata souborů a podmínky přístupu nebo nahrát další soubory pouhým přetažením kdekoli na stránku.", @@ -8618,7 +8618,7 @@ "submission.sections.sherpa.record.information.uri": "URI", // "submission.sections.sherpa.error.message": "There was an error retrieving sherpa informations", - "submission.sections.sherpa.error.message": "Informace ze Sherpa Romeo se nepodařilo načíst.", + "submission.sections.sherpa.error.message": "Při načítání informací ze služby Sherpa došlo k chybě", // "submission.submit.breadcrumbs": "New submission", "submission.submit.breadcrumbs": "Nově podaný záznam", @@ -8676,7 +8676,7 @@ "submission.workflow.tasks.claimed.decline_help": "", // "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", - "submission.workflow.tasks.claimed.reject.reason.info": "Do níže uvedeného pole zadejte důvod odmítnutí podání a uveďte, zda může vkladatel problém odstranit a podání znovu odeslat.", + "submission.workflow.tasks.claimed.reject.reason.info": "Do níže uvedeného pole zadejte důvod odmítnutí podání a uveďte, zda může odesílatel problém odstranit a podání znovu odeslat.", // "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", "submission.workflow.tasks.claimed.reject.reason.placeholder": "Popište důvod odmítnutí", @@ -8691,7 +8691,7 @@ "submission.workflow.tasks.claimed.reject.submit": "Odmítnout", // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", - "submission.workflow.tasks.claimed.reject_help": "Pokud jste záznam zkontrolovali a zjistili, že není vhodný pro zařazení do kolekce, vyberte \"Odmítnout\". Poté budete vyzváni k zadání zprávy, ve které uvedete, proč je záznam nevhodný, a zda by měl vkladatel něco změnit a znovu odeslat.", + "submission.workflow.tasks.claimed.reject_help": "Pokud jste záznam zkontrolovali a zjistili, že není vhodný pro zařazení do kolekce, vyberte \"Odmítnout\". Poté budete vyzváni k zadání zprávy, ve které uvedete, proč je záznam nevhodný, a zda by měl odesílatel něco změnit a znovu odeslat.", // "submission.workflow.tasks.claimed.return": "Return to pool", "submission.workflow.tasks.claimed.return": "Vrátit do fondu", @@ -8712,7 +8712,7 @@ "submission.workflow.tasks.generic.success": "Operace proběhla úspěšně", // "submission.workflow.tasks.pool.claim": "Claim", - "submission.workflow.tasks.pool.claim": "Vyžádat si", + "submission.workflow.tasks.pool.claim": "Převzít", // "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", "submission.workflow.tasks.pool.claim_help": "Přiřaďte si tento úkol.", @@ -8909,7 +8909,7 @@ "uploader.or": ", nebo ", // "uploader.processing": "Processing uploaded file(s)... (it's now safe to close this page)", - "uploader.processing": "(nyní je bezpečné tuto stránku zavřít)", + "uploader.processing": "Zpracovávám nahrané soubory... (nyní je bezpečné tuto stránku zavřít)", // "uploader.queue-length": "Queue length", "uploader.queue-length": "Délka fronty", @@ -8933,7 +8933,7 @@ "workflowAdmin.search.results.head": "Spravovat workflow", // "workflow.search.results.head": "Workflow tasks", - "workflow.search.results.head": "Kroky workflow", + "workflow.search.results.head": "Úlohy workflow", // "supervision.search.results.head": "Workflow and Workspace tasks", "supervision.search.results.head": "Úlohy Workflow a osobního pracovního prostoru", @@ -8973,22 +8973,22 @@ "workflow-item.delete.button.confirm": "Smazat", // "workflow-item.send-back.notification.success.title": "Sent back to submitter", - "workflow-item.send-back.notification.success.title": "Odesláno zpět vkladateli", + "workflow-item.send-back.notification.success.title": "Vráceno zpět odesílateli", // "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", - "workflow-item.send-back.notification.success.content": "Tento záznam ve workflow byl úspěšně odeslán zpět vkladateli", + "workflow-item.send-back.notification.success.content": "Tento záznam ve workflow byl úspěšně vrácen zpět odesílateli", // "workflow-item.send-back.notification.error.title": "Something went wrong", "workflow-item.send-back.notification.error.title": "Něco se pokazilo", // "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", - "workflow-item.send-back.notification.error.content": "Záznam ve workflow se nepodařilo odeslat zpět vkladateli", + "workflow-item.send-back.notification.error.content": "Záznam ve workflow se nepodařilo vrátit zpět odesílateli", // "workflow-item.send-back.title": "Send workflow item back to submitter", - "workflow-item.send-back.title": "Odeslat záznam ve workflow zpět vladateli", + "workflow-item.send-back.title": "Vrátit záznam ve workflow zpět odesílateli", // "workflow-item.send-back.header": "Send workflow item back to submitter", - "workflow-item.send-back.header": "Odeslat záznam ve workflow zpět vladateli", + "workflow-item.send-back.header": "Vrátit záznam ve workflow zpět odesílateli", // "workflow-item.send-back.button.cancel": "Cancel", "workflow-item.send-back.button.cancel": "Zrušit", @@ -9004,7 +9004,7 @@ "workspace-item.view.breadcrumbs": "Zobrazení pracovního prostoru", // "workspace-item.view.title": "Workspace View", - "workspace-item.view.title": "Zobrazení pracovní prostoru", + "workspace-item.view.title": "Zobrazení pracovního prostoru", // "workspace-item.delete.breadcrumbs": "Workspace Delete", "workspace-item.delete.breadcrumbs": "Vymazat obsah pracovního prostoru", @@ -9337,7 +9337,7 @@ "person.page.orcid.sync-queue.send.bad-request-error": "Odeslání do ORCID se nezdařilo, protože zdroj odeslaný do registru ORCID není platný", // "person.page.orcid.sync-queue.send.error": "The submission to ORCID failed", - "person.page.orcid.sync-queue.send.error": "Podání do ORCID se nezdařilo", + "person.page.orcid.sync-queue.send.error": "Odeslání do ORCID se nezdařilo", // "person.page.orcid.sync-queue.send.conflict-error": "The submission to ORCID failed because the resource is already present on the ORCID registry", "person.page.orcid.sync-queue.send.conflict-error": "Odeslání do ORCID se nezdařilo, protože zdroj se již nachází v registru ORCID", @@ -9490,7 +9490,7 @@ "system-wide-alert-form.retrieval.error": "Něco se pokazilo při načítání systémových upozornění", // "system-wide-alert.form.cancel": "Cancel", - "system-wide-alert.form.cancel": "Zrušir", + "system-wide-alert.form.cancel": "Zrušit", // "system-wide-alert.form.save": "Save", "system-wide-alert.form.save": "Uložit", @@ -9508,7 +9508,7 @@ "system-wide-alert.form.label.message": "Obsah upozornění", // "system-wide-alert.form.label.countdownTo.enable": "Enable a countdown timer", - "system-wide-alert.form.label.countdownTo.enable": "Povolit odpočítávací měřič", + "system-wide-alert.form.label.countdownTo.enable": "Povolit odpočet", // "system-wide-alert.form.label.countdownTo.hint": "Hint: Set a countdown timer. When enabled, a date can be set in the future and the system-wide alert banner will perform a countdown to the set date. When this timer ends, it will disappear from the alert. The server will NOT be automatically stopped.", "system-wide-alert.form.label.countdownTo.hint": "Nápověda: Nastavte odpočítávací měřič. Je-li to povoleno, lze datum nastavit i v budoucnosti a systémový upozornění bude uvádět odpočítávání do nastaveného data. Ve chvíli, kdy skončí odpočítávání, zmizí i odpočítávač z upozornění. Server NEBUDE automaticky zastaven.", @@ -9643,7 +9643,7 @@ // "vocabulary-treeview.search.form.add": "Add", // TODO New key - Add a translation - "vocabulary-treeview.search.form.add": "Add", + "vocabulary-treeview.search.form.add": "Přidat", // "admin.notifications.publicationclaim.breadcrumbs": "Publication Claim", // TODO New key - Add a translation From d586a8450d5d0207035d4703b7545d8caf1b5dfa Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 9 Oct 2024 16:14:04 +0200 Subject: [PATCH 347/822] Updated cs localization for subcommunities and subcollections (cherry picked from commit 9badd4a4b6261a2abf5ed838f16bb000b1a127f0) --- src/assets/i18n/cs.json5 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 2cb95f10d3b..09dd023e8d5 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -2259,7 +2259,7 @@ "community.create.notifications.success": "Úspěšně vytvořena komunita", // "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", - "community.create.sub-head": "Vytvořit dílčí komunitu pro komunitu {{ parent }}", + "community.create.sub-head": "Vytvořit podkomunitu v komunitě {{ parent }}", // "community.curate.header": "Curate Community: {{community}}", "community.curate.header": "Spravovat komunitu: {{ community }}", @@ -2396,7 +2396,7 @@ "comcol-role.edit.collection-admin.name": "Správci", // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", - "comcol-role.edit.community-admin.description": "Administrátoři komunit mohou vytvářet dílčí komunity nebo kolekce a spravovat nebo přidělovat správu těmto dílčím komunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do všech dílčích kolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", + "comcol-role.edit.community-admin.description": "Administrátoři komunit mohou vytvářet podkomunity nebo kolekce a spravovat nebo přidělovat správu těmto podkomunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do všech podkolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", // "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", "comcol-role.edit.collection-admin.description": "Správci kolekcí rozhodují o tom, kdo může do kolekce vkládat záznamy, upravovat metadata záznamů (po vložení) a přidávat (mapovat) existující záznamy z jiných kolekcí do této kolekce (podléhá autorizaci pro danou kolekci).", @@ -2421,7 +2421,7 @@ // "comcol-role.edit.bitstream_read.description": "E-People and Groups that can read new bitstreams submitted to this collection. Changes to this role are not retroactive. Existing bitstreams in the system will still be viewable by those who had read access at the time of their addition.", // TODO Source message changed - Revise the translation - "comcol-role.edit.bitstream_read.description": "Správci komunit mohou vytvářet dílčí komunity nebo kolekce a spravovat nebo přidělovat správu těmto dílčím komunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do libovolných dílčích kolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", + "comcol-role.edit.bitstream_read.description": "Správci komunit mohou vytvářet podkomunity nebo kolekce a spravovat nebo přidělovat správu těmto podkomunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do libovolných podkolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", // "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", "comcol-role.edit.bitstream_read.anonymous-group": "Výchozí čtení pro příchozí soubory je v současné době nastaveno na hodnotu Anonymní.", @@ -2481,7 +2481,7 @@ "community.page.news": "Novinky", // "community.all-lists.head": "Subcommunities and Collections", - "community.all-lists.head": "Dílčí komunity a kolekce", + "community.all-lists.head": "Podkomunity a kolekce", // "community.search.results.head": "Search Results", // TODO New key - Add a translation @@ -2927,10 +2927,10 @@ "error.invalid-search-query": "Vyhledávací dotaz není platný. Další informace o této chybě naleznete v osvědčených postupech Solr query syntax.", // "error.sub-collections": "Error fetching sub-collections", - "error.sub-collections": "Chyba při načítání dílčích kolekcí", + "error.sub-collections": "Chyba při načítání podkolekcí", // "error.sub-communities": "Error fetching sub-communities", - "error.sub-communities": "Chyba při načítání dílčích komunit", + "error.sub-communities": "Chyba při načítání podkomunit", // "error.submission.sections.init-form-error": "An error occurred during section initialize, please check your input-form configuration. Details are below :

    ", "error.submission.sections.init-form-error": "Při inicializaci sekce došlo k chybě, zkontrolujte prosím konfiguraci vstupního formuláře. Podrobnosti jsou uvedeny níže :

    ", @@ -4985,10 +4985,10 @@ "loading.search-results": "Načítají se výsledky vyhledávání...", // "loading.sub-collections": "Loading sub-collections...", - "loading.sub-collections": "Načítají se dílčí kolekce...", + "loading.sub-collections": "Načítají se podkolekce...", // "loading.sub-communities": "Loading sub-communities...", - "loading.sub-communities": "Načítají se dílčí komunity...", + "loading.sub-communities": "Načítají se podkomunity...", // "loading.top-level-communities": "Loading top-level communities...", "loading.top-level-communities": "Načítají se komunity nejvyšší úrovně...", From 68b6cc9bd45e01a306990c05b464e94cacb1a4f2 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Fri, 11 Oct 2024 13:37:24 +0200 Subject: [PATCH 348/822] Fixed small cs localization mistakes (cherry picked from commit 680d6c94166266d6195f13b92e3be916917ae8c0) --- src/assets/i18n/cs.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 09dd023e8d5..466e3475bfb 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -2939,7 +2939,7 @@ "error.top-level-communities": "Chyba při načítání komunit nejvyšší úrovně", // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", - "error.validation.license.notgranted": "Bez udělení licence nelze záznam dokončit. Pokud v tuto chvíli nemůžete licenci udělit, uložte svou práci a vraťte se k příspěveku později nebo jej smažte.", + "error.validation.license.notgranted": "Bez udělení licence nelze záznam dokončit. Pokud v tuto chvíli nemůžete licenci udělit, uložte svou práci a vraťte se k příspěvku později nebo jej smažte.", // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", "error.validation.pattern": "Toto zadání je omezeno aktuálním vzorcem: {{ pattern }}.", @@ -4934,7 +4934,7 @@ "iiif.page.doi": "Trvalý odkaz: ", // "iiif.page.issue": "Issue: ", - "iiif.page.issue": "Číslo:", + "iiif.page.issue": "Číslo: ", // "iiif.page.description": "Description: ", "iiif.page.description": "Popis: ", From b11efbbf0cde5cde73f3873a41539bec7588cf9c Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Mon, 4 Nov 2024 14:37:04 +0100 Subject: [PATCH 349/822] Updated messages for the 'supervised' and 'claim' sentenses (cherry picked from commit 1aef6ce1d623ac8f0a52dcf8086847996a2d0180) --- src/assets/i18n/cs.json5 | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 466e3475bfb..f06db668a39 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -4221,10 +4221,10 @@ "workflow-item.search.result.notification.deleted.failure": "Při mazání příkazu supervize \"{{name}}\" došlo k chybě", // "workflow-item.search.result.list.element.supervised-by": "Supervised by:", - "workflow-item.search.result.list.element.supervised-by": "Supervizován:", + "workflow-item.search.result.list.element.supervised-by": "Pod dohledem:", // "workflow-item.search.result.list.element.supervised.remove-tooltip": "Remove supervision group", - "workflow-item.search.result.list.element.supervised.remove-tooltip": "Odebrat skupinu supervize", + "workflow-item.search.result.list.element.supervised.remove-tooltip": "Odebrat skupinu dohledu", // "confidence.indicator.help-text.accepted": "This authority value has been confirmed as accurate by an interactive user", // TODO New key - Add a translation @@ -4380,10 +4380,10 @@ "item.page.version.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí už další rozpracovaná verze existuje.", // "item.page.claim.button": "Claim", - "item.page.claim.button": "Prohlásit", + "item.page.claim.button": "Převzít", // "item.page.claim.tooltip": "Claim this item as profile", - "item.page.claim.tooltip": "Prohlásit tento záznam za profilovou", + "item.page.claim.tooltip": "Prohlásit tento záznam za profil", // "item.page.image.alt.ROR": "ROR logo", // TODO New key - Add a translation @@ -5414,7 +5414,7 @@ "mydspace.show.workspace": "Vaše záznamy", // "mydspace.show.supervisedWorkspace": "Supervised items", - "mydspace.show.supervisedWorkspace": "Zkontrolované záznamy", + "mydspace.show.supervisedWorkspace": "Záznamy pod dohledem", // "mydspace.status.mydspaceArchived": "Archived", "mydspace.status.mydspaceArchived": "Archivováno", @@ -6922,7 +6922,7 @@ "search.filters.applied.f.birthDate.min": "Datum narození od", // "search.filters.applied.f.supervisedBy": "Supervised by", - "search.filters.applied.f.supervisedBy": "Zkontrolováno", + "search.filters.applied.f.supervisedBy": "Pod dohledem", // "search.filters.applied.f.withdrawn": "Withdrawn", "search.filters.applied.f.withdrawn": "Vyřazeno", @@ -7221,8 +7221,7 @@ "search.filters.filter.supervisedBy.placeholder": "Supervised By", // "search.filters.filter.supervisedBy.label": "Search Supervised By", - // TODO New key - Add a translation - "search.filters.filter.supervisedBy.label": "Search Supervised By", + "search.filters.filter.supervisedBy.label": "Hledat pod dohledem", // "search.filters.entityType.JournalIssue": "Journal Issue", "search.filters.entityType.JournalIssue": "Číslo časopisu", @@ -8924,7 +8923,7 @@ "virtual-metadata.delete-relationship.modal-head": "Vyberte záznamy, pro které chcete uložit virtuální metadata jako skutečná metadata", // "supervisedWorkspace.search.results.head": "Supervised Items", - "supervisedWorkspace.search.results.head": "Zkontrolované záznamy", + "supervisedWorkspace.search.results.head": "Záznamy pod dohledem", // "workspace.search.results.head": "Your submissions", "workspace.search.results.head": "Moje záznamy", From bd638f03560015a5bdc31108227810ca1fdba540 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Fri, 8 Nov 2024 15:24:06 +0100 Subject: [PATCH 350/822] Updated supervised by messages following NTK suggestions (cherry picked from commit d819cf43968665c20870ee16a1620e744dfbd821) --- src/assets/i18n/cs.json5 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index f06db668a39..866660f513f 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -4221,10 +4221,10 @@ "workflow-item.search.result.notification.deleted.failure": "Při mazání příkazu supervize \"{{name}}\" došlo k chybě", // "workflow-item.search.result.list.element.supervised-by": "Supervised by:", - "workflow-item.search.result.list.element.supervised-by": "Pod dohledem:", + "workflow-item.search.result.list.element.supervised-by": "Dohlížející autorita:", // "workflow-item.search.result.list.element.supervised.remove-tooltip": "Remove supervision group", - "workflow-item.search.result.list.element.supervised.remove-tooltip": "Odebrat skupinu dohledu", + "workflow-item.search.result.list.element.supervised.remove-tooltip": "Odebrat dohlížející autoritu", // "confidence.indicator.help-text.accepted": "This authority value has been confirmed as accurate by an interactive user", // TODO New key - Add a translation @@ -7221,7 +7221,7 @@ "search.filters.filter.supervisedBy.placeholder": "Supervised By", // "search.filters.filter.supervisedBy.label": "Search Supervised By", - "search.filters.filter.supervisedBy.label": "Hledat pod dohledem", + "search.filters.filter.supervisedBy.label": "Hledat dohlížející autoritu", // "search.filters.entityType.JournalIssue": "Journal Issue", "search.filters.entityType.JournalIssue": "Číslo časopisu", From 757574080caabd944d13d75c47997a2d77637744 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Fri, 26 Jul 2024 15:32:57 +0200 Subject: [PATCH 351/822] Updated some messages following the lindat v5 and clarin-dspace v7 instance. (cherry picked from commit b10563ea5388e8c398ec8927dc562d6f841473db) --- src/assets/i18n/cs.json5 | 101 +++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 0b4168cca94..3824e9741a5 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -1477,8 +1477,8 @@ // "bitstream.download.page": "Now downloading {{bitstream}}...", "bitstream.download.page": "Nyní se stahuje {{bitstream}}..." , - // "bitstream.download.page.back": "Back", - "bitstream.download.page.back": "Zpět" , + // "bitstream.download.page.back": "Back" , + "bitstream.download.page.back": "Zpět", // "bitstream.edit.authorizations.link": "Edit bitstream's Policies", "bitstream.edit.authorizations.link": "Upravit politiky souboru", @@ -1797,7 +1797,7 @@ // "claimed-declined-task-search-result-list-element.title": "Declined, sent back to Review Manager's workflow", "claimed-declined-task-search-result-list-element.title": "Zamítnuto, posláno zpět správci schvalovacího workflow", - // "collection.create.breadcrumbs": "Create collection", + // "collection.create.breadcrumbs": "Create collection", // TODO New key - Add a translation "collection.create.breadcrumbs": "Create collection", @@ -2210,8 +2210,7 @@ "collection.source.controls.harvest.last": "Naposledy harvestováno:", // "collection.source.controls.harvest.message": "Harvest info:", - "collection.source.controls.harvest.message": "Informace o harevstu:", - + "collection.source.controls.harvest.message": "Informace o harvestu:", // "collection.source.controls.harvest.no-information": "N/A", "collection.source.controls.harvest.no-information": "Není k dispozi", @@ -2703,7 +2702,7 @@ "dso-selector.create.community.head": "Nová komunita", // "dso-selector.create.community.or-divider": "or", - "dso-selector.create.community.or-divider": "or", + "dso-selector.create.community.or-divider": "nebo", // "dso-selector.create.community.sub-level": "Create a new community in", "dso-selector.create.community.sub-level": "Vytvořit novou komunitu v", @@ -2940,7 +2939,7 @@ "error.top-level-communities": "Chyba při načítání komunit nejvyšší úrovně", // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", - "error.validation.license.notgranted": "eslání. Pokud tuto licenci v tuto chvíli nemůžete udělit, můžete svou práci uložit a vrátit se k ní později nebo podání odstranit.", + "error.validation.license.notgranted": "Pro dokončení zaslání musíte udělit licenci. Pokud v tuto chvíli tuto licenci nemůžete udělit, můžete svou práci uložit a později se k svému příspěveku vrátit nebo jej smazat.", // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", "error.validation.pattern": "Toto zadání je omezeno aktuálním vzorcem: {{ pattern }}.", @@ -3252,7 +3251,7 @@ "grant-deny-request-copy.intro2": "Po výběru možnosti se zobrazí návrh e-mailové odpovědi, který můžete upravit.", // "grant-deny-request-copy.processed": "This request has already been processed. You can use the button below to get back to the home page.", - "grant-deny-request-copy.processed": " Tato žádost již byla zpracována. Pomocí níže uvedeného tlačítka se můžete vrátit na domovskou stránku.", + "grant-deny-request-copy.processed": "Tato žádost již byla zpracována. Pomocí níže uvedeného tlačítka se můžete vrátit na domovskou stránku.", // "grant-request-copy.email.subject": "Request copy of document", "grant-request-copy.email.subject": "Žádost o kopii dokumentu", @@ -3432,8 +3431,7 @@ "info.coar-notify-support.breadcrumbs": "COAR Notify Support", // "item.alerts.private": "This item is non-discoverable", - // TODO Source message changed - Revise the translation - "item.alerts.private": "Tento záznam je nezobrazitelný", + "item.alerts.private": "Tento záznam je nevyhledatelný", // "item.alerts.withdrawn": "This item has been withdrawn", "item.alerts.withdrawn": "Tento záznam byl stažen", @@ -4168,7 +4166,7 @@ "item.page.journal-title": "Název časopisu", // "item.page.publisher": "Publisher", - "item.page.publisher": "Vydavatel", + "item.page.publisher": "Nakladatel", // "item.page.titleprefix": "Item: ", "item.page.titleprefix": "Záznam: ", @@ -4268,7 +4266,7 @@ "item.page.abstract": "Abstrakt", // "item.page.author": "Authors", - "item.page.author": "Autor", + "item.page.author": "Autoři", // "item.page.citation": "Citation", "item.page.citation": "Citace", @@ -4310,10 +4308,10 @@ "item.page.journal.search.title": "Články v tomto časopise", // "item.page.link.full": "Full item page", - "item.page.link.full": "Úplný záznam", + "item.page.link.full": "Zobrazit celý záznam", // "item.page.link.simple": "Simple item page", - "item.page.link.simple": "Jednoduchý záznam", + "item.page.link.simple": "Zobrazit minimální záznam", // "item.page.orcid.title": "ORCID", "item.page.orcid.title": "ORCID", @@ -4346,7 +4344,7 @@ "item.page.subject": "Klíčová slova", // "item.page.uri": "URI", - "item.page.uri": "URI", + "item.page.uri": "Identifikátor", // "item.page.bitstreams.view-more": "Show more", "item.page.bitstreams.view-more": "Zobrazit více", @@ -4461,10 +4459,10 @@ "item.preview.oaire.awardNumber": "Identifikátor zdroje financování:", // "item.preview.dc.title.alternative": "Acronym:", - "item.preview.dc.title.alternative": "Akronym:", + "item.preview.dc.title.alternative": "Zkratka:", // "item.preview.dc.coverage.spatial": "Jurisdiction:", - "item.preview.dc.coverage.spatial": "Jurisdikce:", + "item.preview.dc.coverage.spatial": "Příslušnost:", // "item.preview.oaire.fundingStream": "Funding Stream:", "item.preview.oaire.fundingStream": "Tok finančních prostředků:", @@ -4841,7 +4839,7 @@ "journal.page.issn": "ISSN", // "journal.page.publisher": "Publisher", - "journal.page.publisher": "Vydavatel", + "journal.page.publisher": "Nakladatel", // "journal.page.titleprefix": "Journal: ", "journal.page.titleprefix": "Časopis: ", @@ -4936,7 +4934,7 @@ "iiif.page.doi": "Trvalý odkaz: ", // "iiif.page.issue": "Issue: ", - "iiif.page.issue": "Číslo: ", + "iiif.page.issue": "Problém:", // "iiif.page.description": "Description: ", "iiif.page.description": "Popis: ", @@ -5042,8 +5040,7 @@ "menu.header.nav.description": "Admin navigation bar", // "menu.header.admin": "Management", - // TODO Source message changed - Revise the translation - "menu.header.admin": "Management", + "menu.header.admin": "Admin", // "menu.header.image.logo": "Repository logo", "menu.header.image.logo": "Logo úložiště", @@ -5378,7 +5375,7 @@ "mydspace.new-submission-external-short": "Importovat metadata", // "mydspace.results.head": "Your submissions", - "mydspace.results.head": "Váš příspěvek", + "mydspace.results.head": "Vaše zázmany", // "mydspace.results.no-abstract": "No Abstract", "mydspace.results.no-abstract": "Žádný abstrakt", @@ -5390,7 +5387,7 @@ "mydspace.results.no-collections": "Žádné kolekce", // "mydspace.results.no-date": "No Date", - "mydspace.results.no-date": "Žádné datum", + "mydspace.results.no-date": "Žádny datum", // "mydspace.results.no-files": "No Files", "mydspace.results.no-files": "Žádné soubory", @@ -5412,9 +5409,9 @@ // TODO Source message changed - Revise the translation "mydspace.show.workflow": "Úlohy workflow", - // "mydspace.show.workspace": "Your submissions", + // "mydspace.show.workspace": "Your Submissions", // TODO Source message changed - Revise the translation - "mydspace.show.workspace": "Váš příspěvek", + "mydspace.show.workspace": "Vaše záznamy", // "mydspace.show.supervisedWorkspace": "Supervised items", "mydspace.show.supervisedWorkspace": "Zkontrolované záznamy", @@ -5488,7 +5485,7 @@ "nav.user-profile-menu-and-logout": "Menu uživatelského profilu a odhlášení", // "nav.logout": "Log Out", - "nav.logout": "Menu uživatelského profilu a odhlášení", + "nav.logout": "Odhlásit se", // "nav.main.description": "Main navigation bar", "nav.main.description": "Hlavní navigační panel", @@ -6289,7 +6286,7 @@ "publication.page.journal-title": "Název časopisu", // "publication.page.publisher": "Publisher", - "publication.page.publisher": "Vydavatel", + "publication.page.publisher": "Nakladatel", // "publication.page.titleprefix": "Publication: ", "publication.page.titleprefix": "Publikace: ", @@ -6913,7 +6910,7 @@ "search.filters.applied.f.subject": "Předmět", // "search.filters.applied.f.submitter": "Submitter", - "search.filters.applied.f.submitter": "Vkladatel", + "search.filters.applied.f.submitter": "Předkladatel", // "search.filters.applied.f.jobTitle": "Job Title", "search.filters.applied.f.jobTitle": "Název pracovní pozice", @@ -7019,10 +7016,10 @@ "search.filters.filter.creativeWorkKeywords.label": "Předmět hledání", // "search.filters.filter.creativeWorkPublisher.head": "Publisher", - "search.filters.filter.creativeWorkPublisher.head": "Vydavatel", + "search.filters.filter.creativeWorkPublisher.head": "Nakladatel", // "search.filters.filter.creativeWorkPublisher.placeholder": "Publisher", - "search.filters.filter.creativeWorkPublisher.placeholder": "Vydavatel", + "search.filters.filter.creativeWorkPublisher.placeholder": "Nakladatel", // "search.filters.filter.creativeWorkPublisher.label": "Search publisher", "search.filters.filter.creativeWorkPublisher.label": "Hledat vydavatele", @@ -7058,7 +7055,7 @@ "search.filters.filter.discoverable.head": "Nedohledatelné", // "search.filters.filter.withdrawn.head": "Withdrawn", - "search.filters.filter.withdrawn.head": "Zrušeno", + "search.filters.filter.withdrawn.head": "Vyřazeno", // "search.filters.filter.entityType.head": "Item Type", "search.filters.filter.entityType.head": "Typ záznamu", @@ -7142,7 +7139,7 @@ "search.filters.filter.objectpeople.placeholder": "Lidé", // "search.filters.filter.objectpeople.label": "Search people", - "search.filters.filter.objectpeople.label": "Hledat lidi", + "search.filters.filter.objectpeople.label": "Hledat osoby", // "search.filters.filter.organizationAddressCountry.head": "Country", "search.filters.filter.organizationAddressCountry.head": "Stát", @@ -7178,7 +7175,7 @@ "search.filters.filter.scope.placeholder": "Filtr rozsahu", // "search.filters.filter.scope.label": "Search scope filter", - "search.filters.filter.scope.label": "Hledat filtr rozsahu", + "search.filters.filter.scope.label": "Filtr rozsahu hledání", // "search.filters.filter.show-less": "Collapse", "search.filters.filter.show-less": "Sbalit", @@ -7196,13 +7193,13 @@ "search.filters.filter.subject.label": "Hledat předmět", // "search.filters.filter.submitter.head": "Submitter", - "search.filters.filter.submitter.head": "Vkladatel", + "search.filters.filter.submitter.head": "Předkladatel", // "search.filters.filter.submitter.placeholder": "Submitter", - "search.filters.filter.submitter.placeholder": "Vkladatel", + "search.filters.filter.submitter.placeholder": "Předkladatel", // "search.filters.filter.submitter.label": "Search submitter", - "search.filters.filter.submitter.label": "Hledat vkladatele", + "search.filters.filter.submitter.label": "Hledat předkladatele", // "search.filters.filter.show-tree": "Browse {{ name }} tree", "search.filters.filter.show-tree": "Procházet {{ name }} podle", @@ -7286,8 +7283,8 @@ // "search.filters.withdrawn.false": "No", "search.filters.withdrawn.false": "Ne", - // "search.filters.head": "Filters", - "search.filters.head": "Filtry", + // "search.filters.head": "Limit your search", + "search.filters.head": "Zúžit hledání", // "search.filters.reset": "Reset filters", "search.filters.reset": "Resetovat filtry", @@ -7526,7 +7523,7 @@ "submission.general.cannot_submit": "Nemáte oprávnění k vytvoření nového příspěvku.", // "submission.general.deposit": "Deposit", - "submission.general.deposit": "Vložit do repozitáře", + "submission.general.deposit": "Nahrát", // "submission.general.discard.confirm.cancel": "Cancel", "submission.general.discard.confirm.cancel": "Zrušit", @@ -7554,7 +7551,7 @@ "submission.general.info.pending-changes": "Neuložené změny", // "submission.general.save": "Save", - "submission.general.save": "Průběžně uložit záznam", + "submission.general.save": "Uložit", // "submission.general.save-later": "Save for later", "submission.general.save-later": "Uložit na později", @@ -7709,10 +7706,10 @@ "submission.import-external.preview.subtitle": "Níže uvedená metadata byla importována z externího zdroje. Budou předvyplněna při zahájení odesílání..", // "submission.import-external.preview.button.import": "Start submission", - "submission.import-external.preview.button.import": "Zahájit odesílání", + "submission.import-external.preview.button.import": "Začít nový příspěvek", // "submission.import-external.preview.error.import.title": "Submission error", - "submission.import-external.preview.error.import.title": "Chyba při odesílání", + "submission.import-external.preview.error.import.title": "Chyba při vytváření nového příspěvku", // "submission.import-external.preview.error.import.body": "An error occurs during the external source entry import process.", "submission.import-external.preview.error.import.body": "Během procesu importu externí zdrojového záznamu došlo k chybě.", @@ -7893,7 +7890,7 @@ "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Vyhledávací dotaz", // "submission.sections.describe.relationship-lookup.search-tab.search": "Go", - "submission.sections.describe.relationship-lookup.search-tab.search": "Hledání", + "submission.sections.describe.relationship-lookup.search-tab.search": "Přejít na", // "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "Search...", "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "Hledání...", @@ -8080,7 +8077,7 @@ "submission.sections.describe.relationship-lookup.title.Funding Agency": "Financující agentura", // "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", - "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Projekt, ke kterému publikace náleží", + "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Financování", // "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Nadřazená organizační jednotka", @@ -8311,7 +8308,7 @@ "submission.sections.submit.progressbar.describe.recycle": "Opětovně použít", // "submission.sections.submit.progressbar.describe.stepcustom": "Describe", - "submission.sections.submit.progressbar.describe.stepcustom": "Popsat", + "submission.sections.submit.progressbar.describe.stepcustom": "Popis", // "submission.sections.submit.progressbar.describe.stepone": "Describe", "submission.sections.submit.progressbar.describe.stepone": "Základní informace o dokumentu", @@ -8627,8 +8624,8 @@ "submission.submit.breadcrumbs": "Nově podaný záznam", // "submission.submit.title": "New submission", - // TODO Source message changed - Revise the translation - "submission.submit.title": "Nově podaný záznam", + "submission.submit.title": "Nový příspěvek", + // "submission.workflow.generic.delete": "Delete", "submission.workflow.generic.delete": "Smazat", @@ -8710,7 +8707,7 @@ "submission.workflow.tasks.generic.processing": "Zpracování...", // "submission.workflow.tasks.generic.submitter": "Submitter", - "submission.workflow.tasks.generic.submitter": "Zadavatel", + "submission.workflow.tasks.generic.submitter": "Předkladatel", // "submission.workflow.tasks.generic.success": "Operation successful", "submission.workflow.tasks.generic.success": "Operace proběhla úspěšně", @@ -9074,10 +9071,10 @@ "workflow-item.scorereviewaction.notification.error.content": "Nebylo možné zkontrolovat tento záznam", // "workflow-item.scorereviewaction.title": "Rate this item", - "workflow-item.scorereviewaction.title": "Zkontrolovat tento záznam", + "workflow-item.scorereviewaction.title": "Ohodnotit tento záznam", // "workflow-item.scorereviewaction.header": "Rate this item", - "workflow-item.scorereviewaction.header": "Zkontrolovat tento záznam", + "workflow-item.scorereviewaction.header": "Ohodnotit tento záznam", // "workflow-item.scorereviewaction.button.cancel": "Cancel", "workflow-item.scorereviewaction.button.cancel": "Zrušit", @@ -11034,6 +11031,4 @@ // "item.page.cc.license.disclaimer": "Except where otherwised noted, this item's license is described as", // TODO New key - Add a translation "item.page.cc.license.disclaimer": "Except where otherwised noted, this item's license is described as", - - -} \ No newline at end of file +} From c357ac93f3a4de0ee9a3721bbe73bea81686cb98 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Fri, 26 Jul 2024 15:49:37 +0200 Subject: [PATCH 352/822] Fixed linting error. (cherry picked from commit 7e864d27b45c58ef566d31c5d0e2a478a540ecdd) --- src/assets/i18n/cs.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 3824e9741a5..a957232a893 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -1797,7 +1797,7 @@ // "claimed-declined-task-search-result-list-element.title": "Declined, sent back to Review Manager's workflow", "claimed-declined-task-search-result-list-element.title": "Zamítnuto, posláno zpět správci schvalovacího workflow", - // "collection.create.breadcrumbs": "Create collection", + // "collection.create.breadcrumbs": "Create collection", // TODO New key - Add a translation "collection.create.breadcrumbs": "Create collection", From ca8981611a9559c80024dbf38a234ad2dfebb7c6 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 9 Oct 2024 15:08:31 +0200 Subject: [PATCH 353/822] Updated cs messages following review requirements (cherry picked from commit 813d644b32a28685f8a4205bc383268b2502afdb) --- src/assets/i18n/cs.json5 | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index a957232a893..5e52f751ec5 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -1475,9 +1475,9 @@ "auth.messages.token-refresh-failed": "Nepodařilo se obnovit váš přístupový token. Prosím přihlašte se znovu.", // "bitstream.download.page": "Now downloading {{bitstream}}...", - "bitstream.download.page": "Nyní se stahuje {{bitstream}}..." , + "bitstream.download.page": "Nyní se stahuje {{bitstream}}...", - // "bitstream.download.page.back": "Back" , + // "bitstream.download.page.back": "Back", "bitstream.download.page.back": "Zpět", // "bitstream.edit.authorizations.link": "Edit bitstream's Policies", @@ -2939,7 +2939,7 @@ "error.top-level-communities": "Chyba při načítání komunit nejvyšší úrovně", // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", - "error.validation.license.notgranted": "Pro dokončení zaslání musíte udělit licenci. Pokud v tuto chvíli tuto licenci nemůžete udělit, můžete svou práci uložit a později se k svému příspěveku vrátit nebo jej smazat.", + "error.validation.license.notgranted": "Bez udělení licence nelze záznam dokončit. Pokud v tuto chvíli nemůžete licenci udělit, uložte svou práci a vraťte se k příspěveku později nebo jej smažte.", // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", "error.validation.pattern": "Toto zadání je omezeno aktuálním vzorcem: {{ pattern }}.", @@ -4308,7 +4308,7 @@ "item.page.journal.search.title": "Články v tomto časopise", // "item.page.link.full": "Full item page", - "item.page.link.full": "Zobrazit celý záznam", + "item.page.link.full": "Zobrazit úplný záznam", // "item.page.link.simple": "Simple item page", "item.page.link.simple": "Zobrazit minimální záznam", @@ -4344,7 +4344,7 @@ "item.page.subject": "Klíčová slova", // "item.page.uri": "URI", - "item.page.uri": "Identifikátor", + "item.page.uri": "Permanentní identifikátor", // "item.page.bitstreams.view-more": "Show more", "item.page.bitstreams.view-more": "Zobrazit více", @@ -4934,7 +4934,7 @@ "iiif.page.doi": "Trvalý odkaz: ", // "iiif.page.issue": "Issue: ", - "iiif.page.issue": "Problém:", + "iiif.page.issue": "Číslo:", // "iiif.page.description": "Description: ", "iiif.page.description": "Popis: ", @@ -5375,7 +5375,7 @@ "mydspace.new-submission-external-short": "Importovat metadata", // "mydspace.results.head": "Your submissions", - "mydspace.results.head": "Vaše zázmany", + "mydspace.results.head": "Vaše záznamy", // "mydspace.results.no-abstract": "No Abstract", "mydspace.results.no-abstract": "Žádný abstrakt", @@ -5387,7 +5387,7 @@ "mydspace.results.no-collections": "Žádné kolekce", // "mydspace.results.no-date": "No Date", - "mydspace.results.no-date": "Žádny datum", + "mydspace.results.no-date": "Žádné datum", // "mydspace.results.no-files": "No Files", "mydspace.results.no-files": "Žádné soubory", @@ -6910,7 +6910,7 @@ "search.filters.applied.f.subject": "Předmět", // "search.filters.applied.f.submitter": "Submitter", - "search.filters.applied.f.submitter": "Předkladatel", + "search.filters.applied.f.submitter": "Odesílatel", // "search.filters.applied.f.jobTitle": "Job Title", "search.filters.applied.f.jobTitle": "Název pracovní pozice", @@ -7193,13 +7193,13 @@ "search.filters.filter.subject.label": "Hledat předmět", // "search.filters.filter.submitter.head": "Submitter", - "search.filters.filter.submitter.head": "Předkladatel", + "search.filters.filter.submitter.head": "Odesílatel", // "search.filters.filter.submitter.placeholder": "Submitter", - "search.filters.filter.submitter.placeholder": "Předkladatel", + "search.filters.filter.submitter.placeholder": "Odesílatel", // "search.filters.filter.submitter.label": "Search submitter", - "search.filters.filter.submitter.label": "Hledat předkladatele", + "search.filters.filter.submitter.label": "Hledat odesílatele", // "search.filters.filter.show-tree": "Browse {{ name }} tree", "search.filters.filter.show-tree": "Procházet {{ name }} podle", @@ -8626,7 +8626,6 @@ // "submission.submit.title": "New submission", "submission.submit.title": "Nový příspěvek", - // "submission.workflow.generic.delete": "Delete", "submission.workflow.generic.delete": "Smazat", @@ -8692,7 +8691,7 @@ "submission.workflow.tasks.claimed.reject.submit": "Odmítnout", // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", - "submission.workflow.tasks.claimed.reject_help": "Pokud jste záznam zkontrolovali a zjistili, že není vhodný pro zařazení do kolekce, vyberte \"Odmítnout\". Poté budete vyzváni k zadání zprávy, ve které uvedete, proč je záznam nevhodný, a zda by měl vkladatel něco změnit a znovu předložit.", + "submission.workflow.tasks.claimed.reject_help": "Pokud jste záznam zkontrolovali a zjistili, že není vhodný pro zařazení do kolekce, vyberte \"Odmítnout\". Poté budete vyzváni k zadání zprávy, ve které uvedete, proč je záznam nevhodný, a zda by měl vkladatel něco změnit a znovu odeslat.", // "submission.workflow.tasks.claimed.return": "Return to pool", "submission.workflow.tasks.claimed.return": "Vrátit do fondu", @@ -8707,7 +8706,7 @@ "submission.workflow.tasks.generic.processing": "Zpracování...", // "submission.workflow.tasks.generic.submitter": "Submitter", - "submission.workflow.tasks.generic.submitter": "Předkladatel", + "submission.workflow.tasks.generic.submitter": "Odesílatel", // "submission.workflow.tasks.generic.success": "Operation successful", "submission.workflow.tasks.generic.success": "Operace proběhla úspěšně", From 301eb9017c046873146d721f162ef90c3769afe2 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 9 Oct 2024 16:09:51 +0200 Subject: [PATCH 354/822] Fixed messages following the PR from the UFAL - https://github.com/dataquest-dev/dspace-angular/pull/669/commits/f18d45ce23ea9c42778885f59e5f7d25e548b2e9 (cherry picked from commit 5e5c627b8b4dbafc5454d91e24797f3ef6ef76aa) --- src/assets/i18n/cs.json5 | 220 +++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 5e52f751ec5..2cb95f10d3b 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -13,7 +13,7 @@ "403.help": "Nemáte povolení k přístupu na tuto stránku. Pro návrat na domovskou stránku můžete použít tlačítko níže.", // "403.link.home-page": "Take me to the home page", - "403.link.home-page": "Přesměrujte mě na domovskou stránku", + "403.link.home-page": "Návrat na domovskou stránku", // "403.forbidden": "Forbidden", "403.forbidden": "Přístup zakázán", @@ -46,7 +46,7 @@ "error-page.description.500": "Služba je nedostupná", // "error-page.description.404": "Page not found", - "error-page.description.404": "Stránka nebyla nenalezena", + "error-page.description.404": "Stránka nebyla nalezena", // "error-page.orcid.generic-error": "An error occurred during login via ORCID. Make sure you have shared your ORCID account email address with DSpace. If the error persists, contact the administrator", "error-page.orcid.generic-error": "Při přihlašování přes ORCID došlo k chybě. Ujistěte se, že jste sdíleli e-mailovou adresu připojenou ke svému účtu ORCID s DSpace. Pokud chyba přetrvává, kontaktujte správce", @@ -67,13 +67,13 @@ "access-status.unknown.listelement.badge": "Status neznámý", // "admin.curation-tasks.breadcrumbs": "System curation tasks", - "admin.curation-tasks.breadcrumbs": "Kurátorská úloha systému", + "admin.curation-tasks.breadcrumbs": "Systémové úlohy správy", // "admin.curation-tasks.title": "System curation tasks", - "admin.curation-tasks.title": "Kurátorská úloha systému", + "admin.curation-tasks.title": "Systémové úlohy správy", // "admin.curation-tasks.header": "System curation tasks", - "admin.curation-tasks.header": "Kurátorská úloha systému", + "admin.curation-tasks.header": "Systémové úlohy správy", // "admin.registries.bitstream-formats.breadcrumbs": "Format registry", "admin.registries.bitstream-formats.breadcrumbs": "Registr formátů", @@ -172,7 +172,7 @@ "admin.registries.bitstream-formats.edit.supportLevel.label": "Úroveň podpory", // "admin.registries.bitstream-formats.head": "Bitstream Format Registry", - "admin.registries.bitstream-formats.head": "Registr formátu souboru", + "admin.registries.bitstream-formats.head": "Registr formátů souboru", // "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", "admin.registries.bitstream-formats.no-items": "Žádné formáty souboru k zobrazení.", @@ -373,7 +373,7 @@ "admin.access-control.bulk-access.breadcrumbs": "Hromadná správa přístupu", // "administrativeBulkAccess.search.results.head": "Search Results", - "administrativeBulkAccess.search.results.head": "Prohledávat výsledky", + "administrativeBulkAccess.search.results.head": "Výsledky vyhledávání", // "admin.access-control.bulk-access": "Bulk Access Management", "admin.access-control.bulk-access": "Hromadná správa přístupu", @@ -403,7 +403,7 @@ "admin.access-control.epeople.actions.reset": "Resetovat heslo", // "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", - "admin.access-control.epeople.actions.stop-impersonating": "Přestat simulovat jiného uživatele", + "admin.access-control.epeople.actions.stop-impersonating": "Přestat vystupovat jako jiný uživatel", // "admin.access-control.epeople.breadcrumbs": "EPeople", "admin.access-control.epeople.breadcrumbs": "Uživatelé", @@ -612,7 +612,7 @@ "admin.access-control.groups.table.edit.buttons.remove": "Odstranit \"{{name}}\"", // "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", - "admin.access-control.groups.no-items": "Nebyly nalezeny žádné skupiny, které by měly toto ve svém názvu nebo toto jako UUID,", + "admin.access-control.groups.no-items": "Nebyla nalezena žádná skupina s tímto v návzvu nebo UUID", // "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", "admin.access-control.groups.notification.deleted.success": "Úspěšně odstraněna skupina \"{{name}}\"", @@ -696,7 +696,7 @@ "admin.access-control.groups.form.members-list.button.see-all": "Procházet vše", // "admin.access-control.groups.form.members-list.headMembers": "Current Members", - "admin.access-control.groups.form.members-list.headMembers": "Aktuální členové", + "admin.access-control.groups.form.members-list.headMembers": "Současní členové", // "admin.access-control.groups.form.members-list.search.button": "Search", "admin.access-control.groups.form.members-list.search.button": "Hledat", @@ -738,13 +738,13 @@ "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Přidat člena jménem \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", - "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "Žádná aktuální aktivní skupina, nejprve zadejte jméno.", + "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "Žádná aktuální aktivní skupina, nejprve zadejte název.", // "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", "admin.access-control.groups.form.members-list.no-members-yet": "Ve skupině zatím nejsou žádní členové, vyhledejte je a přidejte.", // "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", - "admin.access-control.groups.form.members-list.no-items": "V tomto vyhledávání nebyly nalezeni žádní uživatelé", + "admin.access-control.groups.form.members-list.no-items": "V tomto vyhledávání nebyli nalezeni žádní uživatelé", // "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", "admin.access-control.groups.form.subgroups-list.notification.failure": "Neúspěch: Něco se pokazilo: \"{{cause}}\"", @@ -801,7 +801,7 @@ "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "Toto je aktuální skupina, nelze přidat.", // "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", - "admin.access-control.groups.form.subgroups-list.no-items": "Nebyly nalezeny žádné skupiny, které by měly toto ve svém názvu nebo toto UUID", + "admin.access-control.groups.form.subgroups-list.no-items": "Nebyla nalezena žádná skupina s tímto v návzvu nebo UUID", // "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "Ve skupině zatím nejsou žádné podskupiny.", @@ -831,7 +831,7 @@ "admin.notifications.source.breadcrumbs": "Quality Assurance", // "admin.access-control.groups.form.tooltip.editGroupPage": "On this page, you can modify the properties and members of a group. In the top section, you can edit the group name and description, unless this is an admin group for a collection or community, in which case the group name and description are auto-generated and cannot be edited. In the following sections, you can edit group membership. See [the wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group) for more details.", - "admin.access-control.groups.form.tooltip.editGroupPage": "Na této stránce můžete upravit vlastnosti a členy skupiny. V horní části můžete upravit název a popis skupiny, pokud se nejedá o skupinu admin pro kolekci nebo komunitu. V takovém případě jsou název a popis skupiny vygenerovány automaticky a nelze je upravovat. V následujících částech můžete upravovat členství ve skupině. Další podrobnosti naleznete v části [the wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group).", + "admin.access-control.groups.form.tooltip.editGroupPage": "Na této stránce můžete upravit vlastnosti a členy skupiny. V horní části můžete upravit název a popis skupiny, pokud se nejedá o skupinu admin pro kolekci nebo komunitu. V takovém případě jsou název a popis skupiny vygenerovány automaticky a nelze je upravovat. V následujících částech můžete upravovat členství ve skupině. Další podrobnosti naleznete v části [wiki](https://wiki.lyrasis.org/display/DSDOC7x/Create+or+manage+a+user+group).", // "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "To add or remove an EPerson to/from this group, either click the 'Browse All' button or use the search bar below to search for users (use the dropdown to the left of the search bar to choose whether to search by metadata or by email). Then click the plus icon for each user you wish to add in the list below, or the trash can icon for each user you wish to remove. The list below may have several pages: use the page controls below the list to navigate to the next pages.", "admin.access-control.groups.form.tooltip.editGroup.addEpeople": "Pro přidání nebo odebrání uživatele z této skupiny, buď klikněte na „Prohledávat všechny“ nebo použijte vyhledávací okno pro vyhledání uživatele (použijte roletku na levé straně vyhledávacího okna a vyberte, zda chcete prohledávat pomocí metadat nebo e-mailu). Potom klikněte na tlačítko plus u každého uživatele, kterého chcete přidat, nebo na ikonu odpadkového koše u každého uživatele, kterého chcete odebrat. Seznam níže může obsahovat několik stránek: k přechodu na další stránku použijte ovládací prvky pod seznamem. Až budete hotovi, uložte změny pomocí tlačítka „Uložit“ v horní části.", @@ -1406,7 +1406,7 @@ "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.button.see-all": "Prohledávat vše", // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Current Members", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Aktuální členové", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.headMembers": "Současní členové", // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "Search", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.search.button": "Hledat", @@ -1448,7 +1448,7 @@ "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.table.edit.buttons.add": "Přidat uživatele jménem \"{{name}}\"", // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", - "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "Žádná aktivní skupina, nejdříve vložte název.", + "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.notification.failure.noActiveGroup": "Žádná aktuální aktivní skupina, nejprve zadejte název.", // "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-members-yet": "No members in group yet, search and add.", "advanced-workflow-action-select-reviewer.groups.form.reviewers-list.no-members-yet": "Žádní členové ve skupině, nejdříve vyhledejte a přidejte.", @@ -1792,7 +1792,7 @@ "claimed-approved-search-result-list-element.title": "Schváleno", // "claimed-declined-search-result-list-element.title": "Rejected, sent back to submitter", - "claimed-declined-search-result-list-element.title": "Zamítnuto, posláno zpět vkladateli", + "claimed-declined-search-result-list-element.title": "Zamítnuto, posláno zpět odesílateli", // "claimed-declined-task-search-result-list-element.title": "Declined, sent back to Review Manager's workflow", "claimed-declined-task-search-result-list-element.title": "Zamítnuto, posláno zpět správci schvalovacího workflow", @@ -1815,7 +1815,7 @@ "collection.create.sub-head": "Vytvořit kolekci pro komunitu {{ parent }}", // "collection.curate.header": "Curate Collection: {{collection}}", - "collection.curate.header": "Kurátorovat kolekci: {{collection}}", + "collection.curate.header": "Spravovat kolekci: {{collection}}", // "collection.delete.cancel": "Cancel", "collection.delete.cancel": "Zrušit", @@ -1923,7 +1923,7 @@ "collection.edit.logo.notifications.add.success": "Nahrání loga kolekce proběhlo úspěšně.", // "collection.edit.logo.notifications.delete.success.title": "Logo deleted", - "collection.edit.logo.notifications.delete.success.title": "Logo odstraněno", + "collection.edit.logo.notifications.delete.success.title": "Logo smazáno", // "collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo", "collection.edit.logo.notifications.delete.success.content": "Úspěšně odstraněno logo kolekce", @@ -1948,10 +1948,10 @@ "collection.edit.tabs.access-control.title": "Úprava kolekce - Řízení přístupu", // "collection.edit.tabs.curate.head": "Curate", - "collection.edit.tabs.curate.head": "Kurátorovat", + "collection.edit.tabs.curate.head": "Spravovat", // "collection.edit.tabs.curate.title": "Collection Edit - Curate", - "collection.edit.tabs.curate.title": "Upravit kolekci - kurátorovat", + "collection.edit.tabs.curate.title": "Upravit kolekci - správa", // "collection.edit.tabs.authorizations.head": "Authorizations", "collection.edit.tabs.authorizations.head": "Oprávnění", @@ -2014,7 +2014,7 @@ "collection.edit.tabs.source.head": "Zdroj obsahu", // "collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "collection.edit.tabs.source.notifications.discarded.content": "Vaše změny byly vyřazeny. Chcete-li své změny obnovit, klikněte na tlačítko Zpět", + "collection.edit.tabs.source.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "collection.edit.tabs.source.notifications.discarded.title": "Changes discarded", // TODO Source message changed - Revise the translation @@ -2024,7 +2024,7 @@ "collection.edit.tabs.source.notifications.invalid.content": "Vaše změny nebyly uloženy. Před uložením se prosím ujistěte, že jsou všechna pole platná.", // "collection.edit.tabs.source.notifications.invalid.title": "Metadata invalid", - "collection.edit.tabs.source.notifications.invalid.title": "Metadata neplatná", + "collection.edit.tabs.source.notifications.invalid.title": "Neplatná metadata", // "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", "collection.edit.tabs.source.notifications.saved.content": "Vaše změny ve zdroji obsahu této kolekce byly uloženy.", @@ -2215,7 +2215,7 @@ "collection.source.controls.harvest.no-information": "Není k dispozi", // "collection.source.update.notifications.error.content": "The provided settings have been tested and didn't work.", - "collection.source.update.notifications.error.content": "Zadané nastavení bylo testováno a nefungovalo.", + "collection.source.update.notifications.error.content": "Zadané nastavení bylo otestováno a nefungovalo.", // "collection.source.update.notifications.error.title": "Server Error", "collection.source.update.notifications.error.title": "Chyba serveru", @@ -2262,7 +2262,7 @@ "community.create.sub-head": "Vytvořit dílčí komunitu pro komunitu {{ parent }}", // "community.curate.header": "Curate Community: {{community}}", - "community.curate.header": "Kurátorství komunity: {{ community }}", + "community.curate.header": "Spravovat komunitu: {{ community }}", // "community.delete.cancel": "Cancel", "community.delete.cancel": "Zrušit", @@ -2295,7 +2295,7 @@ "community.edit.breadcrumbs": "Upravit komunitu", // "community.edit.logo.delete.title": "Delete logo", - "community.edit.logo.delete.title": "Odstranit logo", + "community.edit.logo.delete.title": "Smazat logo", // "community.edit.logo.delete-undo.title": "Undo delete", "community.edit.logo.delete-undo.title": "Zrušit odstranění", @@ -2310,7 +2310,7 @@ "community.edit.logo.notifications.add.success": "Nahrání loga komunity proběhlo úspěšně.", // "community.edit.logo.notifications.delete.success.title": "Logo deleted", - "community.edit.logo.notifications.delete.success.title": "Logo odstraněno", + "community.edit.logo.notifications.delete.success.title": "Logo smazáno", // "community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo", "community.edit.logo.notifications.delete.success.content": "Úspěšně odstraněno logo komunity", @@ -2335,10 +2335,10 @@ "community.edit.return": "Zpět", // "community.edit.tabs.curate.head": "Curate", - "community.edit.tabs.curate.head": "Kurátorovat", + "community.edit.tabs.curate.head": "Spravovat", // "community.edit.tabs.curate.title": "Community Edit - Curate", - "community.edit.tabs.curate.title": "Upravit komunitu - kurátorovat", + "community.edit.tabs.curate.title": "Upravit komunitu - správa", // "community.edit.tabs.access-control.head": "Access Control", "community.edit.tabs.access-control.head": "Řízení přístupu", @@ -2396,13 +2396,13 @@ "comcol-role.edit.collection-admin.name": "Správci", // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", - "comcol-role.edit.community-admin.description": "Správci komunit mohou vytvářet dílčí komunity nebo kolekce a spravovat nebo přidělovat správu těmto dílčím komunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do všech dílčích kolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", + "comcol-role.edit.community-admin.description": "Administrátoři komunit mohou vytvářet dílčí komunity nebo kolekce a spravovat nebo přidělovat správu těmto dílčím komunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do všech dílčích kolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", // "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", "comcol-role.edit.collection-admin.description": "Správci kolekcí rozhodují o tom, kdo může do kolekce vkládat záznamy, upravovat metadata záznamů (po vložení) a přidávat (mapovat) existující záznamy z jiných kolekcí do této kolekce (podléhá autorizaci pro danou kolekci).", // "comcol-role.edit.submitters.name": "Submitters", - "comcol-role.edit.submitters.name": "Vkladatelé", + "comcol-role.edit.submitters.name": "Odesílatelé", // "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", "comcol-role.edit.submitters.description": "Uživatelé a skupiny, které mají oprávnění ke vkládání nových záznamů do této kolekce.", @@ -2460,7 +2460,7 @@ "community.form.errors.title.required": "Zadejte název komunity", // "community.form.rights": "Copyright text (HTML)", - "community.form.rights": "Text autorských práv (HTML)", + "community.form.rights": "Copyright (HTML)", // "community.form.tableofcontents": "News (HTML)", "community.form.tableofcontents": "Novinky (HTML)", @@ -2640,16 +2640,16 @@ "curation.form.submit": "Start", // "curation.form.submit.success.head": "The curation task has been started successfully", - "curation.form.submit.success.head": "Kurátorská úloha byla úspěšně spuštěna", + "curation.form.submit.success.head": "Úloha správy byla úspěšně spuštěna", // "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", "curation.form.submit.success.content": "Budete přesměrováni na příslušnou stránku procesu.", // "curation.form.submit.error.head": "Running the curation task failed", - "curation.form.submit.error.head": "Spuštění kurátorské úlohy se nezdařilo.", + "curation.form.submit.error.head": "Spuštění úlohy správy se nezdařilo.", // "curation.form.submit.error.content": "An error occured when trying to start the curation task.", - "curation.form.submit.error.content": "Při pokusu o spuštění kurátorské úlohy došlo k chybě.", + "curation.form.submit.error.content": "Při pokusu o spuštění úlohy správy došlo k chybě.", // "curation.form.submit.error.invalid-handle": "Couldn't determine the handle for this object", "curation.form.submit.error.invalid-handle": "Nepodařilo se určit handle pro tento objekt", @@ -3044,7 +3044,7 @@ "forgot-email.form.success.head": "E-mail pro obnovení hesla odeslán", // "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", - "forgot-email.form.success.content": "Na adresu {{ email }} byl odeslán e-mail obsahující speciální adresu URL a další pokyny.", + "forgot-email.form.success.content": "Na adresu {{ email }} byl odeslán e-mail obsahující speciální URL a další instrukce.", // "forgot-email.form.error.head": "Error when trying to reset password", // TODO Source message changed - Revise the translation @@ -3242,7 +3242,7 @@ "grant-deny-request-copy.header": "Žádost o kopii dokumentu", // "grant-deny-request-copy.home-page": "Take me to the home page", - "grant-deny-request-copy.home-page": "Přesměrujte mne na domovskou stránku", + "grant-deny-request-copy.home-page": "Návrat na domovskou stránku", // "grant-deny-request-copy.intro1": "If you are one of the authors of the document {{ name }}, then please use one of the options below to respond to the user's request.", "grant-deny-request-copy.intro1": "Pokud jste jedním z autorů dokumentu {{ name }}, použijte prosím jednu z níže uvedených možností, abyste odpověděli na žádost uživatele.", @@ -3278,13 +3278,13 @@ "health-page.info-tab": "Informace", // "health-page.status-tab": "Status", - "health-page.status-tab": "Status", + "health-page.status-tab": "Stav", // "health-page.error.msg": "The health check service is temporarily unavailable", "health-page.error.msg": "Služba kontrolující stav systému je momentálně nedostupná.", // "health-page.property.status": "Status code", - "health-page.property.status": "Kód statusu", + "health-page.property.status": "Stavový kód", // "health-page.section.db.title": "Database", "health-page.section.db.title": "Databáze", @@ -3455,7 +3455,7 @@ "item.badge.private": "Nedohledatelné", // "item.badge.withdrawn": "Withdrawn", - "item.badge.withdrawn": "Zrušeno", + "item.badge.withdrawn": "Vyřazeno", // "item.bitstreams.upload.bundle": "Bundle", "item.bitstreams.upload.bundle": "Svazek", @@ -3543,10 +3543,10 @@ "item.edit.bitstreams.headers.name": "Název", // "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.bitstreams.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Undo'", + "item.edit.bitstreams.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", - "item.edit.bitstreams.notifications.discarded.title": "Změny zahozeny", + "item.edit.bitstreams.notifications.discarded.title": "Zahozené změny", // "item.edit.bitstreams.notifications.move.failed.title": "Error moving bitstreams", "item.edit.bitstreams.notifications.move.failed.title": "Chyba při přesunu souborů", @@ -3558,7 +3558,7 @@ "item.edit.bitstreams.notifications.move.saved.title": "Změny uloženy", // "item.edit.bitstreams.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.bitstreams.notifications.outdated.content": "Záznam, na které právě pracujete, byl změněn jiným uživatelem. Vaše aktuální změny jsou zahozeny, aby se zabránilo konfliktům", + "item.edit.bitstreams.notifications.outdated.content": "Záznam, na kterém právě pracujete, byl změněn jiným uživatelem. Vaše aktuální změny byly zahozeny, aby se zabránilo konfliktům", // "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", "item.edit.bitstreams.notifications.outdated.title": "Změny jsou zastaralé", @@ -3651,13 +3651,13 @@ "item.edit.identifiers.doi.status.MINTED": "Vydáno (nezaregistrováno)", // "item.edit.tabs.status.buttons.register-doi.label": "Register a new or pending DOI", - "item.edit.tabs.status.buttons.register-doi.label": "Registrace nového nebo čekání na nové DOI", + "item.edit.tabs.status.buttons.register-doi.label": "Registrovat nové nebo čekající DOI", // "item.edit.tabs.status.buttons.register-doi.button": "Register DOI...", "item.edit.tabs.status.buttons.register-doi.button": "Zaregistrujte DOI...", // "item.edit.register-doi.header": "Register a new or pending DOI", - "item.edit.register-doi.header": "Zaregistrujte nové DOI nebo čekající k registraci", + "item.edit.register-doi.header": "Registrovat nové nebo čekající DOI", // "item.edit.register-doi.description": "Review any pending identifiers and item metadata below and click Confirm to proceed with DOI registration, or Cancel to back out", "item.edit.register-doi.description": "Níže zkontrolujte všechny identifikátory a metadata ve frontě. Zvolte \"Potvrdit\" pro pokračování v registraci DOI nebo \"Zrušit\" pro přerušení procesu.", @@ -3687,7 +3687,7 @@ "item.edit.item-mapper.cancel": "Zrušit", // "item.edit.item-mapper.description": "This is the item mapper tool that allows administrators to map this item to other collections. You can search for collections and map them, or browse the list of collections the item is currently mapped to.", - "item.edit.item-mapper.description": "Toto je nástroj pro mapování záznamů, který umožňuje správcům mapovat tuto záznam na jiné kolekce. Můžete vyhledávat kolekce a mapovat je nebo procházet seznam kolekcí, ke kterým je záznam aktuálně mapována.", + "item.edit.item-mapper.description": "Toto je nástroj pro mapování záznamů, který umožňuje správcům mapovat tento záznam do jiné kolekce. Můžete vyhledávat kolekce a mapovat je nebo procházet seznam kolekcí, ke kterým je záznam aktuálně mapována.", // "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", "item.edit.item-mapper.head": "Mapování do jiných kolekcí - mapovat záznam do kolekcí", @@ -3768,7 +3768,7 @@ "item.edit.metadata.edit.buttons.unedit": "Zastavit úpravy", // "item.edit.metadata.edit.buttons.virtual": "This is a virtual metadata value, i.e. a value inherited from a related entity. It can’t be modified directly. Add or remove the corresponding relationship in the \"Relationships\" tab", - "item.edit.metadata.edit.buttons.virtual": "Tato hodnota metadat je virtuální, tedy děděná z příbuzné entity. Nemůže být zděděna napřímo. Přidejte či odeberte příslušný vztah na záložce \"Vztahy\".", + "item.edit.metadata.edit.buttons.virtual": "Tato hodnota metadat je virtuální, tedy děděná z provázané entity. Nemůže být změněna napřímo. Přidejte či odeberte příslušný vztah na záložce \"Vztahy\".", // "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", "item.edit.metadata.empty": "Záznam aktuálně neobsahuje žádná metadata. Kliknutím na tlačítko Přidat začněte přidávat hodnotu metadat.", @@ -3796,11 +3796,11 @@ "item.edit.metadata.metadatafield.invalid": "Prosím, vyberte platné metadatové pole", // "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.metadata.notifications.discarded.content": "Vaše změny byly vyřazeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", + "item.edit.metadata.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "item.edit.metadata.notifications.discarded.title": "Changes discarded", // TODO Source message changed - Revise the translation - "item.edit.metadata.notifications.discarded.title": "Změny zahozeny", + "item.edit.metadata.notifications.discarded.title": "Zahozené změny", // "item.edit.metadata.notifications.error.title": "An error occurred", "item.edit.metadata.notifications.error.title": "Došlo k chybě", @@ -3809,17 +3809,17 @@ "item.edit.metadata.notifications.invalid.content": "Vaše změny nebyly uloženy. Před uložením se prosím ujistěte, že jsou všechna pole platná.", // "item.edit.metadata.notifications.invalid.title": "Metadata invalid", - "item.edit.metadata.notifications.invalid.title": "Metadata neplatná", + "item.edit.metadata.notifications.invalid.title": "Neplatná metadata", // "item.edit.metadata.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.metadata.notifications.outdated.content": "Záznam, na které právě pracujete, byl změněna jiným uživatelem. Vaše aktuální změny jsou zahozeny, aby se zabránilo konfliktům", + "item.edit.metadata.notifications.outdated.content": "Záznam, na kterém právě pracujete, byl změněn jiným uživatelem. Vaše aktuální změny byly zahozeny, aby se zabránilo konfliktům", // "item.edit.metadata.notifications.outdated.title": "Changes outdated", // TODO Source message changed - Revise the translation "item.edit.metadata.notifications.outdated.title": "Změny jsou zastaralé", // "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", - "item.edit.metadata.notifications.saved.content": "Vaše změny metadat této záznamu byly uloženy.", + "item.edit.metadata.notifications.saved.content": "Vaše změny metadat tohoto záznamu byly uloženy.", // "item.edit.metadata.notifications.saved.title": "Metadata saved", "item.edit.metadata.notifications.saved.title": "Metadata uložena", @@ -3976,16 +3976,16 @@ "item.edit.relationships.no-relationships": "Žádné vztahy", // "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.relationships.notifications.discarded.content": "Vaše změny byly vyřazeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", + "item.edit.relationships.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "item.edit.relationships.notifications.discarded.title": "Changes discarded", - "item.edit.relationships.notifications.discarded.title": "Změny vyřazeny", + "item.edit.relationships.notifications.discarded.title": "Zahozené změny", // "item.edit.relationships.notifications.failed.title": "Error editing relationships", "item.edit.relationships.notifications.failed.title": "Chyba při úpravě vztahů", // "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.relationships.notifications.outdated.content": "Záznam, na které právě pracujete, byl změněna jiným uživatelem. Vaše aktuální změny jsou vyřazeny, aby se zabránilo konfliktům", + "item.edit.relationships.notifications.outdated.content": "Záznam, na kterém právě pracujete, byl změněn jiným uživatelem. Vaše aktuální změny byly zahozeny, aby se zabránilo konfliktům", // "item.edit.relationships.notifications.outdated.title": "Changes outdated", "item.edit.relationships.notifications.outdated.title": "Změny jsou zastaralé", @@ -4009,25 +4009,25 @@ "item.edit.return": "Zpět", // "item.edit.tabs.bitstreams.head": "Bitstreams", - "item.edit.tabs.bitstreams.head": "Soubor", + "item.edit.tabs.bitstreams.head": "Soubory", // "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", "item.edit.tabs.bitstreams.title": "Úprava záznamu - soubor", // "item.edit.tabs.curate.head": "Curate", - "item.edit.tabs.curate.head": "Kurátorovat", + "item.edit.tabs.curate.head": "Spravovat", // "item.edit.tabs.curate.title": "Item Edit - Curate", - "item.edit.tabs.curate.title": "Úprava záznamu - Kurátorovat", + "item.edit.tabs.curate.title": "Úprava záznamu - spravovat", // "item.edit.curate.title": "Curate Item: {{item}}", - "item.edit.curate.title": "Kurátorovat záznam: {{item}}", + "item.edit.curate.title": "Spravovat záznam: {{item}}", // "item.edit.tabs.access-control.head": "Access Control", - "item.edit.tabs.access-control.head": "Kontrola přístupu", + "item.edit.tabs.access-control.head": "Řízení přístupu", // "item.edit.tabs.access-control.title": "Item Edit - Access Control", - "item.edit.tabs.access-control.title": "Úprava záznamu - Kontrola přístupu", + "item.edit.tabs.access-control.title": "Úprava záznamu - Řízení přístupu", // "item.edit.tabs.metadata.head": "Metadata", "item.edit.tabs.metadata.head": "Metadata", @@ -4275,7 +4275,7 @@ "item.page.collections": "Kolekce", // "item.page.collections.loading": "Loading...", - "item.page.collections.loading": "Načítání...", + "item.page.collections.loading": "Načítá se...", // "item.page.collections.load-more": "Load more", "item.page.collections.load-more": "Načíst další", @@ -4377,7 +4377,7 @@ "item.page.reinstate": "Request reinstatement", // "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history", - "item.page.version.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí právě probíhá zadání nové verze.", + "item.page.version.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí už další rozpracovaná verze existuje.", // "item.page.claim.button": "Claim", "item.page.claim.button": "Prohlásit", @@ -4585,7 +4585,7 @@ "item.version.history.table.action.deleteVersion": "Smazat verzi", // "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history", - "item.version.history.table.action.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí probíhá odesílání.", + "item.version.history.table.action.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí už další rozpracovaná verze existuje.", // "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", "item.version.notice": "Toto není nejnovější verze tohoto záznamu. Nejnovější verzi naleznete zde.", @@ -4698,7 +4698,7 @@ "item.version.create.notification.failure": "Nová verze nebyla vytvořena", // "item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history", - "item.version.create.notification.inProgress": "Nová verze nemůže být vytvořena, protože v historii verzí probíhá odesílání.", + "item.version.create.notification.inProgress": "Nová verze nemůže být vytvořena, protože v historii verzí už další rozpracovaná verze existuje.", // "item.version.delete.modal.header": "Delete version", "item.version.delete.modal.header": "Smazat verzi", @@ -4788,7 +4788,7 @@ "itemtemplate.edit.metadata.metadatafield.invalid": "Prosím zvolte platné metadatové pole", // "itemtemplate.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "itemtemplate.edit.metadata.notifications.discarded.content": "Vaše změny byly zahozeny. Chcete-li obnovit své změny, klikněte na tlačítko 'Zpět'.", + "itemtemplate.edit.metadata.notifications.discarded.content": "Vaše změny byly zahozeny. Pro obnovení změn klikněte na tlačítko 'Vrátit změny'", // "itemtemplate.edit.metadata.notifications.discarded.title": "Changes discarded", "itemtemplate.edit.metadata.notifications.discarded.title": "Změny byly zahozeny", @@ -4797,7 +4797,7 @@ "itemtemplate.edit.metadata.notifications.error.title": "Vyskytla se chyba", // "itemtemplate.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", - "itemtemplate.edit.metadata.notifications.invalid.content": "Vaše změny nebyly uloženy. Před uložením se ujistěte, že všechna pole jsou platná.", + "itemtemplate.edit.metadata.notifications.invalid.content": "Vaše změny nebyly uloženy. Před uložením se prosím ujistěte, že jsou všechna pole platná.", // "itemtemplate.edit.metadata.notifications.invalid.title": "Metadata invalid", "itemtemplate.edit.metadata.notifications.invalid.title": "Neplatná metadata", @@ -4812,7 +4812,7 @@ "itemtemplate.edit.metadata.notifications.saved.content": "Vaše změny v šabloně metadat tohoto záznamu byly uloženy.", // "itemtemplate.edit.metadata.notifications.saved.title": "Metadata saved", - "itemtemplate.edit.metadata.notifications.saved.title": "Metadata uloženy", + "itemtemplate.edit.metadata.notifications.saved.title": "Metadata uložena", // "itemtemplate.edit.metadata.reinstate-button": "Undo", "itemtemplate.edit.metadata.reinstate-button": "Vrátit zpět", @@ -5043,7 +5043,7 @@ "menu.header.admin": "Admin", // "menu.header.image.logo": "Repository logo", - "menu.header.image.logo": "Logo úložiště", + "menu.header.image.logo": "Logo repozitáře", // "menu.header.admin.description": "Management menu", "menu.header.admin.description": "Management menu", @@ -5119,7 +5119,7 @@ "menu.section.control_panel": "Ovládací panel", // "menu.section.curation_task": "Curation Task", - "menu.section.curation_task": "Kurátorská úloha", + "menu.section.curation_task": "Úloha správy", // "menu.section.edit": "Edit", "menu.section.edit": "Upravit", @@ -5165,25 +5165,25 @@ "menu.section.icon.control_panel": "Sekce menu Ovládací panel", // "menu.section.icon.curation_tasks": "Curation Task menu section", - "menu.section.icon.curation_tasks": "Sekce menu Kurátorská úloha", + "menu.section.icon.curation_tasks": "Sekce menu úloha správy", // "menu.section.icon.edit": "Edit menu section", "menu.section.icon.edit": "Sekce menu Upravit", // "menu.section.icon.export": "Export menu section", - "menu.section.icon.export": "Exportovat sekci menu", + "menu.section.icon.export": "Sekce menu Exportovat", // "menu.section.icon.find": "Find menu section", - "menu.section.icon.find": "Najít sekci menu", + "menu.section.icon.find": "Sekce menu Najít", // "menu.section.icon.health": "Health check menu section", - "menu.section.icon.health": "Kontrola stavu sekce menu", + "menu.section.icon.health": "Sekce menu Kontrola stavu", // "menu.section.icon.import": "Import menu section", - "menu.section.icon.import": "Importovat sekci menu", + "menu.section.icon.import": "Sekce menu Importovat", // "menu.section.icon.new": "New menu section", - "menu.section.icon.new": "Nová sekce menu", + "menu.section.icon.new": "Sekce menu Nový", // "menu.section.icon.pin": "Pin sidebar", "menu.section.icon.pin": "Připnout postranní panel", @@ -5260,7 +5260,7 @@ "menu.section.health": "Stav systému", // "menu.section.registries": "Registries", - "menu.section.registries": "Rejstřík", + "menu.section.registries": "Registry", // "menu.section.registries_format": "Format", "menu.section.registries_format": "Formát", @@ -5285,7 +5285,7 @@ "menu.section.toggle.control_panel": "Přepnout sekci ovládacího panelu", // "menu.section.toggle.curation_task": "Toggle Curation Task section", - "menu.section.toggle.curation_task": "Přepnout sekci Kurátorská úloha", + "menu.section.toggle.curation_task": "Přepnout sekci úloha správy", // "menu.section.toggle.edit": "Toggle Edit section", "menu.section.toggle.edit": "Přepnout sekci Úpravy", @@ -5303,7 +5303,7 @@ "menu.section.toggle.new": "Přepnout sekci Nová", // "menu.section.toggle.registries": "Toggle Registries section", - "menu.section.toggle.registries": "Přepnout sekci Rejstříky", + "menu.section.toggle.registries": "Přepnout sekci Registry", // "menu.section.toggle.statistics_task": "Toggle Statistics Task section", "menu.section.toggle.statistics_task": "Přepnout sekci Statistická úloha", @@ -5327,7 +5327,7 @@ "mydspace.description": "", // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", - "mydspace.messages.controller-help": "Zvolte tuto možnost, chcete-li odeslat zprávu vkladateli záznamu.", + "mydspace.messages.controller-help": "Zvolte tuto možnost, chcete-li odeslat zprávu odesílateli záznamu.", // "mydspace.messages.description-placeholder": "Insert your message here...", "mydspace.messages.description-placeholder": "Zde vložte svou zprávu...", @@ -5506,7 +5506,7 @@ "nav.statistics.header": "Statistika", // "nav.stop-impersonating": "Stop impersonating EPerson", - "nav.stop-impersonating": "Přestat simulovat jiného uživatele", + "nav.stop-impersonating": "Přestat vystupovat jako jiný uživatel", // "nav.subscriptions": "Subscriptions", "nav.subscriptions": "Nastavení notifikací", @@ -5810,7 +5810,7 @@ "orgunit.page.city": "Město", // "orgunit.page.country": "Country", - "orgunit.page.country": "Stát", + "orgunit.page.country": "Země", // "orgunit.page.dateestablished": "Date established", "orgunit.page.dateestablished": "Datum založení.", @@ -5892,7 +5892,7 @@ "person-relationships.search.results.head": "Výsledky vyhledávání osob", // "person.search.title": "Person Search", - "person.search.title": "Vyledatávání osob", + "person.search.title": "Vyhledávání osob", // "process.new.select-parameters": "Parameters", "process.new.select-parameters": "Parametry", @@ -6121,7 +6121,7 @@ "process.overview.delete.clear": "Zrušit výběr mazání", // "process.overview.delete.processing": "{{count}} process(es) are being deleted. Please wait for the deletion to fully complete. Note that this can take a while.", - "process.overview.delete.processing": "Smazává se {{count}} procesů. Počkejte prosím na úplné dokončení mazání. To může chvíli trvat.", + "process.overview.delete.processing": "Maže se {{count}} procesů. Počkejte prosím na úplné dokončení mazání. To může chvíli trvat.", // "process.overview.delete.body": "Are you sure you want to delete {{count}} process(es)?", "process.overview.delete.body": "Určitě chcete smazat {{count}} procesů", @@ -6512,7 +6512,7 @@ "register-page.registration.header": "Registrace nového uživatele", // "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", - "register-page.registration.info": "Zaregistrujte si účet a přihlaste se k odběru sbírek pro e-mailové aktualizace a odesílejte nové záznamy do systému DSpace", + "register-page.registration.info": "Zaregistrujte si účet a přihlaste se k odběru kolekcí pro e-mailové aktualizace a odesílejte nové záznamy do systému DSpace", // "register-page.registration.email": "Email Address *", "register-page.registration.email": "E-mailová adresa *", @@ -6880,7 +6880,7 @@ "search.filters.applied.f.dateIssued.min": "Datum zahájení", // "search.filters.applied.f.dateSubmitted": "Date submitted", - "search.filters.applied.f.dateSubmitted": "Date vložení", + "search.filters.applied.f.dateSubmitted": "Datum vložení", // "search.filters.applied.f.discoverable": "Non-discoverable", // TODO Source message changed - Revise the translation @@ -6925,7 +6925,7 @@ "search.filters.applied.f.supervisedBy": "Zkontrolováno", // "search.filters.applied.f.withdrawn": "Withdrawn", - "search.filters.applied.f.withdrawn": "Zrušeno", + "search.filters.applied.f.withdrawn": "Vyřazeno", // "search.filters.applied.operator.equals": "", // TODO New key - Add a translation @@ -7142,10 +7142,10 @@ "search.filters.filter.objectpeople.label": "Hledat osoby", // "search.filters.filter.organizationAddressCountry.head": "Country", - "search.filters.filter.organizationAddressCountry.head": "Stát", + "search.filters.filter.organizationAddressCountry.head": "Země", // "search.filters.filter.organizationAddressCountry.placeholder": "Country", - "search.filters.filter.organizationAddressCountry.placeholder": "Stát", + "search.filters.filter.organizationAddressCountry.placeholder": "Země", // "search.filters.filter.organizationAddressCountry.label": "Search country", "search.filters.filter.organizationAddressCountry.label": "Hledat stát", @@ -7438,10 +7438,10 @@ "sorting.dc.date.issued.DESC": "Datum vydání sestupně", // "sorting.dc.date.accessioned.ASC": "Accessioned Date Ascending", - "sorting.dc.date.accessioned.ASC": "Datum přírůstku vzestupně", + "sorting.dc.date.accessioned.ASC": "Datum odeslání vzestupně", // "sorting.dc.date.accessioned.DESC": "Accessioned Date Descending", - "sorting.dc.date.accessioned.DESC": "Datum přírůstku sestupně", + "sorting.dc.date.accessioned.DESC": "Datum odeslání sestupně", // "sorting.lastModified.ASC": "Last modified Ascending", "sorting.lastModified.ASC": "Naposledy upraveno vzestupně", @@ -8284,7 +8284,7 @@ "submission.sections.identifiers.info": "Pro tento záznam budou vytvořeny následující identifikátory:", // "submission.sections.identifiers.no_handle": "No handles have been minted for this item.", - "submission.sections.identifiers.no_handle": "Tomuto záznamu nybyl přidělen žádný handle.", + "submission.sections.identifiers.no_handle": "Tomuto záznamu nebyl přidělen žádný handle.", // "submission.sections.identifiers.no_doi": "No DOIs have been minted for this item.", "submission.sections.identifiers.no_doi": "Tomuto záznamu nebylo přiděleno žádné DOI.", @@ -8446,10 +8446,10 @@ "submission.sections.upload.form.until-placeholder": "Až do", // "submission.sections.upload.header.policy.default.nolist": "Uploaded files in the {{collectionName}} collection will be accessible according to the following group(s):", - "submission.sections.upload.header.policy.default.nolist": "Nahrané soubory v kolekci {{collectionName}} budou přístupné podle následující skupiny (skupin):", + "submission.sections.upload.header.policy.default.nolist": "Nahrané soubory v kolekci {{collectionName}} budou přístupné podle následujících skupin:", // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - "submission.sections.upload.header.policy.default.withlist": "Vezměte prosím na vědomí, že nahrané soubory v kolekci {{collectionName}} budou kromě toho, co je explicitně rozhodnuto pro jednotlivý soubor, přístupné podle následující skupiny (skupin):", + "submission.sections.upload.header.policy.default.withlist": "Vezměte prosím na vědomí, že nahrané soubory v kolekci {{collectionName}} budou kromě toho, co je explicitně rozhodnuto pro jednotlivý soubor, přístupné podle následujících skupin:", // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Zde najdete všechny soubory, které jsou aktuálně v záznamu. Můžete aktualizovat metadata souborů a podmínky přístupu nebo nahrát další soubory pouhým přetažením kdekoli na stránku.", @@ -8618,7 +8618,7 @@ "submission.sections.sherpa.record.information.uri": "URI", // "submission.sections.sherpa.error.message": "There was an error retrieving sherpa informations", - "submission.sections.sherpa.error.message": "Informace ze Sherpa Romeo se nepodařilo načíst.", + "submission.sections.sherpa.error.message": "Při načítání informací ze služby Sherpa došlo k chybě", // "submission.submit.breadcrumbs": "New submission", "submission.submit.breadcrumbs": "Nově podaný záznam", @@ -8676,7 +8676,7 @@ "submission.workflow.tasks.claimed.decline_help": "", // "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", - "submission.workflow.tasks.claimed.reject.reason.info": "Do níže uvedeného pole zadejte důvod odmítnutí podání a uveďte, zda může vkladatel problém odstranit a podání znovu odeslat.", + "submission.workflow.tasks.claimed.reject.reason.info": "Do níže uvedeného pole zadejte důvod odmítnutí podání a uveďte, zda může odesílatel problém odstranit a podání znovu odeslat.", // "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", "submission.workflow.tasks.claimed.reject.reason.placeholder": "Popište důvod odmítnutí", @@ -8691,7 +8691,7 @@ "submission.workflow.tasks.claimed.reject.submit": "Odmítnout", // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", - "submission.workflow.tasks.claimed.reject_help": "Pokud jste záznam zkontrolovali a zjistili, že není vhodný pro zařazení do kolekce, vyberte \"Odmítnout\". Poté budete vyzváni k zadání zprávy, ve které uvedete, proč je záznam nevhodný, a zda by měl vkladatel něco změnit a znovu odeslat.", + "submission.workflow.tasks.claimed.reject_help": "Pokud jste záznam zkontrolovali a zjistili, že není vhodný pro zařazení do kolekce, vyberte \"Odmítnout\". Poté budete vyzváni k zadání zprávy, ve které uvedete, proč je záznam nevhodný, a zda by měl odesílatel něco změnit a znovu odeslat.", // "submission.workflow.tasks.claimed.return": "Return to pool", "submission.workflow.tasks.claimed.return": "Vrátit do fondu", @@ -8712,7 +8712,7 @@ "submission.workflow.tasks.generic.success": "Operace proběhla úspěšně", // "submission.workflow.tasks.pool.claim": "Claim", - "submission.workflow.tasks.pool.claim": "Vyžádat si", + "submission.workflow.tasks.pool.claim": "Převzít", // "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", "submission.workflow.tasks.pool.claim_help": "Přiřaďte si tento úkol.", @@ -8909,7 +8909,7 @@ "uploader.or": ", nebo ", // "uploader.processing": "Processing uploaded file(s)... (it's now safe to close this page)", - "uploader.processing": "(nyní je bezpečné tuto stránku zavřít)", + "uploader.processing": "Zpracovávám nahrané soubory... (nyní je bezpečné tuto stránku zavřít)", // "uploader.queue-length": "Queue length", "uploader.queue-length": "Délka fronty", @@ -8933,7 +8933,7 @@ "workflowAdmin.search.results.head": "Spravovat workflow", // "workflow.search.results.head": "Workflow tasks", - "workflow.search.results.head": "Kroky workflow", + "workflow.search.results.head": "Úlohy workflow", // "supervision.search.results.head": "Workflow and Workspace tasks", "supervision.search.results.head": "Úlohy Workflow a osobního pracovního prostoru", @@ -8973,22 +8973,22 @@ "workflow-item.delete.button.confirm": "Smazat", // "workflow-item.send-back.notification.success.title": "Sent back to submitter", - "workflow-item.send-back.notification.success.title": "Odesláno zpět vkladateli", + "workflow-item.send-back.notification.success.title": "Vráceno zpět odesílateli", // "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", - "workflow-item.send-back.notification.success.content": "Tento záznam ve workflow byl úspěšně odeslán zpět vkladateli", + "workflow-item.send-back.notification.success.content": "Tento záznam ve workflow byl úspěšně vrácen zpět odesílateli", // "workflow-item.send-back.notification.error.title": "Something went wrong", "workflow-item.send-back.notification.error.title": "Něco se pokazilo", // "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", - "workflow-item.send-back.notification.error.content": "Záznam ve workflow se nepodařilo odeslat zpět vkladateli", + "workflow-item.send-back.notification.error.content": "Záznam ve workflow se nepodařilo vrátit zpět odesílateli", // "workflow-item.send-back.title": "Send workflow item back to submitter", - "workflow-item.send-back.title": "Odeslat záznam ve workflow zpět vladateli", + "workflow-item.send-back.title": "Vrátit záznam ve workflow zpět odesílateli", // "workflow-item.send-back.header": "Send workflow item back to submitter", - "workflow-item.send-back.header": "Odeslat záznam ve workflow zpět vladateli", + "workflow-item.send-back.header": "Vrátit záznam ve workflow zpět odesílateli", // "workflow-item.send-back.button.cancel": "Cancel", "workflow-item.send-back.button.cancel": "Zrušit", @@ -9004,7 +9004,7 @@ "workspace-item.view.breadcrumbs": "Zobrazení pracovního prostoru", // "workspace-item.view.title": "Workspace View", - "workspace-item.view.title": "Zobrazení pracovní prostoru", + "workspace-item.view.title": "Zobrazení pracovního prostoru", // "workspace-item.delete.breadcrumbs": "Workspace Delete", "workspace-item.delete.breadcrumbs": "Vymazat obsah pracovního prostoru", @@ -9337,7 +9337,7 @@ "person.page.orcid.sync-queue.send.bad-request-error": "Odeslání do ORCID se nezdařilo, protože zdroj odeslaný do registru ORCID není platný", // "person.page.orcid.sync-queue.send.error": "The submission to ORCID failed", - "person.page.orcid.sync-queue.send.error": "Podání do ORCID se nezdařilo", + "person.page.orcid.sync-queue.send.error": "Odeslání do ORCID se nezdařilo", // "person.page.orcid.sync-queue.send.conflict-error": "The submission to ORCID failed because the resource is already present on the ORCID registry", "person.page.orcid.sync-queue.send.conflict-error": "Odeslání do ORCID se nezdařilo, protože zdroj se již nachází v registru ORCID", @@ -9490,7 +9490,7 @@ "system-wide-alert-form.retrieval.error": "Něco se pokazilo při načítání systémových upozornění", // "system-wide-alert.form.cancel": "Cancel", - "system-wide-alert.form.cancel": "Zrušir", + "system-wide-alert.form.cancel": "Zrušit", // "system-wide-alert.form.save": "Save", "system-wide-alert.form.save": "Uložit", @@ -9508,7 +9508,7 @@ "system-wide-alert.form.label.message": "Obsah upozornění", // "system-wide-alert.form.label.countdownTo.enable": "Enable a countdown timer", - "system-wide-alert.form.label.countdownTo.enable": "Povolit odpočítávací měřič", + "system-wide-alert.form.label.countdownTo.enable": "Povolit odpočet", // "system-wide-alert.form.label.countdownTo.hint": "Hint: Set a countdown timer. When enabled, a date can be set in the future and the system-wide alert banner will perform a countdown to the set date. When this timer ends, it will disappear from the alert. The server will NOT be automatically stopped.", "system-wide-alert.form.label.countdownTo.hint": "Nápověda: Nastavte odpočítávací měřič. Je-li to povoleno, lze datum nastavit i v budoucnosti a systémový upozornění bude uvádět odpočítávání do nastaveného data. Ve chvíli, kdy skončí odpočítávání, zmizí i odpočítávač z upozornění. Server NEBUDE automaticky zastaven.", @@ -9643,7 +9643,7 @@ // "vocabulary-treeview.search.form.add": "Add", // TODO New key - Add a translation - "vocabulary-treeview.search.form.add": "Add", + "vocabulary-treeview.search.form.add": "Přidat", // "admin.notifications.publicationclaim.breadcrumbs": "Publication Claim", // TODO New key - Add a translation From 5049b13d22b3ba424f1b82d66e3acc019d52973f Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 9 Oct 2024 16:14:04 +0200 Subject: [PATCH 355/822] Updated cs localization for subcommunities and subcollections (cherry picked from commit 9badd4a4b6261a2abf5ed838f16bb000b1a127f0) --- src/assets/i18n/cs.json5 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 2cb95f10d3b..09dd023e8d5 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -2259,7 +2259,7 @@ "community.create.notifications.success": "Úspěšně vytvořena komunita", // "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", - "community.create.sub-head": "Vytvořit dílčí komunitu pro komunitu {{ parent }}", + "community.create.sub-head": "Vytvořit podkomunitu v komunitě {{ parent }}", // "community.curate.header": "Curate Community: {{community}}", "community.curate.header": "Spravovat komunitu: {{ community }}", @@ -2396,7 +2396,7 @@ "comcol-role.edit.collection-admin.name": "Správci", // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", - "comcol-role.edit.community-admin.description": "Administrátoři komunit mohou vytvářet dílčí komunity nebo kolekce a spravovat nebo přidělovat správu těmto dílčím komunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do všech dílčích kolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", + "comcol-role.edit.community-admin.description": "Administrátoři komunit mohou vytvářet podkomunity nebo kolekce a spravovat nebo přidělovat správu těmto podkomunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do všech podkolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", // "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", "comcol-role.edit.collection-admin.description": "Správci kolekcí rozhodují o tom, kdo může do kolekce vkládat záznamy, upravovat metadata záznamů (po vložení) a přidávat (mapovat) existující záznamy z jiných kolekcí do této kolekce (podléhá autorizaci pro danou kolekci).", @@ -2421,7 +2421,7 @@ // "comcol-role.edit.bitstream_read.description": "E-People and Groups that can read new bitstreams submitted to this collection. Changes to this role are not retroactive. Existing bitstreams in the system will still be viewable by those who had read access at the time of their addition.", // TODO Source message changed - Revise the translation - "comcol-role.edit.bitstream_read.description": "Správci komunit mohou vytvářet dílčí komunity nebo kolekce a spravovat nebo přidělovat správu těmto dílčím komunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do libovolných dílčích kolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", + "comcol-role.edit.bitstream_read.description": "Správci komunit mohou vytvářet podkomunity nebo kolekce a spravovat nebo přidělovat správu těmto podkomunitám nebo kolekcím. Kromě toho rozhodují o tom, kdo může odesílat záznamy do libovolných podkolekcí, upravovat metadata záznamů (po odeslání) a přidávat (mapovat) existující záznamy z jiných kolekcí (na základě oprávnění).", // "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", "comcol-role.edit.bitstream_read.anonymous-group": "Výchozí čtení pro příchozí soubory je v současné době nastaveno na hodnotu Anonymní.", @@ -2481,7 +2481,7 @@ "community.page.news": "Novinky", // "community.all-lists.head": "Subcommunities and Collections", - "community.all-lists.head": "Dílčí komunity a kolekce", + "community.all-lists.head": "Podkomunity a kolekce", // "community.search.results.head": "Search Results", // TODO New key - Add a translation @@ -2927,10 +2927,10 @@ "error.invalid-search-query": "Vyhledávací dotaz není platný. Další informace o této chybě naleznete v osvědčených postupech Solr query syntax.", // "error.sub-collections": "Error fetching sub-collections", - "error.sub-collections": "Chyba při načítání dílčích kolekcí", + "error.sub-collections": "Chyba při načítání podkolekcí", // "error.sub-communities": "Error fetching sub-communities", - "error.sub-communities": "Chyba při načítání dílčích komunit", + "error.sub-communities": "Chyba při načítání podkomunit", // "error.submission.sections.init-form-error": "An error occurred during section initialize, please check your input-form configuration. Details are below :

    ", "error.submission.sections.init-form-error": "Při inicializaci sekce došlo k chybě, zkontrolujte prosím konfiguraci vstupního formuláře. Podrobnosti jsou uvedeny níže :

    ", @@ -4985,10 +4985,10 @@ "loading.search-results": "Načítají se výsledky vyhledávání...", // "loading.sub-collections": "Loading sub-collections...", - "loading.sub-collections": "Načítají se dílčí kolekce...", + "loading.sub-collections": "Načítají se podkolekce...", // "loading.sub-communities": "Loading sub-communities...", - "loading.sub-communities": "Načítají se dílčí komunity...", + "loading.sub-communities": "Načítají se podkomunity...", // "loading.top-level-communities": "Loading top-level communities...", "loading.top-level-communities": "Načítají se komunity nejvyšší úrovně...", From 71627d8abf254b1f95b4730b83f5da2038cf5169 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Fri, 11 Oct 2024 13:37:24 +0200 Subject: [PATCH 356/822] Fixed small cs localization mistakes (cherry picked from commit 680d6c94166266d6195f13b92e3be916917ae8c0) --- src/assets/i18n/cs.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 09dd023e8d5..466e3475bfb 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -2939,7 +2939,7 @@ "error.top-level-communities": "Chyba při načítání komunit nejvyšší úrovně", // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", - "error.validation.license.notgranted": "Bez udělení licence nelze záznam dokončit. Pokud v tuto chvíli nemůžete licenci udělit, uložte svou práci a vraťte se k příspěveku později nebo jej smažte.", + "error.validation.license.notgranted": "Bez udělení licence nelze záznam dokončit. Pokud v tuto chvíli nemůžete licenci udělit, uložte svou práci a vraťte se k příspěvku později nebo jej smažte.", // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", "error.validation.pattern": "Toto zadání je omezeno aktuálním vzorcem: {{ pattern }}.", @@ -4934,7 +4934,7 @@ "iiif.page.doi": "Trvalý odkaz: ", // "iiif.page.issue": "Issue: ", - "iiif.page.issue": "Číslo:", + "iiif.page.issue": "Číslo: ", // "iiif.page.description": "Description: ", "iiif.page.description": "Popis: ", From 15afbc2dc9b9d5a4050c35374cc367f34ea6e090 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Mon, 4 Nov 2024 14:37:04 +0100 Subject: [PATCH 357/822] Updated messages for the 'supervised' and 'claim' sentenses (cherry picked from commit 1aef6ce1d623ac8f0a52dcf8086847996a2d0180) --- src/assets/i18n/cs.json5 | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index 466e3475bfb..f06db668a39 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -4221,10 +4221,10 @@ "workflow-item.search.result.notification.deleted.failure": "Při mazání příkazu supervize \"{{name}}\" došlo k chybě", // "workflow-item.search.result.list.element.supervised-by": "Supervised by:", - "workflow-item.search.result.list.element.supervised-by": "Supervizován:", + "workflow-item.search.result.list.element.supervised-by": "Pod dohledem:", // "workflow-item.search.result.list.element.supervised.remove-tooltip": "Remove supervision group", - "workflow-item.search.result.list.element.supervised.remove-tooltip": "Odebrat skupinu supervize", + "workflow-item.search.result.list.element.supervised.remove-tooltip": "Odebrat skupinu dohledu", // "confidence.indicator.help-text.accepted": "This authority value has been confirmed as accurate by an interactive user", // TODO New key - Add a translation @@ -4380,10 +4380,10 @@ "item.page.version.hasDraft": "Nová verze nemůže být vytvořena, protože v historii verzí už další rozpracovaná verze existuje.", // "item.page.claim.button": "Claim", - "item.page.claim.button": "Prohlásit", + "item.page.claim.button": "Převzít", // "item.page.claim.tooltip": "Claim this item as profile", - "item.page.claim.tooltip": "Prohlásit tento záznam za profilovou", + "item.page.claim.tooltip": "Prohlásit tento záznam za profil", // "item.page.image.alt.ROR": "ROR logo", // TODO New key - Add a translation @@ -5414,7 +5414,7 @@ "mydspace.show.workspace": "Vaše záznamy", // "mydspace.show.supervisedWorkspace": "Supervised items", - "mydspace.show.supervisedWorkspace": "Zkontrolované záznamy", + "mydspace.show.supervisedWorkspace": "Záznamy pod dohledem", // "mydspace.status.mydspaceArchived": "Archived", "mydspace.status.mydspaceArchived": "Archivováno", @@ -6922,7 +6922,7 @@ "search.filters.applied.f.birthDate.min": "Datum narození od", // "search.filters.applied.f.supervisedBy": "Supervised by", - "search.filters.applied.f.supervisedBy": "Zkontrolováno", + "search.filters.applied.f.supervisedBy": "Pod dohledem", // "search.filters.applied.f.withdrawn": "Withdrawn", "search.filters.applied.f.withdrawn": "Vyřazeno", @@ -7221,8 +7221,7 @@ "search.filters.filter.supervisedBy.placeholder": "Supervised By", // "search.filters.filter.supervisedBy.label": "Search Supervised By", - // TODO New key - Add a translation - "search.filters.filter.supervisedBy.label": "Search Supervised By", + "search.filters.filter.supervisedBy.label": "Hledat pod dohledem", // "search.filters.entityType.JournalIssue": "Journal Issue", "search.filters.entityType.JournalIssue": "Číslo časopisu", @@ -8924,7 +8923,7 @@ "virtual-metadata.delete-relationship.modal-head": "Vyberte záznamy, pro které chcete uložit virtuální metadata jako skutečná metadata", // "supervisedWorkspace.search.results.head": "Supervised Items", - "supervisedWorkspace.search.results.head": "Zkontrolované záznamy", + "supervisedWorkspace.search.results.head": "Záznamy pod dohledem", // "workspace.search.results.head": "Your submissions", "workspace.search.results.head": "Moje záznamy", From e7da6e42f70e00f0220c4dc50ba84fbcd450be36 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Fri, 8 Nov 2024 15:24:06 +0100 Subject: [PATCH 358/822] Updated supervised by messages following NTK suggestions (cherry picked from commit d819cf43968665c20870ee16a1620e744dfbd821) --- src/assets/i18n/cs.json5 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index f06db668a39..866660f513f 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -4221,10 +4221,10 @@ "workflow-item.search.result.notification.deleted.failure": "Při mazání příkazu supervize \"{{name}}\" došlo k chybě", // "workflow-item.search.result.list.element.supervised-by": "Supervised by:", - "workflow-item.search.result.list.element.supervised-by": "Pod dohledem:", + "workflow-item.search.result.list.element.supervised-by": "Dohlížející autorita:", // "workflow-item.search.result.list.element.supervised.remove-tooltip": "Remove supervision group", - "workflow-item.search.result.list.element.supervised.remove-tooltip": "Odebrat skupinu dohledu", + "workflow-item.search.result.list.element.supervised.remove-tooltip": "Odebrat dohlížející autoritu", // "confidence.indicator.help-text.accepted": "This authority value has been confirmed as accurate by an interactive user", // TODO New key - Add a translation @@ -7221,7 +7221,7 @@ "search.filters.filter.supervisedBy.placeholder": "Supervised By", // "search.filters.filter.supervisedBy.label": "Search Supervised By", - "search.filters.filter.supervisedBy.label": "Hledat pod dohledem", + "search.filters.filter.supervisedBy.label": "Hledat dohlížející autoritu", // "search.filters.entityType.JournalIssue": "Journal Issue", "search.filters.entityType.JournalIssue": "Číslo časopisu", From 898b5fa634e4d09f7c366ceaa833a9af32d5dd47 Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Mon, 11 Nov 2024 13:57:43 -0500 Subject: [PATCH 359/822] French translations for COAR Notify LDN Service Contains all translations in french for new DSpace 8 COAR Notify module. (cherry picked from commit 20263073c68b727932844c6037bcf2602a5cab2f) --- src/assets/i18n/fr.json5 | 1132 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1132 insertions(+) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index 2ea96ad58db..d334789f7ec 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -7149,6 +7149,1138 @@ // "access-control-option-end-date-note": "Select the date until which the related access condition is applied", "access-control-option-end-date-note": "Sélectionnez la date jusqu'à laquelle la condition d'accès liée est appliquée", + //"vocabulary-treeview.search.form.add": "Add", + "vocabulary-treeview.search.form.add": "Ajouter", + //"admin.notifications.publicationclaim.breadcrumbs": "Publication Claim", + "admin.notifications.publicationclaim.breadcrumbs": "Réclamer une publication", + + //"admin.notifications.publicationclaim.page.title": "Publication Claim", + "admin.notifications.publicationclaim.page.title": "Réclamer une publication", + + //"coar-notify-support.title": "COAR Notify Protocol", + "coar-notify-support.title": "Protocole COAR Notify", + + //"coar-notify-support-title.content": "Here, we fully support the COAR Notify protocol, which is designed to enhance the communication between repositories. To learn more about the COAR Notify protocol, visit the COAR Notify website.", + "coar-notify-support-title.content": "Le protocole COAR Notify est destiné à améliorer la communication entre dépôts. Afin d'en savoir plus sur ce protocole, consulter le site web COAR Notify.", + + //"coar-notify-support.ldn-inbox.title": "LDN InBox", + "coar-notify-support.ldn-inbox.title": "Boîte aux lettres LDN", + + //"coar-notify-support.ldn-inbox.content": "For your convenience, our LDN (Linked Data Notifications) InBox is easily accessible at {{ ldnInboxUrl }}. The LDN InBox enables seamless communication and data exchange, ensuring efficient and effective collaboration.", + "coar-notify-support.ldn-inbox.content": "La boîte aux lettres LDN (Linked Data Notifications) est accessible à l'adresse {{ ldnInboxUrl }}. La boîte aux lettres LDN permet la communication et l'échange de données afin de garantir une collaboration effective et efficiente.", + + //"coar-notify-support.message-moderation.title": "Message Moderation", + "coar-notify-support.message-moderation.title": "Modération des messages", + + //"coar-notify-support.message-moderation.content": "To ensure a secure and productive environment, all incoming LDN messages are moderated. If you are planning to exchange information with us, kindly reach out via our dedicated", + "coar-notify-support.message-moderation.content": "Afin d'assurer un environnement sécuritaire et productif, tous les messages LDN entrants font l'objet d'une modération. Si vous envisagez d'échanger de l'information avec nous, veuillez nous contacter en utilisant notre", + + //"coar-notify-support.message-moderation.feedback-form": " Feedback form.", + "coar-notify-support.message-moderation.feedback-form": " formulaire.", + + //"service.overview.delete.header": "Delete Service", + "service.overview.delete.header": "Supprimer le service", + + //"ldn-registered-services.title": "Registered Services", + "ldn-registered-services.title": "Services enregistrés", + + //"ldn-registered-services.table.name": "Name", + "ldn-registered-services.table.name": "Nom", + + //"ldn-registered-services.table.description": "Description", + "ldn-registered-services.table.description": "Description", + + //"ldn-registered-services.table.status": "Status", + "ldn-registered-services.table.status": "Statut", + + //"ldn-registered-services.table.action": "Action", + "ldn-registered-services.table.action": "Action", + + //"ldn-registered-services.new": "NEW", + "ldn-registered-services.new": "NOUVEAU", + + //"ldn-registered-services.new.breadcrumbs": "Registered Services", + "ldn-registered-services.new.breadcrumbs": "Services enregistrés", + + //"ldn-service.overview.table.enabled": "Enabled", + "ldn-service.overview.table.enabled": "Activé", + + //"ldn-service.overview.table.disabled": "Disabled", + "ldn-service.overview.table.disabled": "Désactivé", + + //"ldn-service.overview.table.clickToEnable": "Click to enable", + "ldn-service.overview.table.clickToEnable": "Cliquer pour activer", + + //"ldn-service.overview.table.clickToDisable": "Click to disable", + "ldn-service.overview.table.clickToDisable": "Cliquer pour désactiver", + + //"ldn-edit-registered-service.title": "Edit Service", + "ldn-edit-registered-service.title": "Éditer le service", + + //"ldn-create-service.title": "Create service", + "ldn-create-service.title": "Créer un service", + + //"service.overview.create.modal": "Create Service", + "service.overview.create.modal": "Créer un service", + + //"service.overview.create.body": "Please confirm the creation of this service.", + "service.overview.create.body": "S'il vous plaît, confirmer la création de ce service.", + + //"ldn-service-status": "Status", + "ldn-service-status": "Statut", + + //"service.confirm.create": "Create", + "service.confirm.create": "Créer", + + //"service.refuse.create": "Cancel", + "service.refuse.create": "Annuler", + + //"ldn-register-new-service.title": "Register a new service", + "ldn-register-new-service.title": "Enregistrer un nouveau service", + + //"ldn-new-service.form.label.submit": "Save", + "ldn-new-service.form.label.submit": "Sauvegarder", + + //"ldn-new-service.form.label.name": "Name", + "ldn-new-service.form.label.name": "Nom", + + //"ldn-new-service.form.label.description": "Description", + "ldn-new-service.form.label.description": "Description", + + //"ldn-new-service.form.label.url": "Service URL", + "ldn-new-service.form.label.url": "URL du service", + + //"ldn-new-service.form.label.ip-range": "Service IP range", + "ldn-new-service.form.label.ip-range": "Intervalle IP du service", + + //"ldn-new-service.form.label.score": "Level of trust", + "ldn-new-service.form.label.score": "Niveau de confiance", + + //"ldn-new-service.form.label.ldnUrl": "LDN Inbox URL", + "ldn-new-service.form.label.ldnUrl": "URL de la boîte aux lettres LDN", + + //"ldn-new-service.form.placeholder.name": "Please provide service name", + "ldn-new-service.form.placeholder.name": "S'il vous plaît, fournissez le nom du service", + + //"ldn-new-service.form.placeholder.description": "Please provide a description regarding your service", + "ldn-new-service.form.placeholder.description": "S'il vous plaît, décrivez votre service", + + //"ldn-new-service.form.placeholder.url": "Please input the URL for users to check out more information about the service", + "ldn-new-service.form.placeholder.url": "S'il vous plaît, fournissez l'URL pour les usagers afin qu'ils puissent consulter plus d'information sur le service.", + + //"ldn-new-service.form.placeholder.lowerIp": "IPv4 range lower bound", + "ldn-new-service.form.placeholder.lowerIp": "Limite inférieure de l'intervalle IPv4", + + //"ldn-new-service.form.placeholder.upperIp": "IPv4 range upper bound", + "ldn-new-service.form.placeholder.upperIp": "Limite supérieure de l'intervalle IPv4", + + //"ldn-new-service.form.placeholder.ldnUrl": "Please specify the URL of the LDN Inbox", + "ldn-new-service.form.placeholder.ldnUrl": "S'il vous plaît, spécifiez l'URL de la boîte aux lettres LDN", + + //"ldn-new-service.form.placeholder.score": "Please enter a value between 0 and 1. Use the “.” as decimal separator", + "ldn-new-service.form.placeholder.score": "S'il vous plaît, saisissez une valeur entre 0 et 1. Utilisez le “.” comme séparateur de décimale.", + + //"ldn-service.form.label.placeholder.default-select": "Select a pattern", + "ldn-service.form.label.placeholder.default-select": "Sélectionnez un modèle", + + //"ldn-service.form.pattern.ack-accept.label": "Acknowledge and Accept", + "ldn-service.form.pattern.ack-accept.label": "Accuser réception et accepter", + + //"ldn-service.form.pattern.ack-accept.description": "This pattern is used to acknowledge and accept a request (offer). It implies an intention to act on the request.", + "ldn-service.form.pattern.ack-accept.description": "Ce modèle est utilisé pour accuser réception et accepter une requête (offre). Il implique une intention de donner suite à la requête.", + + //"ldn-service.form.pattern.ack-accept.category": "Acknowledgements", + "ldn-service.form.pattern.ack-accept.category": "Accusés de réception", + + //"ldn-service.form.pattern.ack-reject.label": "Acknowledge and Reject", + "ldn-service.form.pattern.ack-reject.label": "Accuser réception et refuser", + + //"ldn-service.form.pattern.ack-reject.description": "This pattern is used to acknowledge and reject a request (offer). It signifies no further action regarding the request.", + "ldn-service.form.pattern.ack-reject.description": "Ce modèle est utilisé pour accuser réception et refuser une requête (offre). Il signifie qu'aucune action supplémentaire n'est nécessaire pour la requête.", + + //"ldn-service.form.pattern.ack-reject.category": "Acknowledgements", + "ldn-service.form.pattern.ack-reject.category": "Accusés de réception", + + //"ldn-service.form.pattern.ack-tentative-accept.label": "Acknowledge and Tentatively Accept", + "ldn-service.form.pattern.ack-tentative-accept.label": "Accuser réception et accepter provisoirement", + + //"ldn-service.form.pattern.ack-tentative-accept.description": "This pattern is used to acknowledge and tentatively accept a request (offer). It implies an intention to act, which may change.", + "ldn-service.form.pattern.ack-tentative-accept.description": "Ce modèle est utilisé pour accuser réception et accepter provisoirement une requête (offre). Il implique une intention d'agir qui pourrait changer.", + + //"ldn-service.form.pattern.ack-tentative-accept.category": "Acknowledgements", + "ldn-service.form.pattern.ack-tentative-accept.category": "Accusés de réception", + + //"ldn-service.form.pattern.ack-tentative-reject.label": "Acknowledge and Tentatively Reject", + "ldn-service.form.pattern.ack-tentative-reject.label": "Accuser réception et refuser provisoirement", + + //"ldn-service.form.pattern.ack-tentative-reject.description": "This pattern is used to acknowledge and tentatively reject a request (offer). It signifies no further action, subject to change.", + "ldn-service.form.pattern.ack-tentative-reject.description": "Ce modèle est utilisé pour accuser réception et refuser provisoirement une requête (offre). Il implique qu'aucune action supplémentaire n'est nécessaire sous réserve de modification.", + + //"ldn-service.form.pattern.ack-tentative-reject.category": "Acknowledgements", + "ldn-service.form.pattern.ack-tentative-reject.category": "Accusés de réception", + + //"ldn-service.form.pattern.announce-endorsement.label": "Announce Endorsement", + "ldn-service.form.pattern.announce-endorsement.label": "Annocer l'approbation", + + //"ldn-service.form.pattern.announce-endorsement.description": "This pattern is used to announce the existence of an endorsement, referencing the endorsed resource.", + "ldn-service.form.pattern.announce-endorsement.description": "Ce modèle est utilisé pour annoncer l'existence d'une approbation, référençant la ressource approuvée.", + + //"ldn-service.form.pattern.announce-endorsement.category": "Announcements", + "ldn-service.form.pattern.announce-endorsement.category": "Annonces", + + //"ldn-service.form.pattern.announce-ingest.label": "Announce Ingest", + "ldn-service.form.pattern.announce-ingest.label": "Annoncer l'ingestion", + + //"ldn-service.form.pattern.announce-ingest.description": "This pattern is used to announce that a resource has been ingested.", + "ldn-service.form.pattern.announce-ingest.description": "Ce modèle est utilisé pour annoncer qu'une ressource a été ingérée.", + + //"ldn-service.form.pattern.announce-ingest.category": "Announcements", + "ldn-service.form.pattern.announce-ingest.category": "Annonces", + + //"ldn-service.form.pattern.announce-relationship.label": "Announce Relationship", + "ldn-service.form.pattern.announce-relationship.label": "Annoncer la relation", + + //"ldn-service.form.pattern.announce-relationship.description": "This pattern is used to announce a relationship between two resources.", + "ldn-service.form.pattern.announce-relationship.description": "Ce modèle est utilisé pour annoncer une relation entre 2 ressources.", + + //"ldn-service.form.pattern.announce-relationship.category": "Announcements", + "ldn-service.form.pattern.announce-relationship.category": "Annonces", + + //"ldn-service.form.pattern.announce-review.label": "Announce Review", + "ldn-service.form.pattern.announce-review.label": "Annoncer l'évaluation", + + //"ldn-service.form.pattern.announce-review.description": "This pattern is used to announce the existence of a review, referencing the reviewed resource.", + "ldn-service.form.pattern.announce-review.description": "Ce modèle est utilisé pour annoncer l'existence d'une évaluation, référencant la ressource évaluée.", + + //"ldn-service.form.pattern.announce-review.category": "Announcements", + "ldn-service.form.pattern.announce-review.category": "Annonces", + + //"ldn-service.form.pattern.announce-service-result.label": "Announce Service Result", + "ldn-service.form.pattern.announce-service-result.label": "Annoncer le résultat de service", + + //"ldn-service.form.pattern.announce-service-result.description": "This pattern is used to announce the existence of a 'service result', referencing the relevant resource.", + "ldn-service.form.pattern.announce-service-result.description": "Ce modèle est utilisé pour annoncer l'existence d'un 'résultat de service', référençant la ressource pertinente.", + + //"ldn-service.form.pattern.announce-service-result.category": "Announcements", + "ldn-service.form.pattern.announce-service-result.category": "Annonces", + + //"ldn-service.form.pattern.request-endorsement.label": "Request Endorsement", + "ldn-service.form.pattern.request-endorsement.label": "Approbation de la requête", + + //"ldn-service.form.pattern.request-endorsement.description": "This pattern is used to request endorsement of a resource owned by the origin system.", + "ldn-service.form.pattern.request-endorsement.description": "Ce modèle est utilisé pour demander l'approbation d'une ressource appartenant au système d'origine.", + + //"ldn-service.form.pattern.request-endorsement.category": "Requests", + "ldn-service.form.pattern.request-endorsement.category": "Requêtes", + + //"ldn-service.form.pattern.request-ingest.label": "Request Ingest", + "ldn-service.form.pattern.request-ingest.label": "Demander l'ingestion", + + //"ldn-service.form.pattern.request-ingest.description": "This pattern is used to request that the target system ingest a resource.", + "ldn-service.form.pattern.request-ingest.description": "Ce modèle est utilisé pour demander au système cible d'ingérer une ressource.", + + //"ldn-service.form.pattern.request-ingest.category": "Requests", + "ldn-service.form.pattern.request-ingest.category": "Requêtes", + + //"ldn-service.form.pattern.request-review.label": "Request Review", + "ldn-service.form.pattern.request-review.label": "Requête d'évaluation", + + //"ldn-service.form.pattern.request-review.description": "This pattern is used to request a review of a resource owned by the origin system.", + "ldn-service.form.pattern.request-review.description": "Ce modèle est utilisé pour demander l'évaluation d'une ressource appartenant au système d'origine.", + + //"ldn-service.form.pattern.request-review.category": "Requests", + "ldn-service.form.pattern.request-review.category": "Requêtes", + + //"ldn-service.form.pattern.undo-offer.label": "Undo Offer", + "ldn-service.form.pattern.undo-offer.label": "Retirer l'offre", + + //"ldn-service.form.pattern.undo-offer.description": "This pattern is used to undo (retract) an offer previously made.", + "ldn-service.form.pattern.undo-offer.description": "Ce modèle est utilisé pour retirer une offre faite précédemment.", + + //"ldn-service.form.pattern.undo-offer.category": "Undo", + "ldn-service.form.pattern.undo-offer.category": "Retirer", + + //"ldn-new-service.form.label.placeholder.selectedItemFilter": "No Item Filter Selected", + "ldn-new-service.form.label.placeholder.selectedItemFilter": "Aucun filtre d'Item sélectionné", + + //"ldn-new-service.form.label.ItemFilter": "Item Filter", + "ldn-new-service.form.label.ItemFilter": "Filtre d'Item", + + //"ldn-new-service.form.label.automatic": "Automatic", + "ldn-new-service.form.label.automatic": "Automatique", + + //"ldn-new-service.form.error.name": "Name is required", + "ldn-new-service.form.error.name": "Le nom est obligatoire", + + //"ldn-new-service.form.error.url": "URL is required", + "ldn-new-service.form.error.url": "L'URL est obligatoire", + + //"ldn-new-service.form.error.ipRange": "Please enter a valid IP range", + "ldn-new-service.form.error.ipRange": "S'il vous plaît, saisissez un intervalle IP valide.", + + //"ldn-new-service.form.hint.ipRange": "Please enter a valid IpV4 in both range bounds (note: for single IP, please enter the same value in both fields)", + "ldn-new-service.form.hint.ipRange": "S'il vous plaît, saisissez une adresse IpV4 valide pour chaque limite de l'intervalle (note: pour une adresse IP unique, entrez les mêmes valeurs dans les 2 champs).", + + //"ldn-new-service.form.error.ldnurl": "LDN URL is required", + "ldn-new-service.form.error.ldnurl": "L'URL LDN est obligatoire.", + + //"ldn-new-service.form.error.patterns": "At least a pattern is required", + "ldn-new-service.form.error.patterns": "Au moins un modèle est requis.", + + //"ldn-new-service.form.error.score": "Please enter a valid score (between 0 and 1). Use the “.” as decimal separator", + "ldn-new-service.form.error.score": "S'il vous plaît, saisissez une note valide (entre 0 et 1). Utilisez le “.” comme séparateur de décimale.", + + //"ldn-new-service.form.label.inboundPattern": "Supported Pattern", + "ldn-new-service.form.label.inboundPattern": "Modèle supporté", + + //"ldn-new-service.form.label.addPattern": "+ Add more", + "ldn-new-service.form.label.addPattern": "+ Ajouter", + + //"ldn-new-service.form.label.removeItemFilter": "Remove", + "ldn-new-service.form.label.removeItemFilter": "Supprimer", + + //"ldn-register-new-service.breadcrumbs": "New Service", + "ldn-register-new-service.breadcrumbs": "Nouveau service", + + //"service.overview.delete.body": "Are you sure you want to delete this service?", + "service.overview.delete.body": "Êtes-vous sûr de vouloir supprimer ce service ?", + + //"service.overview.edit.body": "Do you confirm the changes?", + "service.overview.edit.body": "Confirmez-vous les changements ?", + + //"service.overview.edit.modal": "Edit Service", + "service.overview.edit.modal": "Modifier le service", + + //"service.detail.update": "Confirm", + "service.detail.update": "Confirmer", + + //"service.detail.return": "Cancel", + "service.detail.return": "Annuler", + + //"service.overview.reset-form.body": "Are you sure you want to discard the changes and leave?", + "service.overview.reset-form.body": "Êtes-vous sûr de vouloir ignorer les changements et de quitter ?", + + //"service.overview.reset-form.modal": "Discard Changes", + "service.overview.reset-form.modal": "Ignorer les changements", + + //"service.overview.reset-form.reset-confirm": "Discard", + "service.overview.reset-form.reset-confirm": "Ignorer", + + //"admin.registries.services-formats.modify.success.head": "Successful Edit", + "admin.registries.services-formats.modify.success.head": "Modification réussie", + + //"admin.registries.services-formats.modify.success.content": "The service has been edited", + "admin.registries.services-formats.modify.success.content": "Le service a été modifié.", + + //"admin.registries.services-formats.modify.failure.head": "Failed Edit", + "admin.registries.services-formats.modify.failure.head": "La modification a échoué.", + + //"admin.registries.services-formats.modify.failure.content": "The service has not been edited", + "admin.registries.services-formats.modify.failure.content": "Le service a été modifié.", + + //"ldn-service-notification.created.success.title": "Successful Create", + "ldn-service-notification.created.success.title": "Création réussie", + + //"ldn-service-notification.created.success.body": "The service has been created", + "ldn-service-notification.created.success.body": "Le service a été crée.", + + //"ldn-service-notification.created.failure.title": "Failed Create", + "ldn-service-notification.created.failure.title": "Échec de la création", + + //"ldn-service-notification.created.failure.body": "The service has not been created", + "ldn-service-notification.created.failure.body": "Le service n'a pas été crée.", + + //"ldn-service-notification.created.warning.title": "Please select at least one Inbound Pattern", + "ldn-service-notification.created.warning.title": "Sélectionnez au moins un modèle entrant.", + + //"ldn-enable-service.notification.success.title": "Successful status updated", + "ldn-enable-service.notification.success.title": "Mise à jour du statut réussie", + + //"ldn-enable-service.notification.success.content": "The service status has been updated", + "ldn-enable-service.notification.success.content": "Le statut du service a été mis à jour.", + + //"ldn-service-delete.notification.success.title": "Successful Deletion", + "ldn-service-delete.notification.success.title": "Suppression réussie", + + //"ldn-service-delete.notification.success.content": "The service has been deleted", + "ldn-service-delete.notification.success.content": "Le service a été supprimé.", + + //"ldn-service-delete.notification.error.title": "Failed Deletion", + "ldn-service-delete.notification.error.title": "Échec de la suppression", + + //"ldn-service-delete.notification.error.content": "The service has not been deleted", + "ldn-service-delete.notification.error.content": "Le service n'a pas été supprimé.", + + //"service.overview.reset-form.reset-return": "Cancel", + "service.overview.reset-form.reset-return": "Annuler", + + //"service.overview.delete": "Delete service", + "service.overview.delete": "Supprimer le service", + + //"ldn-edit-service.title": "Edit service", + "ldn-edit-service.title": "Modifier le service", + + //"ldn-edit-service.form.label.name": "Name", + "ldn-edit-service.form.label.name": "Nom", + + //"ldn-edit-service.form.label.description": "Description", + "ldn-edit-service.form.label.description": "Description", + + //"ldn-edit-service.form.label.url": "Service URL", + "ldn-edit-service.form.label.url": "URL du service", + + //"ldn-edit-service.form.label.ldnUrl": "LDN Inbox URL", + "ldn-edit-service.form.label.ldnUrl": "URL de la boîte aux lettres LDN", + + //"ldn-edit-service.form.label.inboundPattern": "Inbound Pattern", + "ldn-edit-service.form.label.inboundPattern": "Modèle entrant", + + //"ldn-edit-service.form.label.noInboundPatternSelected": "No Inbound Pattern", + "ldn-edit-service.form.label.noInboundPatternSelected": "Aucun modèle entrant", + + //"ldn-edit-service.form.label.selectedItemFilter": "Selected Item Filter", + "ldn-edit-service.form.label.selectedItemFilter": "Filtre d'Item sélectionné", + + //"ldn-edit-service.form.label.selectItemFilter": "No Item Filter", + "ldn-edit-service.form.label.selectItemFilter": "Aucun filtre d'Item", + + //"ldn-edit-service.form.label.automatic": "Automatic", + "ldn-edit-service.form.label.automatic": "Automatique", + + //"ldn-edit-service.form.label.addInboundPattern": "+ Add more", + "ldn-edit-service.form.label.addInboundPattern": "+ Ajouter", + + //"ldn-edit-service.form.label.submit": "Save", + "ldn-edit-service.form.label.submit": "Sauvegarder", + + //"ldn-edit-service.breadcrumbs": "Edit Service", + "ldn-edit-service.breadcrumbs": "Éditer le service", + + //"ldn-service.control-constaint-select-none": "Select none", + "ldn-service.control-constaint-select-none": "Ne rien sélectionner", + + //"ldn-register-new-service.notification.error.title": "Error", + "ldn-register-new-service.notification.error.title": "Erreur", + + //"ldn-register-new-service.notification.error.content": "An error occurred while creating this process", + "ldn-register-new-service.notification.error.content": "Une erreur s'est produite lors de la création de ce processus.", + + //"ldn-register-new-service.notification.success.title": "Success", + "ldn-register-new-service.notification.success.title": "Succès", + + //"ldn-register-new-service.notification.success.content": "The process was successfully created", + "ldn-register-new-service.notification.success.content": "Le processus a été créé.", + + //"submission.sections.notify.info": "The selected service is compatible with the item according to its current status. {{ service.name }}: {{ service.description }}", + "submission.sections.notify.info": "Le service sélectionné est compatible avec l'Item d'après son statut actuel. {{ service.name }}: {{ service.description }}", + + //"item.page.endorsement": "Endorsement", + "item.page.endorsement": "Approbation", + + //"item.page.review": "Review", + "item.page.review": "Évaluation", + + //"item.page.referenced": "Referenced By", + "item.page.referenced": "Référencé par", + + //"item.page.supplemented": "Supplemented By", + "item.page.supplemented": "Complété par", + + //"menu.section.icon.ldn_services": "LDN Services overview", + "menu.section.icon.ldn_services": "Aperçu des services LDN", + + //"menu.section.services": "LDN Services", + "menu.section.services": "Services LDN", + + //"menu.section.services_new": "LDN Service", + "menu.section.services_new": "Service LDN", + + //"quality-assurance.topics.description-with-target": "Below you can see all the topics received from the subscriptions to {{source}} in regards to the", + "quality-assurance.topics.description-with-target": "Vous pouvez consulter ci-dessous tous les sujets reçus de l'abonnement à {{source}} en ce qui concerne", + + //"quality-assurance.events.description": "Below the list of all the suggestions for the selected topic {{topic}}, related to {{source}}.", + "quality-assurance.events.description": "En dessous de la liste des suggestions pour le sujet sélectionné {{topic}}, en relation avec {{source}}.", + + //"quality-assurance.events.description-with-topic-and-target": "Below the list of all the suggestions for the selected topic {{topic}}, related to {{source}} and ", + "quality-assurance.events.description-with-topic-and-target": "En dessous de la liste des suggestions pour le sujet sélectionné {{topic}}, en relation avec {{source}} and ", + + //"quality-assurance.event.table.event.message.serviceUrl": "Service URL:", + "quality-assurance.event.table.event.message.serviceUrl": "URL du service :", + + //"quality-assurance.event.table.event.message.link": "Link:", + "quality-assurance.event.table.event.message.link": "Lien :", + + //"service.detail.delete.cancel": "Cancel", + "service.detail.delete.cancel": "Annuler", + + //"service.detail.delete.button": "Delete service", + "service.detail.delete.button": "Supprimer le service", + + //"service.detail.delete.header": "Delete service", + "service.detail.delete.header": "Supprimer le service", + + //"service.detail.delete.body": "Are you sure you want to delete the current service?", + "service.detail.delete.body": "Êtes-vous sûr de vouloir supprimer ce service ?", + + //"service.detail.delete.confirm": "Delete service", + "service.detail.delete.confirm": "Supprimer le service", + + //"service.detail.delete.success": "The service was successfully deleted.", + "service.detail.delete.success": "Le service a été supprimé.", + + //"service.detail.delete.error": "Something went wrong when deleting the service", + "service.detail.delete.error": "Une erreure s'est produite lors de la suppression du service.", + + //"service.overview.table.id": "Services ID", + "service.overview.table.id": "Identifiants des services", + + //"service.overview.table.name": "Name", + "service.overview.table.name": "Nom", + + //"service.overview.table.start": "Start time (UTC)", + "service.overview.table.start": "Heure de début (UTC)", + + //"service.overview.table.status": "Status", + "service.overview.table.status": "Statut", + + //"service.overview.table.user": "User", + "service.overview.table.user": "Utilisateur", + + //"service.overview.title": "Services Overview", + "service.overview.title": "Aperçu des services", + + //"service.overview.breadcrumbs": "Services Overview", + "service.overview.breadcrumbs": "Aperçu des services", + + //"service.overview.table.actions": "Actions", + "service.overview.table.actions": "Actions", + + //"service.overview.table.description": "Description", + "service.overview.table.description": "Description", + + //"submission.sections.submit.progressbar.coarnotify": "COAR Notify", + "submission.sections.submit.progressbar.coarnotify": "COAR Notify", + + //"submission.section.section-coar-notify.control.request-review.label": "You can request a review to one of the following services", + "submission.section.section-coar-notify.control.request-review.label": "Vous pouvez demander une évaluation à l'un des services suivants", + + //"submission.section.section-coar-notify.control.request-endorsement.label": "You can request an Endorsement to one of the following overlay journals", + "submission.section.section-coar-notify.control.request-endorsement.label": "Vous pouvez demander une approbation à l'une des épirevues suivantes", + + //"submission.section.section-coar-notify.control.request-ingest.label": "You can request to ingest a copy of your submission to one of the following services", + "submission.section.section-coar-notify.control.request-ingest.label": "Vous pouvez demander à ce qu'une copie de votre soumission soit ingérée par l'un des services suivants", + + //"submission.section.section-coar-notify.dropdown.no-data": "No data available", + "submission.section.section-coar-notify.dropdown.no-data": "Aucune donnée disponible", + + //"submission.section.section-coar-notify.dropdown.select-none": "Select none", + "submission.section.section-coar-notify.dropdown.select-none": "Ne rien sélectionner", + + //"submission.section.section-coar-notify.small.notification": "Select a service for {{ pattern }} of this item", + "submission.section.section-coar-notify.small.notification": "Sélectionner un service pour {{ pattern }} pour cet Item", + + //"submission.section.section-coar-notify.selection.description": "Selected service's description:", + "submission.section.section-coar-notify.selection.description": "Description du service sélectionné :", + + //"submission.section.section-coar-notify.selection.no-description": "No further information is available", + "submission.section.section-coar-notify.selection.no-description": "Aucune autre information n'est disponible", + + //"submission.section.section-coar-notify.notification.error": "The selected service is not suitable for the current item. Please check the description for details about which record can be managed by this service.", + "submission.section.section-coar-notify.notification.error": "Le service sélectionné n'est pas approprié pour cet Item. Consulter la description afin de savoir quel Item est approprié pour ce service.", + + //"submission.section.section-coar-notify.info.no-pattern": "No configurable patterns found.", + "submission.section.section-coar-notify.info.no-pattern": "Aucun modèle configurable n'a été trouvé.", + + //"error.validation.coarnotify.invalidfilter": "Invalid filter, try to select another service or none.", + "error.validation.coarnotify.invalidfilter": "Filtre invalide, sélectionnez un autre service ou aucun service.", + + //"request-status-alert-box.accepted": "The requested {{ offerType }} for {{ serviceName }} has been taken in charge.", + "request-status-alert-box.accepted": "Le {{ offerType }} demandé pour {{ serviceName }} a été pris en charge.", + + //"request-status-alert-box.rejected": "The requested {{ offerType }} for {{ serviceName }} has been rejected.", + "request-status-alert-box.rejected": "Le {{ offerType }} demandé pour {{ serviceName }} a été rejeté.", + + //"request-status-alert-box.requested": "The requested {{ offerType }} for {{ serviceName }} is pending.", + "request-status-alert-box.requested": "Le {{ offerType }} demandé pour {{ serviceName }} est en attente.", + + //"ldn-service-button-mark-inbound-deletion": "Mark supported pattern for deletion", + "ldn-service-button-mark-inbound-deletion": "Sélectionner le modèle pour suppression", + + //"ldn-service-button-unmark-inbound-deletion": "Unmark supported pattern for deletion", + "ldn-service-button-unmark-inbound-deletion": "Désélectionner le modèle pour suppression", + + //"ldn-service-input-inbound-item-filter-dropdown": "Select Item filter for the pattern", + "ldn-service-input-inbound-item-filter-dropdown": "Sélectionner le filtre de l'Item pour le modèle", + + //"ldn-service-input-inbound-pattern-dropdown": "Select a pattern for service", + "ldn-service-input-inbound-pattern-dropdown": "Sélectionner un modèle pour le service", + + //"ldn-service-overview-select-delete": "Select service for deletion", + "ldn-service-overview-select-delete": "Sélectionner le service à supprimer", + + //"ldn-service-overview-select-edit": "Edit LDN service", + "ldn-service-overview-select-edit": "Modifier le service LDN", + + //"ldn-service-overview-close-modal": "Close modal", + "ldn-service-overview-close-modal": "Fermer la fenêtre", + + //"a-common-or_statement.label": "Item type is Journal Article or Dataset", + "a-common-or_statement.label": "Le type de l'Item est Article de revue ou Jeu de donnnées", + + //"always_true_filter.label": "Always true", + "always_true_filter.label": "Toujours vrai", + + //"automatic_processing_collection_filter_16.label": "Automatic processing", + "automatic_processing_collection_filter_16.label": "Traitement automatique", + + //"dc-identifier-uri-contains-doi_condition.label": "URI contains DOI", + "dc-identifier-uri-contains-doi_condition.label": "L'URI contient un DOI", + + //"doi-filter.label": "DOI filter", + "doi-filter.label": "Filtre DOI", + + //"driver-document-type_condition.label": "Document type equals driver", + "driver-document-type_condition.label": "Le type de document correspond à Driver", + + //"has-at-least-one-bitstream_condition.label": "Has at least one Bitstream", + "has-at-least-one-bitstream_condition.label": "A au moins un Bitstream", + + //"has-bitstream_filter.label": "Has Bitstream", + "has-bitstream_filter.label": "A un Bitstream", + + //"has-one-bitstream_condition.label": "Has one Bitstream", + "has-one-bitstream_condition.label": "A un Bitstream", + + //"is-archived_condition.label": "Is archived", + "is-archived_condition.label": "Est archivé", + + //"is-withdrawn_condition.label": "Is withdrawn", + "is-withdrawn_condition.label": "Est retiré", + + //"item-is-public_condition.label": "Item is public", + "item-is-public_condition.label": "L'Item est public", + + //"journals_ingest_suggestion_collection_filter_18.label": "Journals ingest", + "journals_ingest_suggestion_collection_filter_18.label": "Ingestion des revues", + + //"title-starts-with-pattern_condition.label": "Title starts with pattern", + "title-starts-with-pattern_condition.label": "Le titre commence par le modèle", + + //"type-equals-dataset_condition.label": "Type equals Dataset", + "type-equals-dataset_condition.label": "Le type de document est Jeu de données", + + //"type-equals-journal-article_condition.label": "Type equals Journal Article", + "type-equals-journal-article_condition.label": "Le type de document est Article de revue", + + //"ldn.no-filter.label": "None", + "ldn.no-filter.label": "Aucun", + + //"admin.notify.dashboard": "Dashboard", + "admin.notify.dashboard": "Tableau de bord", + + //"menu.section.notify_dashboard": "Dashboard", + "menu.section.notify_dashboard": "Tableau de bord", + + //"menu.section.coar_notify": "COAR Notify", + "menu.section.coar_notify": "COAR Notify", + + //"admin-notify-dashboard.title": "Notify Dashboard", + "admin-notify-dashboard.title": "Tableau de bord Notify", + + //"admin-notify-dashboard.description": "The Notify dashboard monitor the general usage of the COAR Notify protocol across the repository. In the “Metrics” tab are statistics about usage of the COAR Notify protocol. In the “Logs/Inbound” and “Logs/Outbound” tabs it’s possible to search and check the individual status of each LDN message, either received or sent.", + "admin-notify-dashboard.description": "Le tableau de bord Notify surveille l'utilisation générale du protocole COAR Notify dans le dépôt. Les statistiques d'utilisation du protocole COAR Notify sont dans l'onglet “Métrique”. Dans les onglets “Journaux/Entrant” et “Journaux/Sortant” il est possible de rechercher et vérifier le statut de chaque message LDN, qu'il ait été reçu ou envoyé.", + + //"admin-notify-dashboard.metrics": "Metrics", + "admin-notify-dashboard.metrics": "Metriques", + + //"admin-notify-dashboard.received-ldn": "Number of received LDN", + "admin-notify-dashboard.received-ldn": "Nombre de LDN reçu", + + //"admin-notify-dashboard.generated-ldn": "Number of generated LDN", + "admin-notify-dashboard.generated-ldn": "Nombre de LDN généré", + + //"admin-notify-dashboard.NOTIFY.incoming.accepted": "Accepted", + "admin-notify-dashboard.NOTIFY.incoming.accepted": "Accepté", + + //"admin-notify-dashboard.NOTIFY.incoming.accepted.description": "Accepted inbound notifications", + "admin-notify-dashboard.NOTIFY.incoming.accepted.description": "Avis entrant acceptés", + + //"admin-notify-logs.NOTIFY.incoming.accepted": "Currently displaying: Accepted notifications", + "admin-notify-logs.NOTIFY.incoming.accepted": "Affiché actuellement : avis acceptés", + + //"admin-notify-dashboard.NOTIFY.incoming.processed": "Processed LDN", + "admin-notify-dashboard.NOTIFY.incoming.processed": "LDN traités", + + //"admin-notify-dashboard.NOTIFY.incoming.processed.description": "Processed inbound notifications", + "admin-notify-dashboard.NOTIFY.incoming.processed.description": "Avis entrant traités", + + //"admin-notify-logs.NOTIFY.incoming.processed": "Currently displaying: Processed LDN", + "admin-notify-logs.NOTIFY.incoming.processed": "Affiché actuellement : LDN traités", + + //"admin-notify-logs.NOTIFY.incoming.failure": "Currently displaying: Failed notifications", + "admin-notify-logs.NOTIFY.incoming.failure": "Affiché actuellement : avis en échec", + + //"admin-notify-dashboard.NOTIFY.incoming.failure": "Failure", + "admin-notify-dashboard.NOTIFY.incoming.failure": "Échec", + + //"admin-notify-dashboard.NOTIFY.incoming.failure.description": "Failed inbound notifications", + "admin-notify-dashboard.NOTIFY.incoming.failure.description": "Avis entrant en échec", + + //"admin-notify-logs.NOTIFY.outgoing.failure": "Currently displaying: Failed notifications", + "admin-notify-logs.NOTIFY.outgoing.failure": "Affiché actuellement : avis en échec", + + //"admin-notify-dashboard.NOTIFY.outgoing.failure": "Failure", + "admin-notify-dashboard.NOTIFY.outgoing.failure": "Échec", + + //"admin-notify-dashboard.NOTIFY.outgoing.failure.description": "Failed outbound notifications", + "admin-notify-dashboard.NOTIFY.outgoing.failure.description": "Avis sortant en échec", + + //"admin-notify-logs.NOTIFY.incoming.untrusted": "Currently displaying: Untrusted notifications", + "admin-notify-logs.NOTIFY.incoming.untrusted": "Affiché actuellement : avis non fiables", + + //"admin-notify-dashboard.NOTIFY.incoming.untrusted": "Untrusted", + "admin-notify-dashboard.NOTIFY.incoming.untrusted": "Non fiable", + + //"admin-notify-dashboard.NOTIFY.incoming.untrusted.description": "Inbound notifications not trusted", + "admin-notify-dashboard.NOTIFY.incoming.untrusted.description": "Avis entrant non fiable", + + //"admin-notify-logs.NOTIFY.incoming.delivered": "Currently displaying: Delivered notifications", + "admin-notify-logs.NOTIFY.incoming.delivered": "Affiché actuellement : avis livrés", + + //"admin-notify-dashboard.NOTIFY.incoming.delivered.description": "Inbound notifications successfully delivered", + "admin-notify-dashboard.NOTIFY.incoming.delivered.description": "Avis entrants livrés avec succès", + + //"admin-notify-dashboard.NOTIFY.outgoing.delivered": "Delivered", + "admin-notify-dashboard.NOTIFY.outgoing.delivered": "Livrés", + + //"admin-notify-logs.NOTIFY.outgoing.delivered": "Currently displaying: Delivered notifications", + "admin-notify-logs.NOTIFY.outgoing.delivered": "Affiché actuellement : avis livrés", + + //"admin-notify-dashboard.NOTIFY.outgoing.delivered.description": "Outbound notifications successfully delivered", + "admin-notify-dashboard.NOTIFY.outgoing.delivered.description": "Avis sortant livrés avec succès", + + //"admin-notify-logs.NOTIFY.outgoing.queued": "Currently displaying: Queued notifications", + "admin-notify-logs.NOTIFY.outgoing.queued": "Affiché actuellement : avis dans la liste d'attente", + + //"admin-notify-dashboard.NOTIFY.outgoing.queued.description": "Notifications currently queued", + "admin-notify-dashboard.NOTIFY.outgoing.queued.description": "Avis actuellement dans la liste d'attente", + + //"admin-notify-dashboard.NOTIFY.outgoing.queued": "Queued", + "admin-notify-dashboard.NOTIFY.outgoing.queued": "Ajouter à la liste d'attente", + + //"admin-notify-logs.NOTIFY.outgoing.queued_for_retry": "Currently displaying: Queued for retry notifications", + "admin-notify-logs.NOTIFY.outgoing.queued_for_retry": "Affiché actuellement : Avis en attente pour une nouvelle tentative", + + //"admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry": "Queued for retry", + "admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry": "En file d'attente pour une nouvelle tentative", + + //"admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry.description": "Notifications currently queued for retry", + "admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry.description": "Avis actuellement en attente pour une nouvelle tentative", + + //"admin-notify-dashboard.NOTIFY.incoming.involvedItems": "Items involved", + "admin-notify-dashboard.NOTIFY.incoming.involvedItems": "Items impliqués", + + //"admin-notify-dashboard.NOTIFY.incoming.involvedItems.description": "Items related to inbound notifications", + "admin-notify-dashboard.NOTIFY.incoming.involvedItems.description": "Items liés aux avis entrants", + + //"admin-notify-dashboard.NOTIFY.outgoing.involvedItems": "Items involved", + "admin-notify-dashboard.NOTIFY.outgoing.involvedItems": "Items impliqués", + + //"admin-notify-dashboard.NOTIFY.outgoing.involvedItems.description": "Items related to outbound notifications", + "admin-notify-dashboard.NOTIFY.outgoing.involvedItems.description": "Items liés aux avis sortants", + + //"admin.notify.dashboard.breadcrumbs": "Dashboard", + "admin.notify.dashboard.breadcrumbs": "Tableau de bord", + + //"admin.notify.dashboard.inbound": "Inbound messages", + "admin.notify.dashboard.inbound": "Messages entrants", + + //"admin.notify.dashboard.inbound-logs": "Logs/Inbound", + "admin.notify.dashboard.inbound-logs": "Journaux/Entrant", + + //"admin.notify.dashboard.filter": "Filter: ", + "admin.notify.dashboard.filter": "Filtre : ", + + //"search.filters.applied.f.relateditem": "Related items", + "search.filters.applied.f.relateditem": "Items liés", + + //"search.filters.applied.f.ldn_service": "LDN Service", + "search.filters.applied.f.ldn_service": "Service LDN", + + //"search.filters.applied.f.notifyReview": "Notify Review", + "search.filters.applied.f.notifyReview": "Évaluation Notify", + + //"search.filters.applied.f.notifyEndorsement": "Notify Endorsement", + "search.filters.applied.f.notifyEndorsement": "Approbation Notify", + + //"search.filters.applied.f.notifyRelation": "Notify Relation", + "search.filters.applied.f.notifyRelation": "Relation Notify", + + //"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.min.label": "Min range", + "search.filters.filter.queue_last_start_time.min.label": "Intervalle minimum", + + //"search.filters.filter.queue_last_start_time.max.label": "Max range", + "search.filters.filter.queue_last_start_time.max.label": "Intervalle maximum", + + //"search.filters.applied.f.queue_last_start_time.min": "Min range", + "search.filters.applied.f.queue_last_start_time.min": "Intervalle minimum", + + //"search.filters.applied.f.queue_last_start_time.max": "Max range", + "search.filters.applied.f.queue_last_start_time.max": "Intervalle maximum", + + //"admin.notify.dashboard.outbound": "Outbound messages", + "admin.notify.dashboard.outbound": "Messages sortants", + + //"admin.notify.dashboard.outbound-logs": "Logs/Outbound", + "admin.notify.dashboard.outbound-logs": "Journaux/Sortant", + + //"NOTIFY.incoming.search.results.head": "Incoming", + "NOTIFY.incoming.search.results.head": "À venir", + + //"search.filters.filter.relateditem.head": "Related item", + "search.filters.filter.relateditem.head": "Item lié", + + //"search.filters.filter.origin.head": "Origin", + "search.filters.filter.origin.head": "Origine", + + //"search.filters.filter.ldn_service.head": "LDN Service", + "search.filters.filter.ldn_service.head": "Service LDN", + + //"search.filters.filter.target.head": "Target", + "search.filters.filter.target.head": "Cible", + + //"search.filters.filter.queue_status.head": "Queue status", + "search.filters.filter.queue_status.head": "Statut de la file d'attente", + + //"search.filters.filter.activity_stream_type.head": "Activity stream type", + "search.filters.filter.activity_stream_type.head": "Type de flux d'activité", + + //"search.filters.filter.coar_notify_type.head": "COAR Notify type", + "search.filters.filter.coar_notify_type.head": "Type COAR Notify", + + //"search.filters.filter.notification_type.head": "Notification type", + "search.filters.filter.notification_type.head": "Type d'avis", + + //"search.filters.filter.relateditem.label": "Search related items", + "search.filters.filter.relateditem.label": "Chercher des Items liés", + + //"search.filters.filter.queue_status.label": "Search queue status", + "search.filters.filter.queue_status.label": "Chercher le statut de la file d'attente", + + //"search.filters.filter.target.label": "Search target", + "search.filters.filter.target.label": "Chercher la cible", + + //"search.filters.filter.activity_stream_type.label": "Search activity stream type", + "search.filters.filter.activity_stream_type.label": "Chercheur le type de flux d'activité", + + //"search.filters.applied.f.queue_status": "Queue Status", + "search.filters.applied.f.queue_status": "Statut de la file d'attente", + + //"search.filters.queue_status.0,authority": "Untrusted Ip" + "search.filters.queue_status.0,authority": "IP non fiable", + + //"search.filters.queue_status.1,authority": "Queued", + "search.filters.queue_status.1,authority": "Dans la file d'attente", + + //"search.filters.queue_status.2,authority": "Processing", + "search.filters.queue_status.2,authority": "En traitement", + + //"search.filters.queue_status.3,authority": "Processed", + "search.filters.queue_status.3,authority": "Traité", + + //"search.filters.queue_status.4,authority": "Failed", + "search.filters.queue_status.4,authority": "En échec", + + //"search.filters.queue_status.5,authority": "Untrusted", + "search.filters.queue_status.5,authority": "Non fiable", + + //"search.filters.queue_status.6,authority": "Unmapped Action", + "search.filters.queue_status.6,authority": "Action non répertoriée", + + //"search.filters.queue_status.7,authority": "Queued for retry", + "search.filters.queue_status.7,authority": "En file d'attente pour une nouvelle tentative", + + //"search.filters.applied.f.activity_stream_type": "Activity stream type", + "search.filters.applied.f.activity_stream_type": "Type de flux d'activité", + + //"search.filters.applied.f.coar_notify_type": "COAR Notify type", + "search.filters.applied.f.coar_notify_type": "Type COAR Notify", + + //"search.filters.applied.f.notification_type": "Notification type", + "search.filters.applied.f.notification_type": "Type d'avis", + + //"search.filters.filter.coar_notify_type.label": "Search COAR Notify type", + "search.filters.filter.coar_notify_type.label": "Chercher le type COAR Notify", + + //"search.filters.filter.notification_type.label": "Search notification type", + "search.filters.filter.notification_type.label": "Chercher le type d'avis", + + //"search.filters.filter.relateditem.placeholder": "Related items", + "search.filters.filter.relateditem.placeholder": "Items liés", + + //"search.filters.filter.target.placeholder": "Target", + "search.filters.filter.target.placeholder": "Cible", + + //"search.filters.filter.origin.label": "Search source", + "search.filters.filter.origin.label": "Chercher la source", + + //"search.filters.filter.origin.placeholder": "Source", + "search.filters.filter.origin.placeholder": "Source", + + //"search.filters.filter.ldn_service.label": "Search LDN Service", + "search.filters.filter.ldn_service.label": "Chercher le service LDN", + + //"search.filters.filter.ldn_service.placeholder": "LDN Service", + "search.filters.filter.ldn_service.placeholder": "Service LDN", + + //"search.filters.filter.queue_status.placeholder": "Queue status", + "search.filters.filter.queue_status.placeholder": "Statut de la file d'attente", + + //"search.filters.filter.activity_stream_type.placeholder": "Activity stream type", + "search.filters.filter.activity_stream_type.placeholder": "Type de flux d'activité", + + //"search.filters.filter.coar_notify_type.placeholder": "COAR Notify type", + "search.filters.filter.coar_notify_type.placeholder": "Type COAR Notify", + + //"search.filters.filter.notification_type.placeholder": "Notification", + "search.filters.filter.notification_type.placeholder": "Avis", + + //"search.filters.filter.notifyRelation.head": "Notify Relation", + "search.filters.filter.notifyRelation.head": "Relation Notify", + + //"search.filters.filter.notifyRelation.label": "Search Notify Relation", + "search.filters.filter.notifyRelation.label": "Chercher une relation Notify", + + //"search.filters.filter.notifyRelation.placeholder": "Notify Relation", + "search.filters.filter.notifyRelation.placeholder": "Relation Notify", + + //"search.filters.filter.notifyReview.head": "Notify Review", + "search.filters.filter.notifyReview.head": "Évaluation Notify", + + //"search.filters.filter.notifyReview.label": "Search Notify Review", + "search.filters.filter.notifyReview.label": "Chercher une évaluation Notify", + + //"search.filters.filter.notifyReview.placeholder": "Notify Review", + "search.filters.filter.notifyReview.placeholder": "Évaluation Notify", + + //"search.filters.coar_notify_type.coar-notify:ReviewAction": "Review action", + "search.filters.coar_notify_type.coar-notify:ReviewAction": "Action d'évaluation", + + //"search.filters.coar_notify_type.coar-notify:ReviewAction,authority": "Review action", + "search.filters.coar_notify_type.coar-notify:ReviewAction,authority": "Action d'évaluation", + + //"notify-detail-modal.coar-notify:ReviewAction": "Review action", + "notify-detail-modal.coar-notify:ReviewAction": "Action d'évaluation", + + //"search.filters.coar_notify_type.coar-notify:EndorsementAction": "Endorsement action", + "search.filters.coar_notify_type.coar-notify:EndorsementAction": "Action d'approbation", + + //"search.filters.coar_notify_type.coar-notify:EndorsementAction,authority": "Endorsement action", + "search.filters.coar_notify_type.coar-notify:EndorsementAction,authority": "Action d'approbation", + + //"notify-detail-modal.coar-notify:EndorsementAction": "Endorsement action", + "notify-detail-modal.coar-notify:EndorsementAction": "Action d'approbation", + + //"search.filters.coar_notify_type.coar-notify:IngestAction": "Ingest action", + "search.filters.coar_notify_type.coar-notify:IngestAction": "Action d'ingestion", + + //"search.filters.coar_notify_type.coar-notify:IngestAction,authority": "Ingest action", + "search.filters.coar_notify_type.coar-notify:IngestAction,authority": "Action d'ingestion", + + //"notify-detail-modal.coar-notify:IngestAction": "Ingest action", + "notify-detail-modal.coar-notify:IngestAction": "Action d'ingestion", + + //"search.filters.coar_notify_type.coar-notify:RelationshipAction": "Relationship action", + "search.filters.coar_notify_type.coar-notify:RelationshipAction": "Action de relation", + + //"search.filters.coar_notify_type.coar-notify:RelationshipAction,authority": "Relationship action", + "search.filters.coar_notify_type.coar-notify:RelationshipAction,authority": "Action de relation", + + //"notify-detail-modal.coar-notify:RelationshipAction": "Relationship action", + "notify-detail-modal.coar-notify:RelationshipAction": "Action de relation", + + //"search.filters.queue_status.QUEUE_STATUS_QUEUED": "Queued", + "search.filters.queue_status.QUEUE_STATUS_QUEUED": "En file d'attente", + + //"notify-detail-modal.QUEUE_STATUS_QUEUED": "Queued", + "notify-detail-modal.QUEUE_STATUS_QUEUED": "En file d'attente", + + //"search.filters.queue_status.QUEUE_STATUS_QUEUED_FOR_RETRY": "Queued for retry", + "search.filters.queue_status.QUEUE_STATUS_QUEUED_FOR_RETRY": "En file d'attente pour une nouvelle tentative", + + //"notify-detail-modal.QUEUE_STATUS_QUEUED_FOR_RETRY": "Queued for retry", + "notify-detail-modal.QUEUE_STATUS_QUEUED_FOR_RETRY": "En file d'attente pour une nouvelle tentative", + + //"search.filters.queue_status.QUEUE_STATUS_PROCESSING": "Processing", + "search.filters.queue_status.QUEUE_STATUS_PROCESSING": "En traitement", + + //"notify-detail-modal.QUEUE_STATUS_PROCESSING": "Processing", + "notify-detail-modal.QUEUE_STATUS_PROCESSING": "En traitement", + + //"search.filters.queue_status.QUEUE_STATUS_PROCESSED": "Processed", + "search.filters.queue_status.QUEUE_STATUS_PROCESSED": "Traité", + + //"notify-detail-modal.QUEUE_STATUS_PROCESSED": "Processed", + "notify-detail-modal.QUEUE_STATUS_PROCESSED": "Traité", + + //"search.filters.queue_status.QUEUE_STATUS_FAILED": "Failed", + "search.filters.queue_status.QUEUE_STATUS_FAILED": "En échec", + + //"notify-detail-modal.QUEUE_STATUS_FAILED": "Failed", + "notify-detail-modal.QUEUE_STATUS_FAILED": "En échec", + + //"search.filters.queue_status.QUEUE_STATUS_UNTRUSTED": "Untrusted", + "search.filters.queue_status.QUEUE_STATUS_UNTRUSTED": "Non fiable", + + //"search.filters.queue_status.QUEUE_STATUS_UNTRUSTED_IP": "Untrusted Ip", + "search.filters.queue_status.QUEUE_STATUS_UNTRUSTED_IP": "IP non fiable", + + //"notify-detail-modal.QUEUE_STATUS_UNTRUSTED": "Untrusted", + "notify-detail-modal.QUEUE_STATUS_UNTRUSTED": "Non fiable", + + //"notify-detail-modal.QUEUE_STATUS_UNTRUSTED_IP": "Untrusted Ip", + "notify-detail-modal.QUEUE_STATUS_UNTRUSTED_IP": "IP non fiable", + + //"search.filters.queue_status.QUEUE_STATUS_UNMAPPED_ACTION": "Unmapped Action", + "search.filters.queue_status.QUEUE_STATUS_UNMAPPED_ACTION": "Action non répertoriée", + + //"notify-detail-modal.QUEUE_STATUS_UNMAPPED_ACTION": "Unmapped Action", + "notify-detail-modal.QUEUE_STATUS_UNMAPPED_ACTION": "Action non répertoriée", + + //"sorting.queue_last_start_time.DESC": "Last started queue Descending", + "sorting.queue_last_start_time.DESC": "Dernière file d'attente démarrée Descendant", + + //"sorting.queue_last_start_time.ASC": "Last started queue Ascending", + "sorting.queue_last_start_time.ASC": "Dernière file d'attente démarrée Ascendant", + + //"sorting.queue_attempts.DESC": "Queue attempted Descending", + "sorting.queue_attempts.DESC": "Tentative de mise en file d'attente Descendant", + + //"sorting.queue_attempts.ASC": "Queue attempted Ascending", + "sorting.queue_attempts.ASC": "Tentative de mise en file d'attente Ascendant", + + //"NOTIFY.incoming.involvedItems.search.results.head": "Items involved in incoming LDN", + "NOTIFY.incoming.involvedItems.search.results.head": "Items inclus dans le LDN entrant", + + //"NOTIFY.outgoing.involvedItems.search.results.head": "Items involved in outgoing LDN", + "NOTIFY.outgoing.involvedItems.search.results.head": "Items inclus dans le LDN en cours", + + //"type.notify-detail-modal": "Type", + "type.notify-detail-modal": "Type", + + //"id.notify-detail-modal": "Id", + "id.notify-detail-modal": "Identifiant", + + //"coarNotifyType.notify-detail-modal": "COAR Notify type", + "coarNotifyType.notify-detail-modal": "Type COAR Notify", + + //"activityStreamType.notify-detail-modal": "Activity stream type", + "activityStreamType.notify-detail-modal": "Type de flux d'activité", + + //"inReplyTo.notify-detail-modal": "In reply to", + "inReplyTo.notify-detail-modal": "En réponse à", + + //"object.notify-detail-modal": "Repository Item", + "object.notify-detail-modal": "Item du dépôt", + + //"context.notify-detail-modal": "Repository Item", + "context.notify-detail-modal": "Item du dépôt", + + //"queueAttempts.notify-detail-modal": "Queue attempts", + "queueAttempts.notify-detail-modal": "Tentatives de mise en file d'attente", + + //"queueLastStartTime.notify-detail-modal": "Queue last started", + "queueLastStartTime.notify-detail-modal": "Dernière file d'attente démarrée", + + //"origin.notify-detail-modal": "LDN Service", + "origin.notify-detail-modal": "Service LDN", + + //"target.notify-detail-modal": "LDN Service", + "target.notify-detail-modal": "Service LDN", + + //"queueStatusLabel.notify-detail-modal": "Queue status", + "queueStatusLabel.notify-detail-modal": "Statut de la file d'attente", + + //"queueTimeout.notify-detail-modal": "Queue timeout", + "queueTimeout.notify-detail-modal": "Délai de mise en file d'attente", + + //"notify-message-modal.title": "Message Detail", + "notify-message-modal.title": "Détail du message", + + //"notify-message-modal.show-message": "Show message", + "notify-message-modal.show-message": "Voir le message", + + //notify-message-result.timestamp": "Timestamp", + "notify-message-result.timestamp": "Estampille temporelle", + + //"notify-message-result.repositoryItem": "Repository Item", + "notify-message-result.repositoryItem": "Item du dépôt", + + //"notify-message-result.ldnService": "LDN Service", + "notify-message-result.ldnService": "Service LDN", + + //"notify-message-result.type": "Type", + "notify-message-result.type": "Type", + + //"notify-message-result.status": "Status", + "notify-message-result.status": "Statut", + + //"notify-message-result.action": "Action", + "notify-message-result.action": "Action", + + //"notify-message-result.detail": "Detail", + "notify-message-result.detail": "Détail", + + //"notify-message-result.reprocess": "Reprocess", + "notify-message-result.reprocess": "Réexécuter", + + //"notify-queue-status.processed": "Processed", + "notify-queue-status.processed": "Traité", + + //"notify-queue-status.failed": "Failed", + "notify-queue-status.failed": "En échec", + + //"notify-queue-status.queue_retry": "Queued for retry", + "notify-queue-status.queue_retry": "En file d'attente pour une nouvelle tentative", + + //"notify-queue-status.unmapped_action": "Unmapped action", + "notify-queue-status.unmapped_action": "Action non répertoriée", + + //"notify-queue-status.processing": "Processing", + "notify-queue-status.processing": "En traitement", + + //"notify-queue-status.queued": "Queued", + "notify-queue-status.queued": "En file d'attente", + + //"notify-queue-status.untrusted": "Untrusted", + "notify-queue-status.untrusted": "Non fiable", + + //"ldnService.notify-detail-modal": "LDN Service", + "ldnService.notify-detail-modal": "Service LDN", + + //"relatedItem.notify-detail-modal": "Related Item", + "relatedItem.notify-detail-modal": "Item lié", + + //"search.filters.filter.notifyEndorsement.head": "Notify Endorsement", + "search.filters.filter.notifyEndorsement.head": "Approbation Notify", + + //"search.filters.filter.notifyEndorsement.placeholder": "Notify Endorsement", + "search.filters.filter.notifyEndorsement.placeholder": "Approbation Notify", + + //"search.filters.filter.notifyEndorsement.label": "Search Notify Endorsement", + "search.filters.filter.notifyEndorsement.label": "Chercher l'approbation Notify", + + //"item.page.cc.license.title": "Creative Commons license", + "item.page.cc.license.title": "Licence Creative Commons", + + //"item.page.cc.license.disclaimer": "Except where otherwised noted, this item's license is described as", + "item.page.cc.license.disclaimer": "Sauf indication contraire, la licence de cet Item est décrite comme", + + //"browse.search-form.placeholder": "Search the repository", + "browse.search-form.placeholder": "Chercher dans le dépôt", } From 9e19e8d85965e2848512fe41376a3080e7d6a2ed Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Mon, 11 Nov 2024 14:27:41 -0500 Subject: [PATCH 360/822] Fixes lint error Trailing spaces (cherry picked from commit 60dfe056dd06b08263cdcfad0c2c3d4d93abeb8e) --- src/assets/i18n/fr.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index d334789f7ec..af17af859a3 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -7983,7 +7983,7 @@ //"search.filters.queue_status.0,authority": "Untrusted Ip" "search.filters.queue_status.0,authority": "IP non fiable", - //"search.filters.queue_status.1,authority": "Queued", + //"search.filters.queue_status.1,authority": "Queued", "search.filters.queue_status.1,authority": "Dans la file d'attente", //"search.filters.queue_status.2,authority": "Processing", From aae373ef228f40fb154bb3d578fb0438b1f1a0f5 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Tue, 12 Nov 2024 11:33:45 +0100 Subject: [PATCH 361/822] 120150: Fixed authorization tab not loading in dev mode (cherry picked from commit c062d95354cea7118b9ab2babc2759409fe2ae10) --- src/app/item-page/item-page.resolver.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/item-page/item-page.resolver.ts b/src/app/item-page/item-page.resolver.ts index 431d8522e74..7c991889924 100644 --- a/src/app/item-page/item-page.resolver.ts +++ b/src/app/item-page/item-page.resolver.ts @@ -40,7 +40,7 @@ export const itemPageResolver: ResolveFn> = ( store: Store = inject(Store), authService: AuthService = inject(AuthService), ): Observable> => { - return itemService.findById( + const itemRD$ = itemService.findById( route.params.id, true, false, @@ -48,8 +48,14 @@ export const itemPageResolver: ResolveFn> = ( ).pipe( getFirstCompletedRemoteData(), redirectOn4xx(router, authService), + ); + + itemRD$.subscribe((itemRD: RemoteData) => { + store.dispatch(new ResolvedAction(state.url, itemRD.payload)); + }); + + return itemRD$.pipe( map((rd: RemoteData) => { - store.dispatch(new ResolvedAction(state.url, rd.payload)); if (rd.hasSucceeded && hasValue(rd.payload)) { const thisRoute = state.url; From 844a605b5ee89f4e0188f211e4bb52f6dadc6936 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Fri, 19 Jul 2024 14:54:39 +0200 Subject: [PATCH 362/822] [CST-15591] Fixed headings by their rank --- .../create-collection-page.component.html | 4 ++-- .../create-community-page.component.html | 6 +++--- .../events/quality-assurance-events.component.html | 14 +++++++------- .../source/quality-assurance-source.component.html | 4 ++-- .../topics/quality-assurance-topics.component.html | 4 ++-- .../workspaceitem-actions.component.html | 2 +- .../item-list-preview.component.html | 2 +- .../scope-selector-modal.component.html | 6 +++--- .../search-results/search-results.component.html | 2 +- .../sections/upload/section-upload.component.html | 2 +- .../workspaceitems-delete-page.component.html | 4 ++-- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/app/collection-page/create-collection-page/create-collection-page.component.html b/src/app/collection-page/create-collection-page/create-collection-page.component.html index 6ca55339247..5c1b7b32a58 100644 --- a/src/app/collection-page/create-collection-page/create-collection-page.component.html +++ b/src/app/collection-page/create-collection-page/create-collection-page.component.html @@ -1,8 +1,8 @@
    -

    {{ 'collection.create.sub-head' | translate:{ parent: dsoNameService.getName((parentRD$| async)?.payload) } }}

    +

    {{ 'collection.create.sub-head' | translate:{ parent: dsoNameService.getName((parentRD$| async)?.payload) } }}

    - -

    {{ 'community.create.sub-head' | translate:{ parent: dsoNameService.getName(parent) } }}

    +

    {{ 'community.create.head' | translate }}

    +

    {{ 'community.create.sub-head' | translate:{ parent: dsoNameService.getName(parent) } }}

    diff --git a/src/app/notifications/qa/events/quality-assurance-events.component.html b/src/app/notifications/qa/events/quality-assurance-events.component.html index 4341764d1c8..8a9f40e2b2e 100644 --- a/src/app/notifications/qa/events/quality-assurance-events.component.html +++ b/src/app/notifications/qa/events/quality-assurance-events.component.html @@ -1,11 +1,11 @@
    -

    +

    {{'notifications.events.title'| translate}}
    -

    +
    @@ -17,9 +17,9 @@

    -

    +

    {{'quality-assurance.events.topic' | translate}} {{this.showTopic}} -

    +

    @@ -247,7 +247,7 @@