From fffc43f443ca3bd72ee00cca1aeeb96887235b9d Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Tue, 7 Dec 2021 10:14:22 +0100 Subject: [PATCH 001/409] 85451: Add a button to export search results as CSV --- .../search-export-csv.component.html | 7 + .../search-export-csv.component.scss | 4 + .../search-export-csv.component.spec.ts | 179 ++++++++++++++++++ .../search-export-csv.component.ts | 102 ++++++++++ .../search-results.component.html | 3 + src/app/shared/shared.module.ts | 2 + src/assets/i18n/en.json5 | 5 + 7 files changed, 302 insertions(+) create mode 100644 src/app/shared/search/search-export-csv/search-export-csv.component.html create mode 100644 src/app/shared/search/search-export-csv/search-export-csv.component.scss create mode 100644 src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts create mode 100644 src/app/shared/search/search-export-csv/search-export-csv.component.ts diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.html b/src/app/shared/search/search-export-csv/search-export-csv.component.html new file mode 100644 index 00000000000..7bf87043007 --- /dev/null +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.html @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.scss b/src/app/shared/search/search-export-csv/search-export-csv.component.scss new file mode 100644 index 00000000000..4b0ab3c44ad --- /dev/null +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.scss @@ -0,0 +1,4 @@ +.export-button { + background: var(--ds-admin-sidebar-bg); + border-color: var(--ds-admin-sidebar-bg); +} \ No newline at end of file diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts new file mode 100644 index 00000000000..f8dc089c6ae --- /dev/null +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts @@ -0,0 +1,179 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { of as observableOf } from 'rxjs'; +import { TranslateModule } from '@ngx-translate/core'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { SearchExportCsvComponent } from './search-export-csv.component'; +import { ScriptDataService } from '../../../core/data/processes/script-data.service'; +import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../remote-data.utils'; +import { Script } from '../../../process-page/scripts/script.model'; +import { Process } from '../../../process-page/processes/process.model'; +import { NotificationsServiceStub } from '../../testing/notifications-service.stub'; +import { NotificationsService } from '../../notifications/notifications.service'; +import { Router } from '@angular/router'; +import { By } from '@angular/platform-browser'; +import { PaginatedSearchOptions } from '../paginated-search-options.model'; +import { SearchFilter } from '../search-filter.model'; +import { getProcessDetailRoute } from '../../../process-page/process-page-routing.paths'; + +describe('SearchExportCsvComponent', () => { + let component: SearchExportCsvComponent; + let fixture: ComponentFixture; + + let scriptDataService: ScriptDataService; + let authorizationDataService: AuthorizationDataService; + let notificationsService; + let router; + + const script = Object.assign(new Script(), {id: 'metadata-export-search', name: 'metadata-export-search'}); + const process = Object.assign(new Process(), {processId: 5, scriptName: 'metadata-export-search'}); + + const searchConfig = new PaginatedSearchOptions({ + configuration: 'test-configuration', + scope: 'test-scope', + query: 'test-query', + filters: [ + new SearchFilter('f.filter1', ['filter1value1,equals', 'filter1value2,equals']), + new SearchFilter('f.filter2', ['filter2value1,contains']) + ] + }); + + function initBeforeEachAsync() { + scriptDataService = jasmine.createSpyObj('scriptDataService', { + findById: createSuccessfulRemoteDataObject$(script), + invoke: createSuccessfulRemoteDataObject$(process) + }); + authorizationDataService = jasmine.createSpyObj('authorizationService', { + isAuthorized: observableOf(true) + }); + + notificationsService = new NotificationsServiceStub(); + + router = jasmine.createSpyObj('authorizationService', ['navigateByUrl']); + TestBed.configureTestingModule({ + declarations: [SearchExportCsvComponent], + imports: [TranslateModule.forRoot(), NgbModule], + providers: [ + {provide: ScriptDataService, useValue: scriptDataService}, + {provide: AuthorizationDataService, useValue: authorizationDataService}, + {provide: NotificationsService, useValue: notificationsService}, + {provide: Router, useValue: router}, + ] + }).compileComponents(); + } + + function initBeforeEach() { + fixture = TestBed.createComponent(SearchExportCsvComponent); + component = fixture.componentInstance; + component.searchConfig = searchConfig; + fixture.detectChanges(); + } + + describe('init', () => { + describe('comp', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should init the comp', () => { + expect(component).toBeTruthy(); + }); + }); + describe('when the user is an admin and the metadata-export-search script is present ', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should add the button', () => { + const debugElement = fixture.debugElement.query(By.css('button.export-button')); + expect(debugElement).toBeDefined(); + }); + }); + describe('when the user is not an admin', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + (authorizationDataService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(false)); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should not add the button', () => { + const debugElement = fixture.debugElement.query(By.css('button.export-button')); + expect(debugElement).toBeNull(); + }); + }); + describe('when the metadata-export-search script is not present', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + (scriptDataService.findById as jasmine.Spy).and.returnValue(createFailedRemoteDataObject$('Not found', 404)); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should should not add the button', () => { + const debugElement = fixture.debugElement.query(By.css('button.export-button')); + expect(debugElement).toBeNull(); + }); + }); + }); + describe('export', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should call the invoke script method with the correct parameters', () => { + component.export(); + expect(scriptDataService.invoke).toHaveBeenCalledWith('metadata-export-search', + [ + {name: '-q', value: searchConfig.query}, + {name: '-s', value: searchConfig.scope}, + {name: '-c', value: searchConfig.configuration}, + {name: '-f', value: 'filter1,equals=filter1value1,filter1value2'}, + {name: '-f', value: 'filter2,contains=filter2value1'}, + ], []); + + component.searchConfig = null; + fixture.detectChanges(); + + component.export(); + expect(scriptDataService.invoke).toHaveBeenCalledWith('metadata-export-search', [], []); + + }); + it('should show a success message when the script was invoked successfully and redirect to the corresponding process page', () => { + component.export(); + + expect(notificationsService.success).toHaveBeenCalled(); + expect(router.navigateByUrl).toHaveBeenCalledWith(getProcessDetailRoute(process.processId)); + }); + it('should show an error message when the script was not invoked successfully and stay on the current page', () => { + (scriptDataService.invoke as jasmine.Spy).and.returnValue(createFailedRemoteDataObject$('Error', 500)); + + component.export(); + + expect(notificationsService.error).toHaveBeenCalled(); + expect(router.navigateByUrl).not.toHaveBeenCalled(); + }); + }); + describe('clicking the button', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should trigger the export function', () => { + spyOn(component, 'export'); + + const debugElement = fixture.debugElement.query(By.css('button.export-button')); + debugElement.triggerEventHandler('click', null); + + expect(component.export).toHaveBeenCalled(); + }); + }); +}); diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.ts new file mode 100644 index 00000000000..a1bdf1c7e17 --- /dev/null +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.ts @@ -0,0 +1,102 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { PaginatedSearchOptions } from '../paginated-search-options.model'; +import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; +import { ScriptDataService } from '../../../core/data/processes/script-data.service'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { map, tap } from 'rxjs/operators'; +import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { hasValue, isNotEmpty } from '../../empty.util'; +import { RemoteData } from '../../../core/data/remote-data'; +import { Process } from '../../../process-page/processes/process.model'; +import { getProcessDetailRoute } from '../../../process-page/process-page-routing.paths'; +import { NotificationsService } from '../../notifications/notifications.service'; +import { TranslateService } from '@ngx-translate/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'ds-search-export-csv', + styleUrls: ['./search-export-csv.component.scss'], + templateUrl: './search-export-csv.component.html', +}) +/** + * Display a button to export the current search results as csv + */ +export class SearchExportCsvComponent implements OnInit { + + /** + * The current configuration of the search + */ + @Input() searchConfig: PaginatedSearchOptions; + + /** + * Observable used to determine whether the button should be shown + */ + shouldShowButton$: Observable; + + /** + * The message key used for the tooltip of the button + */ + tooltipMsg = 'metadata-export-search.tooltip'; + + constructor(private scriptDataService: ScriptDataService, + private authorizationDataService: AuthorizationDataService, + private notificationsService: NotificationsService, + private translateService: TranslateService, + private router: Router + ) { + } + + ngOnInit(): void { + const scriptExists$ = this.scriptDataService.findById('metadata-export-search').pipe( + getFirstCompletedRemoteData(), + map((rd) => rd.isSuccess && hasValue(rd.payload)) + ); + + const isAuthorized$ = this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf); + + this.shouldShowButton$ = observableCombineLatest([scriptExists$, isAuthorized$]).pipe( + tap((v) => console.log('showbutton', v)), + map(([scriptExists, isAuthorized]: [boolean, boolean]) => scriptExists && isAuthorized) + ); + } + + /** + * Start the export of the items based on the current search configuration + */ + export() { + const parameters = []; + if (hasValue(this.searchConfig)) { + if (isNotEmpty(this.searchConfig.query)) { + parameters.push({name: '-q', value: this.searchConfig.query}); + } + if (isNotEmpty(this.searchConfig.scope)) { + parameters.push({name: '-s', value: this.searchConfig.scope}); + } + if (isNotEmpty(this.searchConfig.configuration)) { + parameters.push({name: '-c', value: this.searchConfig.configuration}); + } + if (isNotEmpty(this.searchConfig.filters)) { + this.searchConfig.filters.forEach((filter) => { + let operator = 'equals'; + if (hasValue(filter.values)) { + operator = filter.values[0].substring(filter.values[0].indexOf(',') + 1); + } + const filterValue = `${filter.key.substring(2)},${operator}=${filter.values.map((v) => v.substring(0, v.indexOf(','))).join()}`; + parameters.push({name: '-f', value: filterValue}); + }); + } + } + + this.scriptDataService.invoke('metadata-export-search', parameters, []).pipe( + getFirstCompletedRemoteData() + ).subscribe((rd: RemoteData) => { + if (rd.hasSucceeded) { + this.notificationsService.success(this.translateService.get('metadata-export-search.submit.success')); + this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId)); + } else { + this.notificationsService.error(this.translateService.get('metadata-export-search.submit.error')); + } + }); + } +} diff --git a/src/app/shared/search/search-results/search-results.component.html b/src/app/shared/search/search-results/search-results.component.html index 4e6bca094ed..01c63e9c9e3 100644 --- a/src/app/shared/search/search-results/search-results.component.html +++ b/src/app/shared/search/search-results/search-results.component.html @@ -1,4 +1,7 @@ +

{{ (configuration ? configuration + '.search.results.head' : 'search.results.head') | translate }}

+ +
Date: Thu, 9 Dec 2021 15:09:46 +0100 Subject: [PATCH 002/409] 85451: Fixed filter syntax --- .../search-export-csv.component.spec.ts | 7 +++++-- .../search-export-csv.component.ts | 20 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts index f8dc089c6ae..cb0d7e62662 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts @@ -34,7 +34,8 @@ describe('SearchExportCsvComponent', () => { query: 'test-query', filters: [ new SearchFilter('f.filter1', ['filter1value1,equals', 'filter1value2,equals']), - new SearchFilter('f.filter2', ['filter2value1,contains']) + new SearchFilter('f.filter2', ['filter2value1,contains']), + new SearchFilter('f.filter3', ['[2000 TO 2001]'], 'equals') ] }); @@ -134,8 +135,10 @@ describe('SearchExportCsvComponent', () => { {name: '-q', value: searchConfig.query}, {name: '-s', value: searchConfig.scope}, {name: '-c', value: searchConfig.configuration}, - {name: '-f', value: 'filter1,equals=filter1value1,filter1value2'}, + {name: '-f', value: 'filter1,equals=filter1value1'}, + {name: '-f', value: 'filter1,equals=filter1value2'}, {name: '-f', value: 'filter2,contains=filter2value1'}, + {name: '-f', value: 'filter3,equals=[2000 TO 2001]'}, ], []); component.searchConfig = null; diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.ts index a1bdf1c7e17..d499097bd35 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.ts @@ -3,7 +3,7 @@ import { PaginatedSearchOptions } from '../paginated-search-options.model'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { ScriptDataService } from '../../../core/data/processes/script-data.service'; import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; -import { map, tap } from 'rxjs/operators'; +import { map } from 'rxjs/operators'; import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { hasValue, isNotEmpty } from '../../empty.util'; @@ -56,7 +56,6 @@ export class SearchExportCsvComponent implements OnInit { const isAuthorized$ = this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf); this.shouldShowButton$ = observableCombineLatest([scriptExists$, isAuthorized$]).pipe( - tap((v) => console.log('showbutton', v)), map(([scriptExists, isAuthorized]: [boolean, boolean]) => scriptExists && isAuthorized) ); } @@ -78,12 +77,21 @@ export class SearchExportCsvComponent implements OnInit { } if (isNotEmpty(this.searchConfig.filters)) { this.searchConfig.filters.forEach((filter) => { - let operator = 'equals'; if (hasValue(filter.values)) { - operator = filter.values[0].substring(filter.values[0].indexOf(',') + 1); + filter.values.forEach((value) => { + let operator; + let filterValue; + if (hasValue(filter.operator)) { + operator = filter.operator; + filterValue = value; + } else { + operator = value.substring(value.indexOf(',') + 1); + filterValue = value.substring(0, value.indexOf(',')); + } + const valueToAdd = `${filter.key.substring(2)},${operator}=${filterValue}`; + parameters.push({name: '-f', value: valueToAdd}); + }); } - const filterValue = `${filter.key.substring(2)},${operator}=${filter.values.map((v) => v.substring(0, v.indexOf(','))).join()}`; - parameters.push({name: '-f', value: filterValue}); }); } } From 90fb99be9a341663c0ff0e3f07e2e9a8e34c3066 Mon Sep 17 00:00:00 2001 From: SDGBot <38133100+itudevops@users.noreply.github.com> Date: Mon, 14 Feb 2022 13:30:49 +0300 Subject: [PATCH 003/409] Turkish Translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi everyone. As İstanbul Technical University IT Office, we have translated ui to Turkish. --- src/assets/i18n/tr.json5 | 4836 +++++++++++++------------------------- 1 file changed, 1607 insertions(+), 3229 deletions(-) diff --git a/src/assets/i18n/tr.json5 b/src/assets/i18n/tr.json5 index 0d036ff7d36..e8c2d8710e2 100644 --- a/src/assets/i18n/tr.json5 +++ b/src/assets/i18n/tr.json5 @@ -1,6748 +1,5126 @@ { // "401.help": "You're not authorized to access this page. You can use the button below to get back to the home page.", - // TODO New key - Add a translation - "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": "Bu sayfaya erişim yetkiniz bulunmamaktadır. Ana sayfaya dönmek için aşağıdaki butonu kullanabilirsiniz.", // "401.link.home-page": "Take me to the home page", - // TODO New key - Add a translation - "401.link.home-page": "Take me to the home page", + "401.link.home-page": "Beni ana sayfaya götür", // "401.unauthorized": "unauthorized", - // TODO New key - Add a translation - "401.unauthorized": "unauthorized", + "401.unauthorized": "yetkisiz", // "403.help": "You don't have permission to access this page. You can use the button below to get back to the home page.", - // TODO New key - Add a translation - "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": "Bu sayfaya erişim yetkiniz bulunmamaktadır. Ana sayfaya dönmek için aşağıdaki butonu kullanabilirsiniz.", // "403.link.home-page": "Take me to the home page", - // TODO New key - Add a translation - "403.link.home-page": "Take me to the home page", + "403.link.home-page": "Beni ana sayfaya götür", // "403.forbidden": "forbidden", - // TODO New key - Add a translation - "403.forbidden": "forbidden", + "403.forbidden": "yasaklı", // "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. ", - // TODO New key - Add a translation - "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": "Aradığınız sayfayı bulamıyoruz. Sayfa taşınmış veya silinmiş olabilir. Ana sayfaya geri dönmek için aşağıdaki butonu kullanabilirsiniz. ", // "404.link.home-page": "Take me to the home page", - // TODO New key - Add a translation - "404.link.home-page": "Take me to the home page", + "404.link.home-page": "Beni ana sayfaya götür", // "404.page-not-found": "page not found", - // TODO New key - Add a translation - "404.page-not-found": "page not found", + "404.page-not-found": "sayfa bulunamadı", // "admin.curation-tasks.breadcrumbs": "System curation tasks", - // TODO New key - Add a translation - "admin.curation-tasks.breadcrumbs": "System curation tasks", + "admin.curation-tasks.breadcrumbs": "Sistem iyileştirme görevleri", // "admin.curation-tasks.title": "System curation tasks", - // TODO New key - Add a translation - "admin.curation-tasks.title": "System curation tasks", + "admin.curation-tasks.title": "Sistem iyileştirme görevleri", // "admin.curation-tasks.header": "System curation tasks", - // TODO New key - Add a translation - "admin.curation-tasks.header": "System curation tasks", + "admin.curation-tasks.header": "Sistem iyileştirme görevleri", // "admin.registries.bitstream-formats.breadcrumbs": "Format registry", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.breadcrumbs": "Format registry", + "admin.registries.bitstream-formats.breadcrumbs": "Kayıt defterini biçimlendir", // "admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format", + "admin.registries.bitstream-formats.create.breadcrumbs": "Veri akışı biçimi", // "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", + "admin.registries.bitstream-formats.create.failure.content": "Yeni veri akışı biçimi oluşturulurken bir hata oluştu.", // "admin.registries.bitstream-formats.create.failure.head": "Failure", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.failure.head": "Failure", + "admin.registries.bitstream-formats.create.failure.head": "Aksama", // "admin.registries.bitstream-formats.create.head": "Create Bitstream format", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.head": "Create Bitstream format", + "admin.registries.bitstream-formats.create.head": "Vit akışı biçimi oluştur", // "admin.registries.bitstream-formats.create.new": "Add a new bitstream format", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.new": "Add a new bitstream format", + "admin.registries.bitstream-formats.create.new": "Yeni bir veri akışı biçimi ekleyin", // "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", + "admin.registries.bitstream-formats.create.success.content": "Yeni veri akışı biçimi başarıyla oluşturuldu.", // "admin.registries.bitstream-formats.create.success.head": "Success", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.success.head": "Success", + "admin.registries.bitstream-formats.create.success.head": "Başarılı", // "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", + "admin.registries.bitstream-formats.delete.failure.amount": "{{ amount }} biçim(ler) kaldırılamadı", // "admin.registries.bitstream-formats.delete.failure.head": "Failure", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.delete.failure.head": "Failure", + "admin.registries.bitstream-formats.delete.failure.head": "Aksama", // "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", + "admin.registries.bitstream-formats.delete.success.amount": "{{ amount }} biçim(ler) başarıyla kaldırıldı", // "admin.registries.bitstream-formats.delete.success.head": "Success", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.delete.success.head": "Success", + "admin.registries.bitstream-formats.delete.success.head": "Başarılı", // "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", + "admin.registries.bitstream-formats.description": "Bu veri akışı biçimleri listesi, bilinen biçimler ve destek düzeyleri hakkında bilgi sağlar.", // "admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format", + "admin.registries.bitstream-formats.edit.breadcrumbs": "Veri akışı biçimi", // "admin.registries.bitstream-formats.edit.description.hint": "", - // TODO New key - Add a translation "admin.registries.bitstream-formats.edit.description.hint": "", // "admin.registries.bitstream-formats.edit.description.label": "Description", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.description.label": "Description", + "admin.registries.bitstream-formats.edit.description.label": "Tanımlama", // "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.", - // TODO New key - Add a translation - "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": "Uzantılar, yüklenen dosyaların biçimini otomatik olarak tanımlamak için kullanılan dosya uzantılarıdır. Her biçim için birkaç uzantı girebilirsiniz.", // "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", + "admin.registries.bitstream-formats.edit.extensions.label": "Dosya uzantıları", // "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", + "admin.registries.bitstream-formats.edit.extensions.placeholder": "Nokta olmadan bir dosya uzantısı girin", // "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", + "admin.registries.bitstream-formats.edit.failure.content": "Veri akışı biçimi düzenlenirken bir hata oluştu.", // "admin.registries.bitstream-formats.edit.failure.head": "Failure", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.failure.head": "Failure", + "admin.registries.bitstream-formats.edit.failure.head": "Aksama", // "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", + "admin.registries.bitstream-formats.edit.head": "Veri akışı biçimi: {{ format }}", // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", - // TODO New key - Add a translation - "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": "Dahili olarak işaretlenen biçimler, kullanıcıdan gizlenir ve yönetim amacıyla kullanılır.", // "admin.registries.bitstream-formats.edit.internal.label": "Internal", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.internal.label": "Internal", + "admin.registries.bitstream-formats.edit.internal.label": "Dahili", // "admin.registries.bitstream-formats.edit.mimetype.hint": "The MIME type associated with this format, does not have to be unique.", - // TODO New key - Add a translation - "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": "Bu biçimle ilişkili MIME biçimi benzersiz olması gerekmez.", // "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", + "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Biçimi", // "admin.registries.bitstream-formats.edit.shortDescription.hint": "A unique name for this format, (e.g. Microsoft Word XP or Microsoft Word 2000)", - // TODO New key - Add a translation - "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": "Bu biçim için benzersiz bir ad (ör. Microsoft Word XP veya Microsoft Word 2000)", // "admin.registries.bitstream-formats.edit.shortDescription.label": "Name", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.shortDescription.label": "Name", + "admin.registries.bitstream-formats.edit.shortDescription.label": "İsim", // "admin.registries.bitstream-formats.edit.success.content": "The bitstream format was successfully edited.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.success.content": "The bitstream format was successfully edited.", + "admin.registries.bitstream-formats.edit.success.content": "Veri akışı biçimi başarıyla düzenlendi.", // "admin.registries.bitstream-formats.edit.success.head": "Success", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.success.head": "Success", + "admin.registries.bitstream-formats.edit.success.head": "Başarılı", // "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", + "admin.registries.bitstream-formats.edit.supportLevel.hint": "Kurumunuzun bu biçim için taahhüt ettiği destek düzeyi.", // "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", + "admin.registries.bitstream-formats.edit.supportLevel.label": "Destek seviyesi", // "admin.registries.bitstream-formats.head": "Bitstream Format Registry", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.head": "Bitstream Format Registry", + "admin.registries.bitstream-formats.head": "Veri Akışı Biçimi Kayıt Defteri", // "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", + "admin.registries.bitstream-formats.no-items": "Gösterilecek veri akışı biçimi yok.", // "admin.registries.bitstream-formats.table.delete": "Delete selected", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.delete": "Delete selected", + "admin.registries.bitstream-formats.table.delete": "Silme seçildi", // "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", + "admin.registries.bitstream-formats.table.deselect-all": "Tüm seçimleri kaldır", // "admin.registries.bitstream-formats.table.internal": "internal", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.internal": "internal", + "admin.registries.bitstream-formats.table.internal": "dahili", // "admin.registries.bitstream-formats.table.mimetype": "MIME Type", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.mimetype": "MIME Type", + "admin.registries.bitstream-formats.table.mimetype": "MIME Biçimi", // "admin.registries.bitstream-formats.table.name": "Name", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.name": "Name", + "admin.registries.bitstream-formats.table.name": "İsim", // "admin.registries.bitstream-formats.table.return": "Return", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.return": "Return", + "admin.registries.bitstream-formats.table.return": "Geri Dön", // "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Known", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Known", + "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Biliniyor", // "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Supported", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Supported", + "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Destekleniyor", // "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Unknown", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Unknown", + "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Bilinmiyor", // "admin.registries.bitstream-formats.table.supportLevel.head": "Support Level", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.supportLevel.head": "Support Level", + "admin.registries.bitstream-formats.table.supportLevel.head": "Destek Seviyesi", // "admin.registries.bitstream-formats.title": "DSpace Angular :: Bitstream Format Registry", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.title": "DSpace Angular :: Bitstream Format Registry", + "admin.registries.bitstream-formats.title": "DSpace Angular :: Veri Akışı Biçimi Kayıt Defteri ", // "admin.registries.metadata.breadcrumbs": "Metadata registry", - // TODO New key - Add a translation - "admin.registries.metadata.breadcrumbs": "Metadata registry", + "admin.registries.metadata.breadcrumbs": "Metaveri kayıt defteri", // "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.", - // TODO New key - Add a translation - "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": "Metaveri kayıt defteri, veri havuzda bulunan tüm metaveri alanlarının bir listesini tutar. Bu alanlar birden çok şema arasında bölünebilir. Ancak, DSpace nitelikli Dublin Core şemasını gerektirir.", // "admin.registries.metadata.form.create": "Create metadata schema", - // TODO New key - Add a translation - "admin.registries.metadata.form.create": "Create metadata schema", + "admin.registries.metadata.form.create": "Metaveri şeması oluştur", // "admin.registries.metadata.form.edit": "Edit metadata schema", - // TODO New key - Add a translation - "admin.registries.metadata.form.edit": "Edit metadata schema", + "admin.registries.metadata.form.edit": "Metaveri şemasını düzenle", // "admin.registries.metadata.form.name": "Name", - // TODO New key - Add a translation - "admin.registries.metadata.form.name": "Name", + "admin.registries.metadata.form.name": "İsim", // "admin.registries.metadata.form.namespace": "Namespace", - // TODO New key - Add a translation - "admin.registries.metadata.form.namespace": "Namespace", + "admin.registries.metadata.form.namespace": "Ad Alanı", // "admin.registries.metadata.head": "Metadata Registry", - // TODO New key - Add a translation - "admin.registries.metadata.head": "Metadata Registry", + "admin.registries.metadata.head": "Metaveri Kayıt Defteri", // "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", + "admin.registries.metadata.schemas.no-items": "Gösterilecek metaveri alanı yok.", // "admin.registries.metadata.schemas.table.delete": "Delete selected", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.table.delete": "Delete selected", + "admin.registries.metadata.schemas.table.delete": "Silme Seçildi", // "admin.registries.metadata.schemas.table.id": "ID", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.table.id": "ID", + "admin.registries.metadata.schemas.table.id": "Kimlik", // "admin.registries.metadata.schemas.table.name": "Name", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.table.name": "Name", + "admin.registries.metadata.schemas.table.name": "İsim", // "admin.registries.metadata.schemas.table.namespace": "Namespace", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.table.namespace": "Namespace", + "admin.registries.metadata.schemas.table.namespace": "Ad Alanı", // "admin.registries.metadata.title": "DSpace Angular :: Metadata Registry", - // TODO New key - Add a translation - "admin.registries.metadata.title": "DSpace Angular :: Metadata Registry", + "admin.registries.metadata.title": "DSpace Angular :: Metaveri Kayıt Defteri", // "admin.registries.schema.breadcrumbs": "Metadata schema", - // TODO New key - Add a translation - "admin.registries.schema.breadcrumbs": "Metadata schema", + "admin.registries.schema.breadcrumbs": "Metaveri şeması", // "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", - // TODO New key - Add a translation - "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", + "admin.registries.schema.description": "Bu, \"{{namesapce}}\" için meta veri şemasıdır.", // "admin.registries.schema.fields.head": "Schema metadata fields", - // TODO New key - Add a translation - "admin.registries.schema.fields.head": "Schema metadata fields", + "admin.registries.schema.fields.head": "Şema metaveri alanları", // "admin.registries.schema.fields.no-items": "No metadata fields to show.", - // TODO New key - Add a translation - "admin.registries.schema.fields.no-items": "No metadata fields to show.", + "admin.registries.schema.fields.no-items": "Gösterilecek metaveri alanı yok.", // "admin.registries.schema.fields.table.delete": "Delete selected", - // TODO New key - Add a translation - "admin.registries.schema.fields.table.delete": "Delete selected", + "admin.registries.schema.fields.table.delete": "Silme Seçildi", // "admin.registries.schema.fields.table.field": "Field", - // TODO New key - Add a translation - "admin.registries.schema.fields.table.field": "Field", + "admin.registries.schema.fields.table.field": "Alan", // "admin.registries.schema.fields.table.scopenote": "Scope Note", - // TODO New key - Add a translation - "admin.registries.schema.fields.table.scopenote": "Scope Note", + "admin.registries.schema.fields.table.scopenote": "Kapsam Notu", // "admin.registries.schema.form.create": "Create metadata field", - // TODO New key - Add a translation - "admin.registries.schema.form.create": "Create metadata field", + "admin.registries.schema.form.create": "Metaveri alanı oluştur", // "admin.registries.schema.form.edit": "Edit metadata field", - // TODO New key - Add a translation - "admin.registries.schema.form.edit": "Edit metadata field", + "admin.registries.schema.form.edit": "Metaveri alanını düzenle", // "admin.registries.schema.form.element": "Element", - // TODO New key - Add a translation "admin.registries.schema.form.element": "Element", // "admin.registries.schema.form.qualifier": "Qualifier", - // TODO New key - Add a translation - "admin.registries.schema.form.qualifier": "Qualifier", + "admin.registries.schema.form.qualifier": "Niteleyici", // "admin.registries.schema.form.scopenote": "Scope Note", - // TODO New key - Add a translation - "admin.registries.schema.form.scopenote": "Scope Note", + "admin.registries.schema.form.scopenote": "Kapsam Notu", // "admin.registries.schema.head": "Metadata Schema", - // TODO New key - Add a translation - "admin.registries.schema.head": "Metadata Schema", + "admin.registries.schema.head": "Metaveri Şeması", // "admin.registries.schema.notification.created": "Successfully created metadata schema \"{{prefix}}\"", - // TODO New key - Add a translation - "admin.registries.schema.notification.created": "Successfully created metadata schema \"{{prefix}}\"", + "admin.registries.schema.notification.created": "Metaveri şeması \"{{prefix}}\" başarıyla oluşturuldu", // "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", - // TODO New key - Add a translation - "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", + "admin.registries.schema.notification.deleted.failure": "{{amount}} metaveri şeması silinemedi", // "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", - // TODO New key - Add a translation - "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", + "admin.registries.schema.notification.deleted.success": "{{amount}} metaveri şeması başarıyla silindi", // "admin.registries.schema.notification.edited": "Successfully edited metadata schema \"{{prefix}}\"", - // TODO New key - Add a translation - "admin.registries.schema.notification.edited": "Successfully edited metadata schema \"{{prefix}}\"", + "admin.registries.schema.notification.edited": "Metaveri şeması \"{{prefix}}\" başarıyla düzenlendi", // "admin.registries.schema.notification.failure": "Error", - // TODO New key - Add a translation - "admin.registries.schema.notification.failure": "Error", + "admin.registries.schema.notification.failure": "Hata", // "admin.registries.schema.notification.field.created": "Successfully created metadata field \"{{field}}\"", - // TODO New key - Add a translation - "admin.registries.schema.notification.field.created": "Successfully created metadata field \"{{field}}\"", + "admin.registries.schema.notification.field.created": "\"{{field}}\" metaveri alanı başarıyla oluşturuldu", // "admin.registries.schema.notification.field.deleted.failure": "Failed to delete {{amount}} metadata fields", - // TODO New key - Add a translation - "admin.registries.schema.notification.field.deleted.failure": "Failed to delete {{amount}} metadata fields", + "admin.registries.schema.notification.field.deleted.failure": "{{amount}} metaveri alanı silinemedi", // "admin.registries.schema.notification.field.deleted.success": "Successfully deleted {{amount}} metadata fields", - // TODO New key - Add a translation - "admin.registries.schema.notification.field.deleted.success": "Successfully deleted {{amount}} metadata fields", + "admin.registries.schema.notification.field.deleted.success": "{{amount}} metaveri alanı başarıyla silindi", // "admin.registries.schema.notification.field.edited": "Successfully edited metadata field \"{{field}}\"", - // TODO New key - Add a translation - "admin.registries.schema.notification.field.edited": "Successfully edited metadata field \"{{field}}\"", + "admin.registries.schema.notification.field.edited": "Metaveri alanı \"{{field}}\" başarıyla düzenlendi", // "admin.registries.schema.notification.success": "Success", - // TODO New key - Add a translation - "admin.registries.schema.notification.success": "Success", + "admin.registries.schema.notification.success": "Başarılı", // "admin.registries.schema.return": "Return", - // TODO New key - Add a translation - "admin.registries.schema.return": "Return", + "admin.registries.schema.return": "Geri Dön", // "admin.registries.schema.title": "DSpace Angular :: Metadata Schema Registry", - // TODO New key - Add a translation - "admin.registries.schema.title": "DSpace Angular :: Metadata Schema Registry", + "admin.registries.schema.title": "DSpace Angular :: Metaveri Şeması Kayıt Defteri", // "admin.access-control.epeople.actions.delete": "Delete EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.actions.delete": "Delete EPerson", + "admin.access-control.epeople.actions.delete": "E-Kişiyi Sil", // "admin.access-control.epeople.actions.impersonate": "Impersonate EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.actions.impersonate": "Impersonate EPerson", + "admin.access-control.epeople.actions.impersonate": "E-Kişinin Kimliğine Bürün", // "admin.access-control.epeople.actions.reset": "Reset password", - // TODO New key - Add a translation - "admin.access-control.epeople.actions.reset": "Reset password", + "admin.access-control.epeople.actions.reset": "Parolayı sıfırla", // "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", + "admin.access-control.epeople.actions.stop-impersonating": "E-Kişilerin kimliğine bürünmeyi durdurun", // "admin.access-control.epeople.title": "DSpace Angular :: EPeople", - // TODO New key - Add a translation - "admin.access-control.epeople.title": "DSpace Angular :: EPeople", + "admin.access-control.epeople.title": "DSpace Angular :: E-kişiler", // "admin.access-control.epeople.head": "EPeople", - // TODO New key - Add a translation - "admin.access-control.epeople.head": "EPeople", + "admin.access-control.epeople.head": "E-Kişiler", // "admin.access-control.epeople.search.head": "Search", - // TODO New key - Add a translation - "admin.access-control.epeople.search.head": "Search", + "admin.access-control.epeople.search.head": "Ara", - // "admin.access-control.epeople.button.see-all": "Browse All", - // TODO New key - Add a translation + // "admin.access-control.epeople.button.see-all": "Tümüne Gözat", "admin.access-control.epeople.button.see-all": "Browse All", // "admin.access-control.epeople.search.scope.metadata": "Metadata", - // TODO New key - Add a translation - "admin.access-control.epeople.search.scope.metadata": "Metadata", + "admin.access-control.epeople.search.scope.metadata": "Metaveri", // "admin.access-control.epeople.search.scope.email": "E-mail (exact)", - // TODO New key - Add a translation - "admin.access-control.epeople.search.scope.email": "E-mail (exact)", + "admin.access-control.epeople.search.scope.email": "E-posta (tam)", // "admin.access-control.epeople.search.button": "Search", - // TODO New key - Add a translation - "admin.access-control.epeople.search.button": "Search", + "admin.access-control.epeople.search.button": "Ara", // "admin.access-control.epeople.button.add": "Add EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.button.add": "Add EPerson", + "admin.access-control.epeople.button.add": "E-Kişi Ekle", // "admin.access-control.epeople.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.epeople.table.id": "ID", + "admin.access-control.epeople.table.id": "Kimlik", // "admin.access-control.epeople.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.epeople.table.name": "Name", + "admin.access-control.epeople.table.name": "İsim", // "admin.access-control.epeople.table.email": "E-mail (exact)", - // TODO New key - Add a translation - "admin.access-control.epeople.table.email": "E-mail (exact)", + "admin.access-control.epeople.table.email": "E-posta (tam)", // "admin.access-control.epeople.table.edit": "Edit", - // TODO New key - Add a translation - "admin.access-control.epeople.table.edit": "Edit", + "admin.access-control.epeople.table.edit": "Düzenle", // "admin.access-control.epeople.table.edit.buttons.edit": "Edit \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.table.edit.buttons.edit": "Edit \"{{name}}\"", + "admin.access-control.epeople.table.edit.buttons.edit": "Düzenle \"{{name}}\"", // "admin.access-control.epeople.table.edit.buttons.remove": "Delete \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.table.edit.buttons.remove": "Delete \"{{name}}\"", + "admin.access-control.epeople.table.edit.buttons.remove": "Sil \"{{name}}\"", // "admin.access-control.epeople.no-items": "No EPeople to show.", - // TODO New key - Add a translation - "admin.access-control.epeople.no-items": "No EPeople to show.", + "admin.access-control.epeople.no-items": "Gösterilecek E-Kişiler yok.", // "admin.access-control.epeople.form.create": "Create EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.form.create": "Create EPerson", + "admin.access-control.epeople.form.create": "E-Kişi Oluştur", // "admin.access-control.epeople.form.edit": "Edit EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.form.edit": "Edit EPerson", + "admin.access-control.epeople.form.edit": "E-Kişiyi Düzenle", // "admin.access-control.epeople.form.firstName": "First name", - // TODO New key - Add a translation - "admin.access-control.epeople.form.firstName": "First name", + "admin.access-control.epeople.form.firstName": "İsim", // "admin.access-control.epeople.form.lastName": "Last name", - // TODO New key - Add a translation - "admin.access-control.epeople.form.lastName": "Last name", + "admin.access-control.epeople.form.lastName": "Soyadı", // "admin.access-control.epeople.form.email": "E-mail", - // TODO New key - Add a translation - "admin.access-control.epeople.form.email": "E-mail", + "admin.access-control.epeople.form.email": "E-posta", // "admin.access-control.epeople.form.emailHint": "Must be valid e-mail address", - // TODO New key - Add a translation - "admin.access-control.epeople.form.emailHint": "Must be valid e-mail address", + "admin.access-control.epeople.form.emailHint": "Geçerli bir e-posta adresi olmalı", // "admin.access-control.epeople.form.canLogIn": "Can log in", - // TODO New key - Add a translation - "admin.access-control.epeople.form.canLogIn": "Can log in", + "admin.access-control.epeople.form.canLogIn": "Giriş yapabilir", // "admin.access-control.epeople.form.requireCertificate": "Requires certificate", - // TODO New key - Add a translation - "admin.access-control.epeople.form.requireCertificate": "Requires certificate", + "admin.access-control.epeople.form.requireCertificate": "Sertifika gerektirir", // "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.created.success": "E-Kişi \"{{name}}\" başarıyla oluşturuldu", // "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.created.failure": "E-Kişi \"{{name}}\" oluşturulamadı", // "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.", - // TODO New key - Add a translation - "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": "E-Kişi \"{{name}}\" oluşturulamadı, e-posta \"{{email}}\" zaten kullanımda.", // "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Failed to edit EPerson \"{{name}}\", email \"{{email}}\" already in use.", - // TODO New key - Add a translation - "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": "E-Kişi \"{{name}}\" düzenlenemedi, e-posta \"{{email}}\" zaten kullanımda.", // "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.edited.success": "E-kişi \"{{name}}\" başarıyla düzenlendi", // "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.edited.failure": "E-Kişi \"{{name}}\" düzenlenemedi", // "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.deleted.success": "E-Kişi \"{{name}}\" başarıyla silindi", // "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.deleted.failure": "E-Kişi \"{{name}}\" silinemedi", // "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", - // TODO New key - Add a translation - "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", + "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Bu grupların üyesi:", // "admin.access-control.epeople.form.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.epeople.form.table.id": "ID", + "admin.access-control.epeople.form.table.id": "Kimlik", // "admin.access-control.epeople.form.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.epeople.form.table.name": "Name", + "admin.access-control.epeople.form.table.name": "İsim", // "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", - // TODO New key - Add a translation - "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", + "admin.access-control.epeople.form.memberOfNoGroups": "Bu E-Kişi herhangi bir grubun üyesi değil", // "admin.access-control.epeople.form.goToGroups": "Add to groups", - // TODO New key - Add a translation - "admin.access-control.epeople.form.goToGroups": "Add to groups", + "admin.access-control.epeople.form.goToGroups": "Gruplar ekle", // "admin.access-control.epeople.notification.deleted.failure": "Failed to delete EPerson: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.notification.deleted.failure": "Failed to delete EPerson: \"{{name}}\"", + "admin.access-control.epeople.notification.deleted.failure": "E-Kişi silinemedi: \"{{name}}\"", // "admin.access-control.epeople.notification.deleted.success": "Successfully deleted EPerson: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.notification.deleted.success": "Successfully deleted EPerson: \"{{name}}\"", + "admin.access-control.epeople.notification.deleted.success": "E-Kişiler başarıyla silindi: \"{{name}}\"", // "admin.access-control.groups.title": "DSpace Angular :: Groups", - // TODO New key - Add a translation - "admin.access-control.groups.title": "DSpace Angular :: Groups", + "admin.access-control.groups.title": "DSpace Angular :: Gruplar", // "admin.access-control.groups.title.singleGroup": "DSpace Angular :: Edit Group", - // TODO New key - Add a translation - "admin.access-control.groups.title.singleGroup": "DSpace Angular :: Edit Group", + "admin.access-control.groups.title.singleGroup": "DSpace Angular :: Grubu Düzenle", // "admin.access-control.groups.title.addGroup": "DSpace Angular :: New Group", - // TODO New key - Add a translation - "admin.access-control.groups.title.addGroup": "DSpace Angular :: New Group", + "admin.access-control.groups.title.addGroup": "DSpace Angular :: Yeni Grup", // "admin.access-control.groups.head": "Groups", - // TODO New key - Add a translation - "admin.access-control.groups.head": "Groups", + "admin.access-control.groups.head": "Gruplar", // "admin.access-control.groups.button.add": "Add group", - // TODO New key - Add a translation - "admin.access-control.groups.button.add": "Add group", + "admin.access-control.groups.button.add": "Grup ekle", // "admin.access-control.groups.search.head": "Search groups", - // TODO New key - Add a translation - "admin.access-control.groups.search.head": "Search groups", + "admin.access-control.groups.search.head": "Grupları ara", // "admin.access-control.groups.button.see-all": "Browse all", - // TODO New key - Add a translation - "admin.access-control.groups.button.see-all": "Browse all", + "admin.access-control.groups.button.see-all": "Tümüne göz at", // "admin.access-control.groups.search.button": "Search", - // TODO New key - Add a translation - "admin.access-control.groups.search.button": "Search", + "admin.access-control.groups.search.button": "Ara", // "admin.access-control.groups.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.groups.table.id": "ID", + "admin.access-control.groups.table.id": "Kimlik", // "admin.access-control.groups.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.groups.table.name": "Name", + "admin.access-control.groups.table.name": "İsim", // "admin.access-control.groups.table.members": "Members", - // TODO New key - Add a translation - "admin.access-control.groups.table.members": "Members", + "admin.access-control.groups.table.members": "Üyeler", // "admin.access-control.groups.table.edit": "Edit", - // TODO New key - Add a translation - "admin.access-control.groups.table.edit": "Edit", + "admin.access-control.groups.table.edit": "Düzenle", // "admin.access-control.groups.table.edit.buttons.edit": "Edit \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.table.edit.buttons.edit": "Edit \"{{name}}\"", + "admin.access-control.groups.table.edit.buttons.edit": "Düzenle \"{{name}}\"", // "admin.access-control.groups.table.edit.buttons.remove": "Delete \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.table.edit.buttons.remove": "Delete \"{{name}}\"", + "admin.access-control.groups.table.edit.buttons.remove": "Sil \"{{name}}\"", // "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", - // TODO New key - Add a translation - "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", + "admin.access-control.groups.no-items": "Bu adla veya bu UUID olarak hiçbir grup bulunamadı", // "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", + "admin.access-control.groups.notification.deleted.success": "\"{{name}}\" grubu başarıyla silindi", // "admin.access-control.groups.notification.deleted.failure.title": "Failed to delete group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.notification.deleted.failure.title": "Failed to delete group \"{{name}}\"", + "admin.access-control.groups.notification.deleted.failure.title": "\"{{name}}\" grubu silinemedi", // "admin.access-control.groups.notification.deleted.failure.content": "Cause: \"{{cause}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.notification.deleted.failure.content": "Cause: \"{{cause}}\"", + "admin.access-control.groups.notification.deleted.failure.content": "Sorun: \"{{cause}}\"", // "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.", - // TODO New key - Add a translation - "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": "Bu grup kalıcıdır, bu nedenle düzenlenemez veya silinemez. Yine de bu sayfayı kullanarak grup üyeleri ekleyip kaldırabilirsiniz.", // "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.", - // TODO New key - Add a translation - "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": "Bu grup, \"{{name}}\" {{comcol}} içindeki gönderim ve iş akışı sürecindeki bir role karşılık geldiği için değiştirilemez veya silinemez. Bunu, {{comcol}} düzenleme sayfasındaki \"rol ata\" sekmesinden silebilirsiniz. Yine de bu sayfayı kullanarak grup üyeleri ekleyip kaldırabilirsiniz.", // "admin.access-control.groups.form.head.create": "Create group", - // TODO New key - Add a translation - "admin.access-control.groups.form.head.create": "Create group", + "admin.access-control.groups.form.head.create": "Grup oluştur", // "admin.access-control.groups.form.head.edit": "Edit group", - // TODO New key - Add a translation - "admin.access-control.groups.form.head.edit": "Edit group", + "admin.access-control.groups.form.head.edit": "Grubu düzenle", // "admin.access-control.groups.form.groupName": "Group name", - // TODO New key - Add a translation - "admin.access-control.groups.form.groupName": "Group name", + "admin.access-control.groups.form.groupName": "Grup adı", // "admin.access-control.groups.form.groupDescription": "Description", - // TODO New key - Add a translation - "admin.access-control.groups.form.groupDescription": "Description", + "admin.access-control.groups.form.groupDescription": "Açıklama", // "admin.access-control.groups.form.notification.created.success": "Successfully created Group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.created.success": "Successfully created Group \"{{name}}\"", + "admin.access-control.groups.form.notification.created.success": "Grup \"{{name}}\" başarıyla oluşturuldu", // "admin.access-control.groups.form.notification.created.failure": "Failed to create Group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.created.failure": "Failed to create Group \"{{name}}\"", + "admin.access-control.groups.form.notification.created.failure": "\"{{name}}\" Grubu oluşturulamadı", // "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.", - // TODO New key - Add a translation - "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": "Şu ada sahip Grup oluşturulamadı: \"{{name}}\", adın halihazırda kullanımda olmadığından emin olun.", // "admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"", + "admin.access-control.groups.form.notification.edited.failure": "\"{{name}}\" Grubu düzenlenemedi", // "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!", + "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "\"{{name}}\" adı zaten kullanılıyor!", // "admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"", + "admin.access-control.groups.form.notification.edited.success": "\"{{name}}\" Grubu başarıyla düzenlendi", // "admin.access-control.groups.form.actions.delete": "Delete Group", - // TODO New key - Add a translation - "admin.access-control.groups.form.actions.delete": "Delete Group", + "admin.access-control.groups.form.actions.delete": "Grubu Sil", // "admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"", + "admin.access-control.groups.form.delete-group.modal.header": "\"{{ dsoName }}\" Grubunu Sil", // "admin.access-control.groups.form.delete-group.modal.info": "Are you sure you want to delete Group \"{{ dsoName }}\"", - // TODO New key - Add a translation - "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 }}\" Grubunu silmek istediğinizden emin misiniz?", // "admin.access-control.groups.form.delete-group.modal.cancel": "Cancel", - // TODO New key - Add a translation - "admin.access-control.groups.form.delete-group.modal.cancel": "Cancel", + "admin.access-control.groups.form.delete-group.modal.cancel": "İptal", // "admin.access-control.groups.form.delete-group.modal.confirm": "Delete", - // TODO New key - Add a translation - "admin.access-control.groups.form.delete-group.modal.confirm": "Delete", + "admin.access-control.groups.form.delete-group.modal.confirm": "Sil", // "admin.access-control.groups.form.notification.deleted.success": "Successfully deleted group \"{{ name }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.deleted.success": "Successfully deleted group \"{{ name }}\"", + "admin.access-control.groups.form.notification.deleted.success": "\"{{ name }}\" grubu başarıyla silindi", // "admin.access-control.groups.form.notification.deleted.failure.title": "Failed to delete group \"{{ name }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.deleted.failure.title": "Failed to delete group \"{{ name }}\"", + "admin.access-control.groups.form.notification.deleted.failure.title": "\"{{ name }}\" grubu silinemedi", // "admin.access-control.groups.form.notification.deleted.failure.content": "Cause: \"{{ cause }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.deleted.failure.content": "Cause: \"{{ cause }}\"", + "admin.access-control.groups.form.notification.deleted.failure.content": "Sorun: \"{{ cause }}\"", // "admin.access-control.groups.form.members-list.head": "EPeople", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.head": "EPeople", + "admin.access-control.groups.form.members-list.head": "E-Kişiler", // "admin.access-control.groups.form.members-list.search.head": "Add EPeople", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.search.head": "Add EPeople", + "admin.access-control.groups.form.members-list.search.head": "E-Kişiler Ekle", // "admin.access-control.groups.form.members-list.button.see-all": "Browse All", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.button.see-all": "Browse All", + "admin.access-control.groups.form.members-list.button.see-all": "Tümüne Gözat", // "admin.access-control.groups.form.members-list.headMembers": "Current Members", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.headMembers": "Current Members", + "admin.access-control.groups.form.members-list.headMembers": "Mevcut Üyeler", // "admin.access-control.groups.form.members-list.search.scope.metadata": "Metadata", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.search.scope.metadata": "Metadata", + "admin.access-control.groups.form.members-list.search.scope.metadata": "Metaveri", // "admin.access-control.groups.form.members-list.search.scope.email": "E-mail (exact)", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.search.scope.email": "E-mail (exact)", + "admin.access-control.groups.form.members-list.search.scope.email": "E-posta (tam)", // "admin.access-control.groups.form.members-list.search.button": "Search", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.search.button": "Search", + "admin.access-control.groups.form.members-list.search.button": "Ara", // "admin.access-control.groups.form.members-list.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.table.id": "ID", + "admin.access-control.groups.form.members-list.table.id": "Kimlik", // "admin.access-control.groups.form.members-list.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.table.name": "Name", + "admin.access-control.groups.form.members-list.table.name": "İsim", // "admin.access-control.groups.form.members-list.table.edit": "Remove / Add", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.table.edit": "Remove / Add", + "admin.access-control.groups.form.members-list.table.edit": "Kaldır / Ekle", // "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"", - // TODO New key - Add a translation - "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}}\" adlı üyeyi kaldırın", // "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.success.addMember": "Üye başarıyla eklendi: \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", - // TODO New key - Add a translation - "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": "Üye eklenemedi: \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Üye başarıyla silindi: \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", - // TODO New key - Add a translation - "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": "Üye silinemedi: \"{{name}}\"", // "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", - // TODO New key - Add a translation - "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}}\" adlı üye ekleyin", // "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", - // TODO New key - Add a translation - "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": "Mevcut aktif grup yok, önce bir isim gönderin.", // "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", - // TODO New key - Add a translation - "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": "Henüz grupta üye yok, arayın ve ekleyin.", // "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", + "admin.access-control.groups.form.members-list.no-items": "Bu aramada E-Kişiler bulunamadı", // "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure": "Bir şeyler yanlış gitti: \"{{cause}}\"", // "admin.access-control.groups.form.subgroups-list.head": "Groups", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.head": "Groups", + "admin.access-control.groups.form.subgroups-list.head": "Gruplar", // "admin.access-control.groups.form.subgroups-list.search.head": "Add Subgroup", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.search.head": "Add Subgroup", + "admin.access-control.groups.form.subgroups-list.search.head": "Alt Grup Ekle", // "admin.access-control.groups.form.subgroups-list.button.see-all": "Browse All", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.button.see-all": "Browse All", + "admin.access-control.groups.form.subgroups-list.button.see-all": "Tümüne Gözat", // "admin.access-control.groups.form.subgroups-list.headSubgroups": "Current Subgroups", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.headSubgroups": "Current Subgroups", + "admin.access-control.groups.form.subgroups-list.headSubgroups": "Mevcut Alt Gruplar", // "admin.access-control.groups.form.subgroups-list.search.button": "Search", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.search.button": "Search", + "admin.access-control.groups.form.subgroups-list.search.button": "Ara", // "admin.access-control.groups.form.subgroups-list.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.id": "ID", + "admin.access-control.groups.form.subgroups-list.table.id": "Kimlik", // "admin.access-control.groups.form.subgroups-list.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.name": "Name", + "admin.access-control.groups.form.subgroups-list.table.name": "İsim", // "admin.access-control.groups.form.subgroups-list.table.edit": "Remove / Add", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.edit": "Remove / Add", + "admin.access-control.groups.form.subgroups-list.table.edit": "Kaldır / Ekle", // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "Remove subgroup with name \"{{name}}\"", - // TODO New key - Add a translation - "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}}\" adlı alt grubu kaldırın", // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"", - // TODO New key - Add a translation - "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}}\" adlı alt grup ekleyin", // "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Current group", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Current group", + "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Mevcut grup", // "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Alt grup başarıyla eklendi: \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"", - // TODO New key - Add a translation - "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": "Alt grup eklenemedi: \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Alt grup başarıyla silindi: \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Failed to delete subgroup: \"{{name}}\"", - // TODO New key - Add a translation - "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": "Alt grup silinemedi: \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", - // TODO New key - Add a translation - "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": "Aktif grup mevcut değil, önce bir isim gönderin.", // "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "This is the current group, can't be added.", - // TODO New key - Add a translation - "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": "Bu grup mevcut, eklenemez.", // "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", - // TODO New key - Add a translation - "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": "Bu adla veya bu UUID olarak hiçbir grup bulunamadı", // "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", - // TODO New key - Add a translation - "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": "Henüz grupta alt grup yok.", // "admin.access-control.groups.form.return": "Return to groups", - // TODO New key - Add a translation - "admin.access-control.groups.form.return": "Return to groups", + "admin.access-control.groups.form.return": "Gruplara dön", // "admin.search.breadcrumbs": "Administrative Search", - // TODO New key - Add a translation - "admin.search.breadcrumbs": "Administrative Search", + "admin.search.breadcrumbs": "Yönetimsel Arama", // "admin.search.collection.edit": "Edit", - // TODO New key - Add a translation - "admin.search.collection.edit": "Edit", + "admin.search.collection.edit": "Düzenle", // "admin.search.community.edit": "Edit", - // TODO New key - Add a translation - "admin.search.community.edit": "Edit", + "admin.search.community.edit": "Düzenle", // "admin.search.item.delete": "Delete", - // TODO New key - Add a translation - "admin.search.item.delete": "Delete", + "admin.search.item.delete": "Sil", // "admin.search.item.edit": "Edit", - // TODO New key - Add a translation - "admin.search.item.edit": "Edit", + "admin.search.item.edit": "Düzenle", // "admin.search.item.make-private": "Make Private", - // TODO New key - Add a translation - "admin.search.item.make-private": "Make Private", + "admin.search.item.make-private": "Özel yap", // "admin.search.item.make-public": "Make Public", - // TODO New key - Add a translation - "admin.search.item.make-public": "Make Public", + "admin.search.item.make-public": "Ortak yap", // "admin.search.item.move": "Move", - // TODO New key - Add a translation - "admin.search.item.move": "Move", + "admin.search.item.move": "Taşı", // "admin.search.item.reinstate": "Reinstate", - // TODO New key - Add a translation - "admin.search.item.reinstate": "Reinstate", + "admin.search.item.reinstate": "Eski durumuna getir", // "admin.search.item.withdraw": "Withdraw", - // TODO New key - Add a translation - "admin.search.item.withdraw": "Withdraw", + "admin.search.item.withdraw": "Çekil", // "admin.search.title": "Administrative Search", - // TODO New key - Add a translation - "admin.search.title": "Administrative Search", + "admin.search.title": "Yönetimsel Arama", // "administrativeView.search.results.head": "Administrative Search", - // TODO New key - Add a translation - "administrativeView.search.results.head": "Administrative Search", + "administrativeView.search.results.head": "Yönetimsel Arama", // "admin.workflow.breadcrumbs": "Administer Workflow", - // TODO New key - Add a translation - "admin.workflow.breadcrumbs": "Administer Workflow", + "admin.workflow.breadcrumbs": "İş Akışını Yönet", // "admin.workflow.title": "Administer Workflow", - // TODO New key - Add a translation - "admin.workflow.title": "Administer Workflow", + "admin.workflow.title": "İş Akışını Yönet", // "admin.workflow.item.workflow": "Workflow", - // TODO New key - Add a translation - "admin.workflow.item.workflow": "Workflow", + "admin.workflow.item.workflow": "İş akışı", // "admin.workflow.item.delete": "Delete", - // TODO New key - Add a translation - "admin.workflow.item.delete": "Delete", + "admin.workflow.item.delete": "Sil", // "admin.workflow.item.send-back": "Send back", - // TODO New key - Add a translation - "admin.workflow.item.send-back": "Send back", + "admin.workflow.item.send-back": "Geri gönder", // "admin.metadata-import.breadcrumbs": "Import Metadata", - // TODO New key - Add a translation - "admin.metadata-import.breadcrumbs": "Import Metadata", + "admin.metadata-import.breadcrumbs": "Metaverileri İçe Aktar", // "admin.metadata-import.title": "Import Metadata", - // TODO New key - Add a translation - "admin.metadata-import.title": "Import Metadata", + "admin.metadata-import.title": "Metaverileri İçe Aktar", // "admin.metadata-import.page.header": "Import Metadata", - // TODO New key - Add a translation - "admin.metadata-import.page.header": "Import Metadata", + "admin.metadata-import.page.header": "Metaverileri İçe Aktar", // "admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here", - // TODO New key - Add a translation - "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": "Dosyalarda toplu meta veri işlemleri içeren CSV dosyalarını buraya bırakabilir veya bunlara göz atabilirsiniz.", // "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", - // TODO New key - Add a translation - "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", + "admin.metadata-import.page.dropMsg": "İçe aktarmak için bir metaveri CSV'si bırakın", // "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", - // TODO New key - Add a translation - "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", + "admin.metadata-import.page.dropMsgReplace": "İçe aktarılacak CSV metaverilerini değiştirmek için bırakın", // "admin.metadata-import.page.button.return": "Return", - // TODO New key - Add a translation - "admin.metadata-import.page.button.return": "Return", + "admin.metadata-import.page.button.return": "Geri Dön", // "admin.metadata-import.page.button.proceed": "Proceed", - // TODO New key - Add a translation - "admin.metadata-import.page.button.proceed": "Proceed", + "admin.metadata-import.page.button.proceed": "Devam Et", // "admin.metadata-import.page.error.addFile": "Select file first!", - // TODO New key - Add a translation - "admin.metadata-import.page.error.addFile": "Select file first!", + "admin.metadata-import.page.error.addFile": "Önce dosyayı seçin!", // "auth.errors.invalid-user": "Invalid email address or password.", - // TODO New key - Add a translation - "auth.errors.invalid-user": "Invalid email address or password.", + "auth.errors.invalid-user": "Geçersiz e-posta adresi veya parola.", // "auth.messages.expired": "Your session has expired. Please log in again.", - // TODO New key - Add a translation - "auth.messages.expired": "Your session has expired. Please log in again.", + "auth.messages.expired": "Oturumunuz sona erdi. Lütfen tekrar giriş yapın.", // "bitstream.edit.bitstream": "Bitstream: ", - // TODO New key - Add a translation - "bitstream.edit.bitstream": "Bitstream: ", + "bitstream.edit.bitstream": "Veri akışı: ", // "bitstream.edit.form.description.hint": "Optionally, provide a brief description of the file, for example \"Main article\" or \"Experiment data readings\".", - // TODO New key - Add a translation - "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": "İsteğe bağlı olarak, dosyanın kısa bir açıklamasını sağlayın, örneğin \"Ana makale\" veya \"Deneme veri okumaları\".", // "bitstream.edit.form.description.label": "Description", - // TODO New key - Add a translation - "bitstream.edit.form.description.label": "Description", + "bitstream.edit.form.description.label": "Açıklama", // "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.", - // TODO New key - Add a translation - "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": "Erişime izin verilen ilk gün. Bu tarih bu formda değiştirilemez. Bir veri akışı için bir ambargo tarihi ayarlamak için Öğe Durumu sekmesine gidin, Yetkiler...'i tıklayın., veri akışının OKU politikasını oluşturun veya düzenleyin ve Başlangıç ​​Tarihi'ni istediğiniz gibi ayarlayın.", // "bitstream.edit.form.embargo.label": "Embargo until specific date", - // TODO New key - Add a translation - "bitstream.edit.form.embargo.label": "Embargo until specific date", + "bitstream.edit.form.embargo.label": "Belirli bir tarihe kadar ambargo", // "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.", - // TODO New key - Add a translation - "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": "Veri akışının dosya adını değiştirin. Bunun görünen veri akışı URL'sini değiştireceğini, ancak dizi kimliği değişmediği sürece eski bağlantıların çözüleceğini unutmayın.", // "bitstream.edit.form.fileName.label": "Filename", - // TODO New key - Add a translation - "bitstream.edit.form.fileName.label": "Filename", + "bitstream.edit.form.fileName.label": "Dosya adı", // "bitstream.edit.form.newFormat.label": "Describe new format", - // TODO New key - Add a translation - "bitstream.edit.form.newFormat.label": "Describe new format", + "bitstream.edit.form.newFormat.label": "Yeni biçimi tanımla", // "bitstream.edit.form.newFormat.hint": "The application you used to create the file, and the version number (for example, \"ACMESoft SuperApp version 1.5\").", - // TODO New key - Add a translation - "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": "Dosyayı oluşturmak için kullandığınız uygulama ve sürüm numarası (örneğin, \"ACMESoft SuperApp versiyon 1.5\").", // "bitstream.edit.form.primaryBitstream.label": "Primary bitstream", - // TODO New key - Add a translation - "bitstream.edit.form.primaryBitstream.label": "Primary bitstream", + "bitstream.edit.form.primaryBitstream.label": "Birincil veri akışı", // "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\".", - // TODO New key - Add a translation - "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": "Biçim yukarıdaki listede yoksa, select \"listede olmayan biçim\"i above ve \"Yeni biçimi tanımla\" altında açıklayın.", // "bitstream.edit.form.selectedFormat.label": "Selected Format", - // TODO New key - Add a translation - "bitstream.edit.form.selectedFormat.label": "Selected Format", + "bitstream.edit.form.selectedFormat.label": "Seçilen Biçim", // "bitstream.edit.form.selectedFormat.unknown": "Format not in list", - // TODO New key - Add a translation - "bitstream.edit.form.selectedFormat.unknown": "Format not in list", + "bitstream.edit.form.selectedFormat.unknown": "Listede olmayan biçim", // "bitstream.edit.notifications.error.format.title": "An error occurred saving the bitstream's format", - // TODO New key - Add a translation - "bitstream.edit.notifications.error.format.title": "An error occurred saving the bitstream's format", + "bitstream.edit.notifications.error.format.title": "Veri akışının biçimi kaydedilirken bir hata oluştu", // "bitstream.edit.notifications.saved.content": "Your changes to this bitstream were saved.", - // TODO New key - Add a translation - "bitstream.edit.notifications.saved.content": "Your changes to this bitstream were saved.", + "bitstream.edit.notifications.saved.content": "Bu veri akışında yaptığınız değişiklikler kaydedildi.", // "bitstream.edit.notifications.saved.title": "Bitstream saved", - // TODO New key - Add a translation - "bitstream.edit.notifications.saved.title": "Bitstream saved", + "bitstream.edit.notifications.saved.title": "Veri akışı kaydedildi", // "bitstream.edit.title": "Edit bitstream", - // TODO New key - Add a translation - "bitstream.edit.title": "Edit bitstream", + "bitstream.edit.title": "Veri akışını düzenle", // "browse.comcol.by.author": "By Author", - // TODO New key - Add a translation - "browse.comcol.by.author": "By Author", + "browse.comcol.by.author": "Yazara Göre", // "browse.comcol.by.dateissued": "By Issue Date", - // TODO New key - Add a translation - "browse.comcol.by.dateissued": "By Issue Date", + "browse.comcol.by.dateissued": "Çıkarma Tarihine Göre", // "browse.comcol.by.subject": "By Subject", - // TODO New key - Add a translation - "browse.comcol.by.subject": "By Subject", + "browse.comcol.by.subject": "Konuya Göre", // "browse.comcol.by.title": "By Title", - // TODO New key - Add a translation - "browse.comcol.by.title": "By Title", + "browse.comcol.by.title": "Başlığa Göre", // "browse.comcol.head": "Browse", - // TODO New key - Add a translation - "browse.comcol.head": "Browse", + "browse.comcol.head": "Gözat", // "browse.empty": "No items to show.", - // TODO New key - Add a translation - "browse.empty": "No items to show.", + "browse.empty": "Gösterilecek öğe yok.", // "browse.metadata.author": "Author", - // TODO New key - Add a translation - "browse.metadata.author": "Author", + "browse.metadata.author": "Yazar", // "browse.metadata.dateissued": "Issue Date", - // TODO New key - Add a translation - "browse.metadata.dateissued": "Issue Date", + "browse.metadata.dateissued": "Çıkarma tarihi", // "browse.metadata.subject": "Subject", - // TODO New key - Add a translation - "browse.metadata.subject": "Subject", + "browse.metadata.subject": "Konu", // "browse.metadata.title": "Title", - // TODO New key - Add a translation - "browse.metadata.title": "Title", + "browse.metadata.title": "Başlık", // "browse.metadata.author.breadcrumbs": "Browse by Author", - // TODO New key - Add a translation - "browse.metadata.author.breadcrumbs": "Browse by Author", + "browse.metadata.author.breadcrumbs": "Yazara Göre Gözat", // "browse.metadata.dateissued.breadcrumbs": "Browse by Date", - // TODO New key - Add a translation - "browse.metadata.dateissued.breadcrumbs": "Browse by Date", + "browse.metadata.dateissued.breadcrumbs": "Tarihe Göre Gözat", // "browse.metadata.subject.breadcrumbs": "Browse by Subject", - // TODO New key - Add a translation - "browse.metadata.subject.breadcrumbs": "Browse by Subject", + "browse.metadata.subject.breadcrumbs": "Konuya Göre Gözat", // "browse.metadata.title.breadcrumbs": "Browse by Title", - // TODO New key - Add a translation - "browse.metadata.title.breadcrumbs": "Browse by Title", + "browse.metadata.title.breadcrumbs": "Başlığa göre göz atın", // "browse.startsWith.choose_start": "(Choose start)", - // TODO New key - Add a translation - "browse.startsWith.choose_start": "(Choose start)", + "browse.startsWith.choose_start": "(Başlangıç seç)", // "browse.startsWith.choose_year": "(Choose year)", - // TODO New key - Add a translation - "browse.startsWith.choose_year": "(Choose year)", + "browse.startsWith.choose_year": "(Yıl seç)", // "browse.startsWith.jump": "Jump to a point in the index:", - // TODO New key - Add a translation - "browse.startsWith.jump": "Jump to a point in the index:", + "browse.startsWith.jump": "Dizinde bir noktaya atla:", // "browse.startsWith.months.april": "April", - // TODO New key - Add a translation - "browse.startsWith.months.april": "April", + "browse.startsWith.months.april": "Nisan", // "browse.startsWith.months.august": "August", - // TODO New key - Add a translation - "browse.startsWith.months.august": "August", + "browse.startsWith.months.august": "Ağustos", // "browse.startsWith.months.december": "December", - // TODO New key - Add a translation - "browse.startsWith.months.december": "December", + "browse.startsWith.months.december": "Aralık", // "browse.startsWith.months.february": "February", - // TODO New key - Add a translation - "browse.startsWith.months.february": "February", + "browse.startsWith.months.february": "Şubat", // "browse.startsWith.months.january": "January", - // TODO New key - Add a translation - "browse.startsWith.months.january": "January", + "browse.startsWith.months.january": "Ocak", // "browse.startsWith.months.july": "July", - // TODO New key - Add a translation - "browse.startsWith.months.july": "July", + "browse.startsWith.months.july": "Temmuz", // "browse.startsWith.months.june": "June", - // TODO New key - Add a translation - "browse.startsWith.months.june": "June", + "browse.startsWith.months.june": "Haziran", // "browse.startsWith.months.march": "March", - // TODO New key - Add a translation - "browse.startsWith.months.march": "March", + "browse.startsWith.months.march": "Mart", // "browse.startsWith.months.may": "May", - // TODO New key - Add a translation - "browse.startsWith.months.may": "May", + "browse.startsWith.months.may": "Mayıs", // "browse.startsWith.months.none": "(Choose month)", - // TODO New key - Add a translation - "browse.startsWith.months.none": "(Choose month)", + "browse.startsWith.months.none": "(Ay seçin)", // "browse.startsWith.months.november": "November", - // TODO New key - Add a translation - "browse.startsWith.months.november": "November", + "browse.startsWith.months.november": "Kasım", // "browse.startsWith.months.october": "October", - // TODO New key - Add a translation - "browse.startsWith.months.october": "October", + "browse.startsWith.months.october": "Ekim", // "browse.startsWith.months.september": "September", - // TODO New key - Add a translation - "browse.startsWith.months.september": "September", + "browse.startsWith.months.september": "Eylül", // "browse.startsWith.submit": "Go", - // TODO New key - Add a translation - "browse.startsWith.submit": "Go", + "browse.startsWith.submit": "Git", // "browse.startsWith.type_date": "Or type in a date (year-month):", - // TODO New key - Add a translation - "browse.startsWith.type_date": "Or type in a date (year-month):", + "browse.startsWith.type_date": "Veya bir tarih yazın (yıl-ay):", // "browse.startsWith.type_text": "Or enter first few letters:", - // TODO New key - Add a translation - "browse.startsWith.type_text": "Or enter first few letters:", + "browse.startsWith.type_text": "Veya ilk birkaç harfi girin:", // "browse.title": "Browsing {{ collection }} by {{ field }} {{ value }}", - // TODO New key - Add a translation - "browse.title": "Browsing {{ collection }} by {{ field }} {{ value }}", + "browse.title": "{{ field }} {{ value }} ile {{ collection }}'a göz atma", // "chips.remove": "Remove chip", - // TODO New key - Add a translation - "chips.remove": "Remove chip", + "chips.remove": "Çipi kaldır", // "collection.create.head": "Create a Collection", - // TODO New key - Add a translation - "collection.create.head": "Create a Collection", + "collection.create.head": "Koleksiyon Oluştur", // "collection.create.notifications.success": "Successfully created the Collection", - // TODO New key - Add a translation - "collection.create.notifications.success": "Successfully created the Collection", + "collection.create.notifications.success": "Koleksiyon başarıyla oluşturuldu", // "collection.create.sub-head": "Create a Collection for Community {{ parent }}", - // TODO New key - Add a translation - "collection.create.sub-head": "Create a Collection for Community {{ parent }}", + "collection.create.sub-head": "Topluluk için Koleksiyon Oluşturun {{ parent }}", // "collection.curate.header": "Curate Collection: {{collection}}", - // TODO New key - Add a translation - "collection.curate.header": "Curate Collection: {{collection}}", + "collection.curate.header": "Koleksiyonu Düzenle: {{collection}}", // "collection.delete.cancel": "Cancel", - // TODO New key - Add a translation - "collection.delete.cancel": "Cancel", + "collection.delete.cancel": "İptal", // "collection.delete.confirm": "Confirm", - // TODO New key - Add a translation - "collection.delete.confirm": "Confirm", + "collection.delete.confirm": "Onayla", // "collection.delete.head": "Delete Collection", - // TODO New key - Add a translation - "collection.delete.head": "Delete Collection", + "collection.delete.head": "Koleksiyonu sil", // "collection.delete.notification.fail": "Collection could not be deleted", - // TODO New key - Add a translation - "collection.delete.notification.fail": "Collection could not be deleted", + "collection.delete.notification.fail": "Koleksiyon silinemedi", // "collection.delete.notification.success": "Successfully deleted collection", - // TODO New key - Add a translation - "collection.delete.notification.success": "Successfully deleted collection", + "collection.delete.notification.success": "Koleksiyon başarıyla silindi", // "collection.delete.text": "Are you sure you want to delete collection \"{{ dso }}\"", - // TODO New key - Add a translation - "collection.delete.text": "Are you sure you want to delete collection \"{{ dso }}\"", + "collection.delete.text": "\"{{ dso }}\" koleksiyonunu silmek istediğinizden emin misiniz?", // "collection.edit.delete": "Delete this collection", - // TODO New key - Add a translation - "collection.edit.delete": "Delete this collection", + "collection.edit.delete": "Bu koleksiyonu sil", // "collection.edit.head": "Edit Collection", - // TODO New key - Add a translation - "collection.edit.head": "Edit Collection", + "collection.edit.head": "Koleksiyonu Düzenle", // "collection.edit.breadcrumbs": "Edit Collection", - // TODO New key - Add a translation - "collection.edit.breadcrumbs": "Edit Collection", + "collection.edit.breadcrumbs": "Koleksiyonu Düzenle", // "collection.edit.tabs.mapper.head": "Item Mapper", - // TODO New key - Add a translation - "collection.edit.tabs.mapper.head": "Item Mapper", + "collection.edit.tabs.mapper.head": "Öğe eşleştirici", // "collection.edit.tabs.item-mapper.title": "Collection Edit - Item Mapper", - // TODO New key - Add a translation - "collection.edit.tabs.item-mapper.title": "Collection Edit - Item Mapper", + "collection.edit.tabs.item-mapper.title": "Koleksiyon Düzenleme - Öğe Eşleştirici", // "collection.edit.item-mapper.cancel": "Cancel", - // TODO New key - Add a translation - "collection.edit.item-mapper.cancel": "Cancel", + "collection.edit.item-mapper.cancel": "İptal", // "collection.edit.item-mapper.collection": "Collection: \"{{name}}\"", - // TODO New key - Add a translation - "collection.edit.item-mapper.collection": "Collection: \"{{name}}\"", + "collection.edit.item-mapper.collection": "Koleksiyon: \"{{name}}\"", // "collection.edit.item-mapper.confirm": "Map selected items", - // TODO New key - Add a translation - "collection.edit.item-mapper.confirm": "Map selected items", + "collection.edit.item-mapper.confirm": "Seçilen öğeleri eşle", // "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.", - // TODO New key - Add a translation - "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": "Bu, koleksiyon yöneticilerinin diğer koleksiyonlardaki öğeleri bu koleksiyona eşlemelerine olanak tanıyan öğe eşleyici aracıdır. Diğer koleksiyonlardaki öğeleri arayabilir ve bunları eşleyebilir veya şu anda eşlenmiş öğelerin listesine göz atabilirsiniz.", // "collection.edit.item-mapper.head": "Item Mapper - Map Items from Other Collections", - // TODO New key - Add a translation - "collection.edit.item-mapper.head": "Item Mapper - Map Items from Other Collections", + "collection.edit.item-mapper.head": "Öğe Eşleştirici - Diğer Koleksiyonlardaki Öğeleri Eşle", // "collection.edit.item-mapper.no-search": "Please enter a query to search", - // TODO New key - Add a translation - "collection.edit.item-mapper.no-search": "Please enter a query to search", + "collection.edit.item-mapper.no-search": "Lütfen aramak için bir sorgu girin", // "collection.edit.item-mapper.notifications.map.error.content": "Errors occurred for mapping of {{amount}} items.", - // TODO New key - Add a translation - "collection.edit.item-mapper.notifications.map.error.content": "Errors occurred for mapping of {{amount}} items.", + "collection.edit.item-mapper.notifications.map.error.content": "{{amount}} öğenin eşlenmesinde hatalar oluştu.", // "collection.edit.item-mapper.notifications.map.error.head": "Mapping errors", - // TODO New key - Add a translation - "collection.edit.item-mapper.notifications.map.error.head": "Mapping errors", + "collection.edit.item-mapper.notifications.map.error.head": "Eşleme hataları", // "collection.edit.item-mapper.notifications.map.success.content": "Successfully mapped {{amount}} items.", - // TODO New key - Add a translation - "collection.edit.item-mapper.notifications.map.success.content": "Successfully mapped {{amount}} items.", + "collection.edit.item-mapper.notifications.map.success.content": "{{amount}} öğe başarıyla eşlendi.", // "collection.edit.item-mapper.notifications.map.success.head": "Mapping completed", - // TODO New key - Add a translation - "collection.edit.item-mapper.notifications.map.success.head": "Mapping completed", + "collection.edit.item-mapper.notifications.map.success.head": "Eşleme tamamlandı", // "collection.edit.item-mapper.notifications.unmap.error.content": "Errors occurred for removing the mappings of {{amount}} items.", - // TODO New key - Add a translation - "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}} öğenin eşlemeleri kaldırılırken hatalar oluştu.", // "collection.edit.item-mapper.notifications.unmap.error.head": "Remove mapping errors", - // TODO New key - Add a translation - "collection.edit.item-mapper.notifications.unmap.error.head": "Remove mapping errors", + "collection.edit.item-mapper.notifications.unmap.error.head": "Eşleme hatalarını kaldır", // "collection.edit.item-mapper.notifications.unmap.success.content": "Successfully removed the mappings of {{amount}} items.", - // TODO New key - Add a translation - "collection.edit.item-mapper.notifications.unmap.success.content": "Successfully removed the mappings of {{amount}} items.", + "collection.edit.item-mapper.notifications.unmap.success.content": "{{amount}} öğenin eşlemeleri başarıyla kaldırıldı.", // "collection.edit.item-mapper.notifications.unmap.success.head": "Remove mapping completed", - // TODO New key - Add a translation - "collection.edit.item-mapper.notifications.unmap.success.head": "Remove mapping completed", + "collection.edit.item-mapper.notifications.unmap.success.head": "Eşlemeyi kaldır tamamlandı", // "collection.edit.item-mapper.remove": "Remove selected item mappings", - // TODO New key - Add a translation - "collection.edit.item-mapper.remove": "Remove selected item mappings", + "collection.edit.item-mapper.remove": "Seçili öğe eşlemelerini kaldır", // "collection.edit.item-mapper.tabs.browse": "Browse mapped items", - // TODO New key - Add a translation - "collection.edit.item-mapper.tabs.browse": "Browse mapped items", + "collection.edit.item-mapper.tabs.browse": "Eşlenen öğelere göz atın", // "collection.edit.item-mapper.tabs.map": "Map new items", - // TODO New key - Add a translation - "collection.edit.item-mapper.tabs.map": "Map new items", + "collection.edit.item-mapper.tabs.map": "Yeni öğeleri işle", // "collection.edit.logo.label": "Collection logo", - // TODO New key - Add a translation - "collection.edit.logo.label": "Collection logo", - + "collection.edit.logo.label": "Koleksiyon logosu", + // "collection.edit.logo.notifications.add.error": "Uploading Collection logo failed. Please verify the content before retrying.", - // TODO New key - Add a translation - "collection.edit.logo.notifications.add.error": "Uploading Collection logo failed. Please verify the content before retrying.", + "collection.edit.logo.notifications.add.error": "Koleksiyon logosu yüklemesi başarısız. Lütfen yeniden denemeden önce içeriği doğrulayın.", // "collection.edit.logo.notifications.add.success": "Upload Collection logo successful.", - // TODO New key - Add a translation - "collection.edit.logo.notifications.add.success": "Upload Collection logo successful.", + "collection.edit.logo.notifications.add.success": "Koleksiyon logosu yüklemesi başarılı.", // "collection.edit.logo.notifications.delete.success.title": "Logo deleted", - // TODO New key - Add a translation - "collection.edit.logo.notifications.delete.success.title": "Logo deleted", + "collection.edit.logo.notifications.delete.success.title": "Logo silindi", // "collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo", - // TODO New key - Add a translation - "collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo", + "collection.edit.logo.notifications.delete.success.content": "Koleksiyonun logosunu başarıyla silindi", // "collection.edit.logo.notifications.delete.error.title": "Error deleting logo", - // TODO New key - Add a translation - "collection.edit.logo.notifications.delete.error.title": "Error deleting logo", + "collection.edit.logo.notifications.delete.error.title": "Logo silinirken hata", // "collection.edit.logo.upload": "Drop a Collection Logo to upload", - // TODO New key - Add a translation - "collection.edit.logo.upload": "Drop a Collection Logo to upload", + "collection.edit.logo.upload": "Yüklenecek bir koleksiyon logosu bırakın", // "collection.edit.notifications.success": "Successfully edited the Collection", - // TODO New key - Add a translation - "collection.edit.notifications.success": "Successfully edited the Collection", + "collection.edit.notifications.success": "Koleksiyon başarıyla düzenlendi.", // "collection.edit.return": "Return", - // TODO New key - Add a translation - "collection.edit.return": "Return", + "collection.edit.return": "Dönüş", // "collection.edit.tabs.curate.head": "Curate", - // TODO New key - Add a translation - "collection.edit.tabs.curate.head": "Curate", + "collection.edit.tabs.curate.head": "Kuratör", // "collection.edit.tabs.curate.title": "Collection Edit - Curate", - // TODO New key - Add a translation - "collection.edit.tabs.curate.title": "Collection Edit - Curate", + "collection.edit.tabs.curate.title": "Koleksiyon düzenleme - Küratör", // "collection.edit.tabs.authorizations.head": "Authorizations", - // TODO New key - Add a translation - "collection.edit.tabs.authorizations.head": "Authorizations", + "collection.edit.tabs.authorizations.head": "Yetkilendirmeler", // "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", - // TODO New key - Add a translation - "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", + "collection.edit.tabs.authorizations.title": "Koleksiyon düzenleme - Yetkilendirmeler", // "collection.edit.tabs.metadata.head": "Edit Metadata", - // TODO New key - Add a translation - "collection.edit.tabs.metadata.head": "Edit Metadata", + "collection.edit.tabs.metadata.head": "Meta Verileri Düzenle", // "collection.edit.tabs.metadata.title": "Collection Edit - Metadata", - // TODO New key - Add a translation - "collection.edit.tabs.metadata.title": "Collection Edit - Metadata", + "collection.edit.tabs.metadata.title": "Koleksiyon Düzenle - Meta Veriler", // "collection.edit.tabs.roles.head": "Assign Roles", - // TODO New key - Add a translation - "collection.edit.tabs.roles.head": "Assign Roles", + "collection.edit.tabs.roles.head": "Rol atamak", // "collection.edit.tabs.roles.title": "Collection Edit - Roles", - // TODO New key - Add a translation - "collection.edit.tabs.roles.title": "Collection Edit - Roles", + "collection.edit.tabs.roles.title": "Koleksiyon düzenleme - Roller", // "collection.edit.tabs.source.external": "This collection harvests its content from an external source", - // TODO New key - Add a translation - "collection.edit.tabs.source.external": "This collection harvests its content from an external source", + "collection.edit.tabs.source.external": "Bu koleksiyon içeriğini harici bir kaynaktan toplar", // "collection.edit.tabs.source.form.errors.oaiSource.required": "You must provide a set id of the target collection.", - // TODO New key - Add a translation - "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": "Hedef koleksiyonuna bir set kimliği sağlamalısınız.", // "collection.edit.tabs.source.form.harvestType": "Content being harvested", - // TODO New key - Add a translation - "collection.edit.tabs.source.form.harvestType": "Content being harvested", + "collection.edit.tabs.source.form.harvestType": "İçerik harmanlanıyor", // "collection.edit.tabs.source.form.head": "Configure an external source", - // TODO New key - Add a translation - "collection.edit.tabs.source.form.head": "Configure an external source", + "collection.edit.tabs.source.form.head": "Harici bir kaynak yapılandır", // "collection.edit.tabs.source.form.metadataConfigId": "Metadata Format", - // TODO New key - Add a translation - "collection.edit.tabs.source.form.metadataConfigId": "Metadata Format", + "collection.edit.tabs.source.form.metadataConfigId": "Meta veri formatı", // "collection.edit.tabs.source.form.oaiSetId": "OAI specific set id", - // TODO New key - Add a translation - "collection.edit.tabs.source.form.oaiSetId": "OAI specific set id", + "collection.edit.tabs.source.form.oaiSetId": "OAI'ya Özel Set Kimliği", // "collection.edit.tabs.source.form.oaiSource": "OAI Provider", - // TODO New key - Add a translation - "collection.edit.tabs.source.form.oaiSource": "OAI Provider", + "collection.edit.tabs.source.form.oaiSource": "OAI Sağlayıcısı", // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "Harvest metadata and bitstreams (requires ORE support)", - // TODO New key - Add a translation - "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": "Meta verilerini ve veri akışını topla (ORE desteği gerektirir)", - // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "Harvest metadata and references to bitstreams (requires ORE support)", - // TODO New key - Add a translation - "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": "Harvest metadata and references to bitstreams (ORE desteği gerektirir)", + "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "Meta verilerini ve referansları topla (ORE desteği gerektirir)", // "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "Harvest metadata only", - // TODO New key - Add a translation - "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "Harvest metadata only", + "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "Sadece meta verilerini topla", // "collection.edit.tabs.source.head": "Content Source", - // TODO New key - Add a translation - "collection.edit.tabs.source.head": "Content Source", + "collection.edit.tabs.source.head": "İçerik Kaynağı", // "collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - // TODO New key - Add a translation - "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": "Değişiklikleriniz silindi. Değişikliklerinizi eski haline getirmek için 'Geri Al' düğmesine tıklayın.", // "collection.edit.tabs.source.notifications.discarded.title": "Changed discarded", - // TODO New key - Add a translation - "collection.edit.tabs.source.notifications.discarded.title": "Changed discarded", + "collection.edit.tabs.source.notifications.discarded.title": "Silinenler değiştirildi.", // "collection.edit.tabs.source.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", - // TODO New key - Add a translation - "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": "Değişiklikleriniz kaydedilmedi. Lütfen kaydetmeden önce tüm alanların geçerli olduğundan emin olun.", // "collection.edit.tabs.source.notifications.invalid.title": "Metadata invalid", - // TODO New key - Add a translation - "collection.edit.tabs.source.notifications.invalid.title": "Metadata invalid", + "collection.edit.tabs.source.notifications.invalid.title": "Meta veri geçersiz", // "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", - // TODO New key - Add a translation - "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", + "collection.edit.tabs.source.notifications.saved.content": "Bu koleksiyonun içerik kaynağındaki değişiklikleriniz kaydedildi.", // "collection.edit.tabs.source.notifications.saved.title": "Content Source saved", - // TODO New key - Add a translation - "collection.edit.tabs.source.notifications.saved.title": "Content Source saved", + "collection.edit.tabs.source.notifications.saved.title": "İçerik Kaynağı kaydedildi", // "collection.edit.tabs.source.title": "Collection Edit - Content Source", - // TODO New key - Add a translation - "collection.edit.tabs.source.title": "Collection Edit - Content Source", + "collection.edit.tabs.source.title": "Koleksiyon düzenleme - İçerik Kaynağı", // "collection.edit.template.add-button": "Add", - // TODO New key - Add a translation - "collection.edit.template.add-button": "Add", + "collection.edit.template.add-button": "Ekle", // "collection.edit.template.breadcrumbs": "Item template", - // TODO New key - Add a translation - "collection.edit.template.breadcrumbs": "Item template", + "collection.edit.template.breadcrumbs": "Öğe şablonu", // "collection.edit.template.cancel": "Cancel", - // TODO New key - Add a translation - "collection.edit.template.cancel": "Cancel", + "collection.edit.template.cancel": "İptal", // "collection.edit.template.delete-button": "Delete", - // TODO New key - Add a translation - "collection.edit.template.delete-button": "Delete", + "collection.edit.template.delete-button": "Sil", // "collection.edit.template.edit-button": "Edit", - // TODO New key - Add a translation - "collection.edit.template.edit-button": "Edit", + "collection.edit.template.edit-button": "Düzenle", // "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", - // TODO New key - Add a translation - "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", + "collection.edit.template.head": "Koleksiyon için Sablon Öğesini Düzenleyin \"{{ collection }}\"", // "collection.edit.template.label": "Template item", - // TODO New key - Add a translation - "collection.edit.template.label": "Template item", + "collection.edit.template.label": "Şablon öğe", // "collection.edit.template.notifications.delete.error": "Failed to delete the item template", - // TODO New key - Add a translation - "collection.edit.template.notifications.delete.error": "Failed to delete the item template", + "collection.edit.template.notifications.delete.error": "Öğe şablonu silme başarısız", // "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", - // TODO New key - Add a translation - "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", + "collection.edit.template.notifications.delete.success": "Öğe şablonu başarıyla silindi", // "collection.edit.template.title": "Edit Template Item", - // TODO New key - Add a translation - "collection.edit.template.title": "Edit Template Item", + "collection.edit.template.title": "Şablon Öğesini Düzenle", // "collection.form.abstract": "Short Description", - // TODO New key - Add a translation - "collection.form.abstract": "Short Description", + "collection.form.abstract": "Kısa Açıklama", // "collection.form.description": "Introductory text (HTML)", - // TODO New key - Add a translation - "collection.form.description": "Introductory text (HTML)", + "collection.form.description": "Tanıtım metni (HTML)", // "collection.form.errors.title.required": "Please enter a collection name", - // TODO New key - Add a translation - "collection.form.errors.title.required": "Please enter a collection name", + "collection.form.errors.title.required": "Lütfen bir koleksiyon adı girin", // "collection.form.license": "License", - // TODO New key - Add a translation - "collection.form.license": "License", + "collection.form.license": "Lisans", // "collection.form.provenance": "Provenance", - // TODO New key - Add a translation - "collection.form.provenance": "Provenance", + "collection.form.provenance": "Menşei", // "collection.form.rights": "Copyright text (HTML)", - // TODO New key - Add a translation - "collection.form.rights": "Copyright text (HTML)", + "collection.form.rights": "Telif hakkı metni (HTML)", // "collection.form.tableofcontents": "News (HTML)", - // TODO New key - Add a translation - "collection.form.tableofcontents": "News (HTML)", + "collection.form.tableofcontents": "Haberler (HTML)", // "collection.form.title": "Name", - // TODO New key - Add a translation - "collection.form.title": "Name", + "collection.form.title": "İsim", // "collection.listelement.badge": "Collection", - // TODO New key - Add a translation - "collection.listelement.badge": "Collection", + "collection.listelement.badge": "Koleksiyon", // "collection.page.browse.recent.head": "Recent Submissions", - // TODO New key - Add a translation - "collection.page.browse.recent.head": "Recent Submissions", + "collection.page.browse.recent.head": "Son Başvurular", // "collection.page.browse.recent.empty": "No items to show", - // TODO New key - Add a translation - "collection.page.browse.recent.empty": "No items to show", + "collection.page.browse.recent.empty": "Gösterilecek öğe yok", // "collection.page.edit": "Edit this collection", - // TODO New key - Add a translation - "collection.page.edit": "Edit this collection", + "collection.page.edit": "Bu koleksiyonu düzenleyin", // "collection.page.handle": "Permanent URI for this collection", - // TODO New key - Add a translation - "collection.page.handle": "Permanent URI for this collection", + "collection.page.handle": "Bu koleksiyon için kalıcı URI", // "collection.page.license": "License", - // TODO New key - Add a translation - "collection.page.license": "License", + "collection.page.license": "Lisans", // "collection.page.news": "News", - // TODO New key - Add a translation - "collection.page.news": "News", + "collection.page.news": "Haberler", // "collection.select.confirm": "Confirm selected", - // TODO New key - Add a translation - "collection.select.confirm": "Confirm selected", + "collection.select.confirm": "Seçilileri onayla", // "collection.select.empty": "No collections to show", - // TODO New key - Add a translation - "collection.select.empty": "No collections to show", + "collection.select.empty": "Gösterilecek koleksiyon yok", // "collection.select.table.title": "Title", - // TODO New key - Add a translation - "collection.select.table.title": "Title", + "collection.select.table.title": "Başlık", // "collection.source.update.notifications.error.content": "The provided settings have been tested and didn't work.", - // TODO New key - Add a translation - "collection.source.update.notifications.error.content": "The provided settings have been tested and didn't work.", + "collection.source.update.notifications.error.content": "Sağlanan ayarlar test edildi ve işe yaramadı.", // "collection.source.update.notifications.error.title": "Server Error", - // TODO New key - Add a translation - "collection.source.update.notifications.error.title": "Server Error", + "collection.source.update.notifications.error.title": "Sunucu Hatası", // "communityList.tabTitle": "DSpace - Community List", - // TODO New key - Add a translation - "communityList.tabTitle": "DSpace - Community List", + "communityList.tabTitle": "DSpace - Topluluk Listesi", // "communityList.title": "List of Communities", - // TODO New key - Add a translation - "communityList.title": "List of Communities", + "communityList.title": "Toplulukların Listesi", // "communityList.showMore": "Show More", - // TODO New key - Add a translation - "communityList.showMore": "Show More", + "communityList.showMore": "Daha fazla göster", // "community.create.head": "Create a Community", - // TODO New key - Add a translation - "community.create.head": "Create a Community", + "community.create.head": "Bir topluluk oluştur", // "community.create.notifications.success": "Successfully created the Community", - // TODO New key - Add a translation - "community.create.notifications.success": "Successfully created the Community", + "community.create.notifications.success": "Topluluk başarıyla yaratıldı", // "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", - // TODO New key - Add a translation - "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", + "community.create.sub-head": "Topluluk için bir alt topluluk oluşturun {{ parent }}", // "community.curate.header": "Curate Community: {{community}}", - // TODO New key - Add a translation - "community.curate.header": "Curate Community: {{community}}", + "community.curate.header": "Kuratör topluluğu: {{community}}", // "community.delete.cancel": "Cancel", - // TODO New key - Add a translation - "community.delete.cancel": "Cancel", + "community.delete.cancel": "İptal", // "community.delete.confirm": "Confirm", - // TODO New key - Add a translation - "community.delete.confirm": "Confirm", + "community.delete.confirm": "Onayla", // "community.delete.head": "Delete Community", - // TODO New key - Add a translation - "community.delete.head": "Delete Community", + "community.delete.head": "Topluluğu sil", // "community.delete.notification.fail": "Community could not be deleted", - // TODO New key - Add a translation - "community.delete.notification.fail": "Community could not be deleted", + "community.delete.notification.fail": "Topluluk silinemedi", // "community.delete.notification.success": "Successfully deleted community", - // TODO New key - Add a translation - "community.delete.notification.success": "Successfully deleted community", + "community.delete.notification.success": "Topluluk başarıyla silindi", // "community.delete.text": "Are you sure you want to delete community \"{{ dso }}\"", - // TODO New key - Add a translation - "community.delete.text": "Are you sure you want to delete community \"{{ dso }}\"", + "community.delete.text": "Topluluğu silmek istediğinize emin misiniz \"{{ dso }}\"", // "community.edit.delete": "Delete this community", - // TODO New key - Add a translation - "community.edit.delete": "Delete this community", + "community.edit.delete": "Bu topluluğu sil", // "community.edit.head": "Edit Community", - // TODO New key - Add a translation - "community.edit.head": "Edit Community", + "community.edit.head": "Topluluğu düzenle", // "community.edit.breadcrumbs": "Edit Community", - // TODO New key - Add a translation - "community.edit.breadcrumbs": "Edit Community", + "community.edit.breadcrumbs": "Topluluğu düzenle", // "community.edit.logo.label": "Community logo", - // TODO New key - Add a translation - "community.edit.logo.label": "Community logo", + "community.edit.logo.label": "Topluluk logosu", // "community.edit.logo.notifications.add.error": "Uploading Community logo failed. Please verify the content before retrying.", - // TODO New key - Add a translation - "community.edit.logo.notifications.add.error": "Uploading Community logo failed. Please verify the content before retrying.", + "community.edit.logo.notifications.add.error": "Topluluk logosu yüklemesi başarısız. Lütfen yeniden denemeden önce içeriği doğrulayın.", // "community.edit.logo.notifications.add.success": "Upload Community logo successful.", - // TODO New key - Add a translation - "community.edit.logo.notifications.add.success": "Upload Community logo successful.", + "community.edit.logo.notifications.add.success": "Topluluk logosunu başarılı yükle.", // "community.edit.logo.notifications.delete.success.title": "Logo deleted", - // TODO New key - Add a translation - "community.edit.logo.notifications.delete.success.title": "Logo deleted", + "community.edit.logo.notifications.delete.success.title": "Logo silindi", // "community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo", - // TODO New key - Add a translation - "community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo", + "community.edit.logo.notifications.delete.success.content": "Topluluk logosu başarıyla silindi", // "community.edit.logo.notifications.delete.error.title": "Error deleting logo", - // TODO New key - Add a translation - "community.edit.logo.notifications.delete.error.title": "Error deleting logo", + "community.edit.logo.notifications.delete.error.title": "Logo silme hatası", // "community.edit.logo.upload": "Drop a Community Logo to upload", - // TODO New key - Add a translation - "community.edit.logo.upload": "Drop a Community Logo to upload", + "community.edit.logo.upload": "Yüklenecek bir topluluk logosu bırak", // "community.edit.notifications.success": "Successfully edited the Community", - // TODO New key - Add a translation - "community.edit.notifications.success": "Successfully edited the Community", + "community.edit.notifications.success": "Topluluk başarıyla düzenlendi", // "community.edit.notifications.unauthorized": "You do not have privileges to make this change", - // TODO New key - Add a translation - "community.edit.notifications.unauthorized": "You do not have privileges to make this change", + "community.edit.notifications.unauthorized": "Bu değişikliği yapmak için ayrıcalıklarınız yok", // "community.edit.notifications.error": "An error occured while editing the Community", - // TODO New key - Add a translation - "community.edit.notifications.error": "An error occured while editing the Community", + "community.edit.notifications.error": "Topluluğu düzenlerken bir hata oluştu", // "community.edit.return": "Return", - // TODO New key - Add a translation - "community.edit.return": "Return", + "community.edit.return": "Dönüş", // "community.edit.tabs.curate.head": "Curate", - // TODO New key - Add a translation - "community.edit.tabs.curate.head": "Curate", + "community.edit.tabs.curate.head": "Kuratör", // "community.edit.tabs.curate.title": "Community Edit - Curate", - // TODO New key - Add a translation - "community.edit.tabs.curate.title": "Community Edit - Curate", + "community.edit.tabs.curate.title": "Topluluk Düzenle - Küratör", // "community.edit.tabs.metadata.head": "Edit Metadata", - // TODO New key - Add a translation - "community.edit.tabs.metadata.head": "Edit Metadata", + "community.edit.tabs.metadata.head": "Meta Verileri Düzenle", // "community.edit.tabs.metadata.title": "Community Edit - Metadata", - // TODO New key - Add a translation - "community.edit.tabs.metadata.title": "Community Edit - Metadata", + "community.edit.tabs.metadata.title": "Topluluk Düzenle - Meta Veriler", // "community.edit.tabs.roles.head": "Assign Roles", - // TODO New key - Add a translation - "community.edit.tabs.roles.head": "Assign Roles", + "community.edit.tabs.roles.head": "Rol atamak", // "community.edit.tabs.roles.title": "Community Edit - Roles", - // TODO New key - Add a translation - "community.edit.tabs.roles.title": "Community Edit - Roles", + "community.edit.tabs.roles.title": "Topluluk Düzenle - Roller", // "community.edit.tabs.authorizations.head": "Authorizations", - // TODO New key - Add a translation - "community.edit.tabs.authorizations.head": "Authorizations", + "community.edit.tabs.authorizations.head": "Yetkilendirmeler", // "community.edit.tabs.authorizations.title": "Community Edit - Authorizations", - // TODO New key - Add a translation - "community.edit.tabs.authorizations.title": "Community Edit - Authorizations", + "community.edit.tabs.authorizations.title": "Topluluk Düzenle - Yetkilendirmeler", // "community.listelement.badge": "Community", - // TODO New key - Add a translation - "community.listelement.badge": "Community", + "community.listelement.badge": "Topluluk", // "comcol-role.edit.no-group": "None", - // TODO New key - Add a translation - "comcol-role.edit.no-group": "None", + "comcol-role.edit.no-group": "Hiçbiri", // "comcol-role.edit.create": "Create", - // TODO New key - Add a translation - "comcol-role.edit.create": "Create", + "comcol-role.edit.create": "Oluştur", // "comcol-role.edit.restrict": "Restrict", - // TODO New key - Add a translation - "comcol-role.edit.restrict": "Restrict", + "comcol-role.edit.restrict": "Kısıtla", // "comcol-role.edit.delete": "Delete", - // TODO New key - Add a translation - "comcol-role.edit.delete": "Delete", + "comcol-role.edit.delete": "Sil", - // "comcol-role.edit.community-admin.name": "Administrators", - // TODO New key - Add a translation + // "comcol-role.edit.community-admin.name": "Yöneticiler", "comcol-role.edit.community-admin.name": "Administrators", // "comcol-role.edit.collection-admin.name": "Administrators", - // TODO New key - Add a translation - "comcol-role.edit.collection-admin.name": "Administrators", + "comcol-role.edit.collection-admin.name": "Yöneticiler", // "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).", - // TODO New key - Add a translation - "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": "Topluluk yöneticileri alt topluluklar veya koleksiyonlar oluşturabilir ve bu alt topluluklar veya koleksiyonlar için yönetimi yönetebilir veya atayabilir. Ek olarak, kimsenin herhangi bir alt koleksiyona kimin gönderebileceğine, madde meta verilerini (sunulduktan sonra) düzenleyebileceğine karar verirler ve mevcut eşyaları diğer koleksiyonlardan (yetkilendirmeye tabi) ekleyin.", // "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).", - // TODO New key - Add a translation - "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": "Koleksiyon yöneticileri, eşyaları koleksiyona kimin gönderebileceğine, öğe meta verilerini (gönderimden sonra) düzenleyebileceğine karar verir ve mevcut eşyaları diğer koleksiyonlardan (bu koleksiyon için yetkilendirmeye tabi) ekleyin.", // "comcol-role.edit.submitters.name": "Submitters", - // TODO New key - Add a translation - "comcol-role.edit.submitters.name": "Submitters", + "comcol-role.edit.submitters.name": "Göndericiler", // "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", - // TODO New key - Add a translation - "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": "Bu koleksiyona yeni eşya gönderme iznine sahip olan E-insanlar ve gruplar.", // "comcol-role.edit.item_read.name": "Default item read access", - // TODO New key - Add a translation - "comcol-role.edit.item_read.name": "Default item read access", + "comcol-role.edit.item_read.name": "Varsayılan öğe okuma erişimi", // "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.", - // TODO New key - Add a translation - "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": "Bu koleksiyona sunulan yeni eşyaları okuyabilen E-insanlar ve gruplar. Bu roldeki değişiklikler geriye dönük değildir. Sistemdeki mevcut eşyalar, eklemeleri sırasında erişimi okuyanlar tarafından görülebilir.", // "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", - // TODO New key - Add a translation - "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", + "comcol-role.edit.item_read.anonymous-group": "Gelen öğeler için varsayılan okuma şu anda isimsiz olarak ayarlanmıştır.", // "comcol-role.edit.bitstream_read.name": "Default bitstream read access", - // TODO New key - Add a translation - "comcol-role.edit.bitstream_read.name": "Default bitstream read access", + "comcol-role.edit.bitstream_read.name": "Varsayılan veri akışı okuma erişimi", // "comcol-role.edit.bitstream_read.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).", - // TODO New key - Add a translation - "comcol-role.edit.bitstream_read.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.bitstream_read.description": "Topluluk yöneticileri alt topluluklar veya koleksiyonlar oluşturabilir ve bu alt topluluklar veya koleksiyonlar için yönetimi yönetebilir veya atayabilirler. Ek olarak, eşyaları herhangi bir alt koleksiyona kimin gönderebileceğine, öğe meta verilerini (sunulduktan sonra) düzenleyebilir ve harita) Diğer koleksiyonlardan gelen mevcut eşyalar (yetkilendirmeye tabi).", // "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", - // TODO New key - Add a translation - "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", + "comcol-role.edit.bitstream_read.anonymous-group": "Gelen veri akışı için varsayılan okuma şu anda anonim olarak ayarlanmıştır.", // "comcol-role.edit.editor.name": "Editors", - // TODO New key - Add a translation - "comcol-role.edit.editor.name": "Editors", + "comcol-role.edit.editor.name": "Editörler", // "comcol-role.edit.editor.description": "Editors are able to edit the metadata of incoming submissions, and then accept or reject them.", - // TODO New key - Add a translation - "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": "Editörler, gelen gönderilerin meta verilerini düzenleyebilir ve ardından onları kabul edebilir veya reddedebilir.", // "comcol-role.edit.finaleditor.name": "Final editors", - // TODO New key - Add a translation - "comcol-role.edit.finaleditor.name": "Final editors", + "comcol-role.edit.finaleditor.name": "Son editörler", // "comcol-role.edit.finaleditor.description": "Final editors are able to edit the metadata of incoming submissions, but will not be able to reject them.", - // TODO New key - Add a translation - "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": "Nihai editörler gelen başvuruların meta verilerini düzenleyebilir, ancak onları reddedebilir.", // "comcol-role.edit.reviewer.name": "Reviewers", - // TODO New key - Add a translation - "comcol-role.edit.reviewer.name": "Reviewers", + "comcol-role.edit.reviewer.name": "Yorumcular", // "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.", - // TODO New key - Add a translation - "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": "Yorumcular gelen başvuruları kabul edebilir veya reddedebilirler. Ancak, gönderimin meta verilerini düzenleyemezler.", // "community.form.abstract": "Short Description", - // TODO New key - Add a translation - "community.form.abstract": "Short Description", + "community.form.abstract": "Kısa Açıklama", // "community.form.description": "Introductory text (HTML)", - // TODO New key - Add a translation - "community.form.description": "Introductory text (HTML)", + "community.form.description": "Tanıtım metni (HTML)", // "community.form.errors.title.required": "Please enter a community name", - // TODO New key - Add a translation - "community.form.errors.title.required": "Please enter a community name", + "community.form.errors.title.required": "Lütfen bir topluluk adı girin", // "community.form.rights": "Copyright text (HTML)", - // TODO New key - Add a translation - "community.form.rights": "Copyright text (HTML)", + "community.form.rights": "Telif Hakkı Metni (HTML)", // "community.form.tableofcontents": "News (HTML)", - // TODO New key - Add a translation - "community.form.tableofcontents": "News (HTML)", + "community.form.tableofcontents": "Haberler (HTML)", // "community.form.title": "Name", - // TODO New key - Add a translation - "community.form.title": "Name", + "community.form.title": "İsim", // "community.page.edit": "Edit this community", - // TODO New key - Add a translation - "community.page.edit": "Edit this community", + "community.page.edit": "Bu topluluğu düzenle", // "community.page.handle": "Permanent URI for this community", - // TODO New key - Add a translation - "community.page.handle": "Permanent URI for this community", + "community.page.handle": "Bu topluluk için Kalıcı Uri", // "community.page.license": "License", - // TODO New key - Add a translation - "community.page.license": "License", + "community.page.license": "Lisans", // "community.page.news": "News", - // TODO New key - Add a translation - "community.page.news": "News", + "community.page.news": "Haberler", // "community.all-lists.head": "Subcommunities and Collections", - // TODO New key - Add a translation - "community.all-lists.head": "Subcommunities and Collections", + "community.all-lists.head": "Alt topluluklar ve koleksiyonlar", // "community.sub-collection-list.head": "Collections of this Community", - // TODO New key - Add a translation - "community.sub-collection-list.head": "Collections of this Community", + "community.sub-collection-list.head": "Bu topluluğun koleksiyonları", // "community.sub-community-list.head": "Communities of this Community", - // TODO New key - Add a translation - "community.sub-community-list.head": "Communities of this Community", + "community.sub-community-list.head": "Bu topluluğun koleksiyonları", // "cookies.consent.accept-all": "Accept all", - // TODO New key - Add a translation - "cookies.consent.accept-all": "Accept all", + "cookies.consent.accept-all": "Hepsini kabul et", // "cookies.consent.accept-selected": "Accept selected", - // TODO New key - Add a translation - "cookies.consent.accept-selected": "Accept selected", + "cookies.consent.accept-selected": "Seçiliyi kabul et", // "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", - // TODO New key - Add a translation - "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", + "cookies.consent.app.opt-out.description": "Bu uygulama varsayılan olarak yüklenir (ancak vazgeçebilirsiniz)", // "cookies.consent.app.opt-out.title": "(opt-out)", - // TODO New key - Add a translation - "cookies.consent.app.opt-out.title": "(opt-out)", + "cookies.consent.app.opt-out.title": "(vazgeç)", // "cookies.consent.app.purpose": "purpose", - // TODO New key - Add a translation - "cookies.consent.app.purpose": "purpose", + "cookies.consent.app.purpose": "amaç", // "cookies.consent.app.required.description": "This application is always required", - // TODO New key - Add a translation - "cookies.consent.app.required.description": "This application is always required", + "cookies.consent.app.required.description": "Bu uygulama her zaman gereklidir", // "cookies.consent.app.required.title": "(always required)", - // TODO New key - Add a translation - "cookies.consent.app.required.title": "(always required)", + "cookies.consent.app.required.title": "(her zaman gerekli)", // "cookies.consent.update": "There were changes since your last visit, please update your consent.", - // TODO New key - Add a translation - "cookies.consent.update": "There were changes since your last visit, please update your consent.", + "cookies.consent.update": "Son ziyaretinizden bu yana değişiklikler vardı, lütfen onayınızı güncelleyin.", // "cookies.consent.close": "Close", - // TODO New key - Add a translation - "cookies.consent.close": "Close", + "cookies.consent.close": "Kapat", // "cookies.consent.decline": "Decline", - // TODO New key - Add a translation - "cookies.consent.decline": "Decline", + "cookies.consent.decline": "Reddet", // "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}.", - // TODO New key - Add a translation - "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": "Kişisel bilgilerinizi aşağıdaki amaçlarla topluyor ve işleriz: Kimlik Doğrulama, Tercihler, Onay ve İstatistikler.
Daha fazla bilgi için, lütfen okuyun {privacyPolicy}.", // "cookies.consent.content-notice.learnMore": "Customize", - // TODO New key - Add a translation - "cookies.consent.content-notice.learnMore": "Customize", + "cookies.consent.content-notice.learnMore": "Özelleştir", // "cookies.consent.content-modal.description": "Here you can see and customize the information that we collect about you.", - // TODO New key - Add a translation - "cookies.consent.content-modal.description": "Here you can see and customize the information that we collect about you.", + "cookies.consent.content-modal.description": "Burada, sizin hakkınızda topladığımız bilgileri görebilir ve özelleştirebilirsiniz.", // "cookies.consent.content-modal.privacy-policy.name": "privacy policy", - // TODO New key - Add a translation - "cookies.consent.content-modal.privacy-policy.name": "privacy policy", + "cookies.consent.content-modal.privacy-policy.name": "Gizlilik Politikası", // "cookies.consent.content-modal.privacy-policy.text": "To learn more, please read our {privacyPolicy}.", - // TODO New key - Add a translation - "cookies.consent.content-modal.privacy-policy.text": "To learn more, please read our {privacyPolicy}.", + "cookies.consent.content-modal.privacy-policy.text": "Daha fazla bilgi için, lütfen okuyun {privacyPolicy}.", // "cookies.consent.content-modal.title": "Information that we collect", - // TODO New key - Add a translation - "cookies.consent.content-modal.title": "Information that we collect", + "cookies.consent.content-modal.title": "Topladığımız bilgiler", // "cookies.consent.app.title.authentication": "Authentication", - // TODO New key - Add a translation - "cookies.consent.app.title.authentication": "Authentication", + "cookies.consent.app.title.authentication": "Kimlik doğrulama", // "cookies.consent.app.description.authentication": "Required for signing you in", - // TODO New key - Add a translation - "cookies.consent.app.description.authentication": "Required for signing you in", + "cookies.consent.app.description.authentication": "Kayıt olmak için gerekli", // "cookies.consent.app.title.preferences": "Preferences", - // TODO New key - Add a translation - "cookies.consent.app.title.preferences": "Preferences", + "cookies.consent.app.title.preferences": "Tercihler", // "cookies.consent.app.description.preferences": "Required for saving your preferences", - // TODO New key - Add a translation - "cookies.consent.app.description.preferences": "Required for saving your preferences", + "cookies.consent.app.description.preferences": "Tercihlerinizi kaydetmek için gerekli", // "cookies.consent.app.title.acknowledgement": "Acknowledgement", - // TODO New key - Add a translation - "cookies.consent.app.title.acknowledgement": "Acknowledgement", + "cookies.consent.app.title.acknowledgement": "Onaylama", // "cookies.consent.app.description.acknowledgement": "Required for saving your acknowledgements and consents", - // TODO New key - Add a translation - "cookies.consent.app.description.acknowledgement": "Required for saving your acknowledgements and consents", + "cookies.consent.app.description.acknowledgement": "Teşekkürlerinizi ve onayları kurtarmak için gerekli", // "cookies.consent.app.title.google-analytics": "Google Analytics", - // TODO New key - Add a translation - "cookies.consent.app.title.google-analytics": "Google Analytics", + "cookies.consent.app.title.google-analytics": "Google Analitiği", // "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", - // TODO New key - Add a translation - "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", + "cookies.consent.app.description.google-analytics": "İstatistiksel verileri izlememize izin verir", // "cookies.consent.purpose.functional": "Functional", - // TODO New key - Add a translation - "cookies.consent.purpose.functional": "Functional", + "cookies.consent.purpose.functional": "Fonksiyonel", // "cookies.consent.purpose.statistical": "Statistical", - // TODO New key - Add a translation - "cookies.consent.purpose.statistical": "Statistical", + "cookies.consent.purpose.statistical": "İstatistiksel", // "curation-task.task.checklinks.label": "Check Links in Metadata", - // TODO New key - Add a translation - "curation-task.task.checklinks.label": "Check Links in Metadata", + "curation-task.task.checklinks.label": "Meta Verilerdeki Bağlantıları Kontrol Et", // "curation-task.task.noop.label": "NOOP", - // TODO New key - Add a translation "curation-task.task.noop.label": "NOOP", // "curation-task.task.profileformats.label": "Profile Bitstream Formats", - // TODO New key - Add a translation - "curation-task.task.profileformats.label": "Profile Bitstream Formats", + "curation-task.task.profileformats.label": "Profil Veri Akışı Formatları", // "curation-task.task.requiredmetadata.label": "Check for Required Metadata", - // TODO New key - Add a translation - "curation-task.task.requiredmetadata.label": "Check for Required Metadata", + "curation-task.task.requiredmetadata.label": "Gerekli meta verileri kontrol edin", // "curation-task.task.translate.label": "Microsoft Translator", - // TODO New key - Add a translation - "curation-task.task.translate.label": "Microsoft Translator", + "curation-task.task.translate.label": "Microsoft Tercüman", // "curation-task.task.vscan.label": "Virus Scan", - // TODO New key - Add a translation - "curation-task.task.vscan.label": "Virus Scan", + "curation-task.task.vscan.label": "Virüs Taraması", // "curation.form.task-select.label": "Task:", - // TODO New key - Add a translation - "curation.form.task-select.label": "Task:", + "curation.form.task-select.label": "Görev:", // "curation.form.submit": "Start", - // TODO New key - Add a translation - "curation.form.submit": "Start", + "curation.form.submit": "Başlangıç", // "curation.form.submit.success.head": "The curation task has been started successfully", - // TODO New key - Add a translation - "curation.form.submit.success.head": "The curation task has been started successfully", + "curation.form.submit.success.head": "Küratör görevi başarıyla başlatıldı", // "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", - // TODO New key - Add a translation - "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", + "curation.form.submit.success.content": "İlgili işlem sayfasına yönlendirileceksiniz.", // "curation.form.submit.error.head": "Running the curation task failed", - // TODO New key - Add a translation - "curation.form.submit.error.head": "Running the curation task failed", + "curation.form.submit.error.head": "Küratörlük görevi başarısız oldu", // "curation.form.submit.error.content": "An error occured when trying to start the curation task.", - // TODO New key - Add a translation - "curation.form.submit.error.content": "An error occured when trying to start the curation task.", + "curation.form.submit.error.content": "Küratörlük görevi başlatmaya çalışırken bir hata oluştu.", // "curation.form.handle.label": "Handle:", - // TODO New key - Add a translation - "curation.form.handle.label": "Handle:", + "curation.form.handle.label": "Ele al:", // "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", - // TODO New key - Add a translation - "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": "İpucu: Gir [your-handle-prefix]/0 tüm sitede bir görevi çalıştırmak için (tüm görevler bu özelliği destekleyemez)", // "dso-selector.create.collection.head": "New collection", - // TODO New key - Add a translation - "dso-selector.create.collection.head": "New collection", + "dso-selector.create.collection.head": "Yeni koleksiyon", // "dso-selector.create.collection.sub-level": "Create a new collection in", - // TODO New key - Add a translation - "dso-selector.create.collection.sub-level": "Create a new collection in", + "dso-selector.create.collection.sub-level": "Yeni bir koleksiyon oluşturun", // "dso-selector.create.community.head": "New community", - // TODO New key - Add a translation - "dso-selector.create.community.head": "New community", + "dso-selector.create.community.head": "Yeni topluluk", // "dso-selector.create.community.sub-level": "Create a new community in", - // TODO New key - Add a translation - "dso-selector.create.community.sub-level": "Create a new community in", + "dso-selector.create.community.sub-level": "Yeni bir topluluk oluştur", // "dso-selector.create.community.top-level": "Create a new top-level community", - // TODO New key - Add a translation - "dso-selector.create.community.top-level": "Create a new top-level community", + "dso-selector.create.community.top-level": "Yeni bir üst düzey topluluk oluştur", // "dso-selector.create.item.head": "New item", - // TODO New key - Add a translation - "dso-selector.create.item.head": "New item", + "dso-selector.create.item.head": "Yeni öğe", // "dso-selector.create.item.sub-level": "Create a new item in", - // TODO New key - Add a translation - "dso-selector.create.item.sub-level": "Create a new item in", + "dso-selector.create.item.sub-level": "İçinde yeni bir öğe oluşturun", // "dso-selector.create.submission.head": "New submission", - // TODO New key - Add a translation - "dso-selector.create.submission.head": "New submission", + "dso-selector.create.submission.head": "Yeni başvuru", // "dso-selector.edit.collection.head": "Edit collection", - // TODO New key - Add a translation - "dso-selector.edit.collection.head": "Edit collection", + "dso-selector.edit.collection.head": "Koleksiyonu Düzenle", // "dso-selector.edit.community.head": "Edit community", - // TODO New key - Add a translation - "dso-selector.edit.community.head": "Edit community", + "dso-selector.edit.community.head": "Topluluğu Düzenle", // "dso-selector.edit.item.head": "Edit item", - // TODO New key - Add a translation - "dso-selector.edit.item.head": "Edit item", + "dso-selector.edit.item.head": "Ögeyi düzenle", // "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", - // TODO New key - Add a translation - "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", + "dso-selector.export-metadata.dspaceobject.head": "Meta verilerini dışa aktar", - // "dso-selector.no-results": "No {{ type }} found", - // TODO New key - Add a translation - "dso-selector.no-results": "No {{ type }} found", + // "dso-selector.no-results": "No {{ type }} found ", + "dso-selector.no-results": "Bulunamadı {{ type }} ", // "dso-selector.placeholder": "Search for a {{ type }}", - // TODO New key - Add a translation - "dso-selector.placeholder": "Search for a {{ type }}", + "dso-selector.placeholder": " Ara {{ type }}", // "confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}", - // TODO New key - Add a translation - "confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}", + "confirmation-modal.export-metadata.header": "Meta verilerini dışa aktar {{ dsoName }}", // "confirmation-modal.export-metadata.info": "Are you sure you want to export metadata for {{ dsoName }}", - // TODO New key - Add a translation - "confirmation-modal.export-metadata.info": "Are you sure you want to export metadata for {{ dsoName }}", + "confirmation-modal.export-metadata.info": "Meta verileri dışarı aktarmak istediğinizden emin misiniz {{ dsoName }}", // "confirmation-modal.export-metadata.cancel": "Cancel", - // TODO New key - Add a translation - "confirmation-modal.export-metadata.cancel": "Cancel", + "confirmation-modal.export-metadata.cancel": "İptal", // "confirmation-modal.export-metadata.confirm": "Export", - // TODO New key - Add a translation - "confirmation-modal.export-metadata.confirm": "Export", + "confirmation-modal.export-metadata.confirm": "Dışarı aktar", // "confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"", - // TODO New key - Add a translation - "confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"", + "confirmation-modal.delete-eperson.header": "EPerson'ı sil \"{{ dsoName }}\"", // "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", - // TODO New key - Add a translation - "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", + "confirmation-modal.delete-eperson.info": "Eperson'u silmek istediğinize emin misiniz? \"{{ dsoName }}\"", // "confirmation-modal.delete-eperson.cancel": "Cancel", - // TODO New key - Add a translation - "confirmation-modal.delete-eperson.cancel": "Cancel", + "confirmation-modal.delete-eperson.cancel": "İptal", // "confirmation-modal.delete-eperson.confirm": "Delete", - // TODO New key - Add a translation - "confirmation-modal.delete-eperson.confirm": "Delete", + "confirmation-modal.delete-eperson.confirm": "Sil", // "error.bitstream": "Error fetching bitstream", - // TODO New key - Add a translation - "error.bitstream": "Error fetching bitstream", + "error.bitstream": "Alınan bitstream hatası", // "error.browse-by": "Error fetching items", - // TODO New key - Add a translation - "error.browse-by": "Error fetching items", + "error.browse-by": "Alınan öğeler hatası", // "error.collection": "Error fetching collection", - // TODO New key - Add a translation - "error.collection": "Error fetching collection", + "error.collection": "Alınan koleksiyon hatası", // "error.collections": "Error fetching collections", - // TODO New key - Add a translation - "error.collections": "Error fetching collections", + "error.collections": "Alınan koleksiyonlar hatası", // "error.community": "Error fetching community", - // TODO New key - Add a translation - "error.community": "Error fetching community", + "error.community": "Alınan topluluk hatası", // "error.identifier": "No item found for the identifier", - // TODO New key - Add a translation - "error.identifier": "No item found for the identifier", + "error.identifier": "Tanımlayıcı için ürün bulunamadı", // "error.default": "Error", - // TODO New key - Add a translation - "error.default": "Error", + "error.default": "Hata", // "error.item": "Error fetching item", - // TODO New key - Add a translation - "error.item": "Error fetching item", + "error.item": "Alınan öğe hatası", // "error.items": "Error fetching items", - // TODO New key - Add a translation - "error.items": "Error fetching items", + "error.items": "Alınan öğeler hatası", // "error.objects": "Error fetching objects", - // TODO New key - Add a translation - "error.objects": "Error fetching objects", + "error.objects": "Alınan nesneler hatası", // "error.recent-submissions": "Error fetching recent submissions", - // TODO New key - Add a translation - "error.recent-submissions": "Error fetching recent submissions", + "error.recent-submissions": "Son başvuruları alma hatası", // "error.search-results": "Error fetching search results", - // TODO New key - Add a translation - "error.search-results": "Error fetching search results", + "error.search-results": "Arama sonuçlarını alma hatası", // "error.sub-collections": "Error fetching sub-collections", - // TODO New key - Add a translation - "error.sub-collections": "Error fetching sub-collections", + "error.sub-collections": "Alt koleksiyonları alma hatası", // "error.sub-communities": "Error fetching sub-communities", - // TODO New key - Add a translation - "error.sub-communities": "Error fetching sub-communities", + "error.sub-communities": "Alt toplulukları alma hatası", // "error.submission.sections.init-form-error": "An error occurred during section initialize, please check your input-form configuration. Details are below :

", - // TODO New key - Add a translation - "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": "Bölüm başlatma sırasında bir hata oluştu, lütfen giriş formu yapılandırmanızı kontrol edin. Detaylar aşağıdadır :

", // "error.top-level-communities": "Error fetching top-level communities", - // TODO New key - Add a translation - "error.top-level-communities": "Error fetching top-level communities", + "error.top-level-communities": "Üst düzey toplulukları alma hatası", // "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.", - // TODO New key - Add a translation - "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": "Gönderinizi tamamlamak için bu lisansı vermelisiniz. Bu lisansı şu anda veremiyorsanız, çalışmanızı kaydedebilir ve daha sonra geri gönderebilir veya gönderimi kaldırabilirsiniz.", // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", - // TODO New key - Add a translation - "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", + "error.validation.pattern": "Bu giriş mevcut modelle sınırlandırılmıştır.: {{ pattern }}.", // "error.validation.filerequired": "The file upload is mandatory", - // TODO New key - Add a translation - "error.validation.filerequired": "The file upload is mandatory", + "error.validation.filerequired": "Dosya yükleme zorunludur", // "file-section.error.header": "Error obtaining files for this item", - // TODO New key - Add a translation - "file-section.error.header": "Error obtaining files for this item", + "file-section.error.header": "Bu öğe için dosyaları elde etme hatası", // "footer.copyright": "copyright © 2002-{{ year }}", - // TODO New key - Add a translation - "footer.copyright": "copyright © 2002-{{ year }}", + "footer.copyright": "telif hakkı © 2002-{{ year }}", // "footer.link.dspace": "DSpace software", - // TODO New key - Add a translation - "footer.link.dspace": "DSpace software", + "footer.link.dspace": "DSpace yazılım", // "footer.link.lyrasis": "LYRASIS", - // TODO New key - Add a translation "footer.link.lyrasis": "LYRASIS", // "footer.link.cookies": "Cookie settings", - // TODO New key - Add a translation - "footer.link.cookies": "Cookie settings", + "footer.link.cookies": "Çerez Ayarları", // "footer.link.privacy-policy": "Privacy policy", - // TODO New key - Add a translation - "footer.link.privacy-policy": "Privacy policy", + "footer.link.privacy-policy": "Gizlilik Politikası", // "footer.link.end-user-agreement":"End User Agreement", - // TODO New key - Add a translation - "footer.link.end-user-agreement":"End User Agreement", + "footer.link.end-user-agreement":"Son Kullanıcı Sözleşmesi", // "forgot-email.form.header": "Forgot Password", - // TODO New key - Add a translation - "forgot-email.form.header": "Forgot Password", + "forgot-email.form.header": "Parolanızı mı unuttunuz", // "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", - // TODO New key - Add a translation - "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + "forgot-email.form.info": "E-posta güncellemeleri için koleksiyonlara abone olmak için bir hesap kaydedin ve DSPace'e yeni öğeler gönderin.", // "forgot-email.form.email": "Email Address *", - // TODO New key - Add a translation - "forgot-email.form.email": "Email Address *", + "forgot-email.form.email": "Eposta Adresi *", // "forgot-email.form.email.error.required": "Please fill in an email address", - // TODO New key - Add a translation - "forgot-email.form.email.error.required": "Please fill in an email address", + "forgot-email.form.email.error.required": "Lütfen bir e-posta adresi giriniz", // "forgot-email.form.email.error.pattern": "Please fill in a valid email address", - // TODO New key - Add a translation - "forgot-email.form.email.error.pattern": "Please fill in a valid email address", + "forgot-email.form.email.error.pattern": "Lütfen bir e-posta adresi giriniz", // "forgot-email.form.email.hint": "This address will be verified and used as your login name.", - // TODO New key - Add a translation - "forgot-email.form.email.hint": "This address will be verified and used as your login name.", + "forgot-email.form.email.hint": "Bu adres, giriş adınız olarak doğrulanacak ve kullanılacaktır.", // "forgot-email.form.submit": "Submit", - // TODO New key - Add a translation - "forgot-email.form.submit": "Submit", + "forgot-email.form.submit": "Kaydet", // "forgot-email.form.success.head": "Verification email sent", - // TODO New key - Add a translation - "forgot-email.form.success.head": "Verification email sent", + "forgot-email.form.success.head": "Doğrulama e-postası gönderildi", // "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", - // TODO New key - Add a translation - "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + "forgot-email.form.success.content": "Özel bir URL ve daha fazla talimat içeren bir e posta bu {{ email }} mail adresin gönderildi. ", // "forgot-email.form.error.head": "Error when trying to register email", - // TODO New key - Add a translation - "forgot-email.form.error.head": "Error when trying to register email", + "forgot-email.form.error.head": "E-postayı kaydetmeye çalışırken hata oluştu", // "forgot-email.form.error.content": "An error occured when registering the following email address: {{ email }}", - // TODO New key - Add a translation - "forgot-email.form.error.content": "An error occured when registering the following email address: {{ email }}", + "forgot-email.form.error.content": "E-posta adresini kaydederken bir hata oluştu: {{ email }}", // "forgot-password.title": "Forgot Password", - // TODO New key - Add a translation - "forgot-password.title": "Forgot Password", + "forgot-password.title": "Parolanızı mı unuttunuz", // "forgot-password.form.head": "Forgot Password", - // TODO New key - Add a translation - "forgot-password.form.head": "Forgot Password", + "forgot-password.form.head": "Parolanızı mı unuttunuz", // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - // TODO New key - Add a translation - "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + "forgot-password.form.info": "Aşağıdaki kutuya yeni bir parola girin ve tekrar ikinci kutuya yazarak onaylayın. En az altı karakter uzunluğunda olmalıdır.", // "forgot-password.form.card.security": "Security", - // TODO New key - Add a translation - "forgot-password.form.card.security": "Security", + "forgot-password.form.card.security": "Güvenlik", // "forgot-password.form.identification.header": "Identify", - // TODO New key - Add a translation - "forgot-password.form.identification.header": "Identify", + "forgot-password.form.identification.header": "Kimlik", // "forgot-password.form.identification.email": "Email address: ", - // TODO New key - Add a translation - "forgot-password.form.identification.email": "Email address: ", + "forgot-password.form.identification.email": "E-posta adresi: ", // "forgot-password.form.label.password": "Password", - // TODO New key - Add a translation - "forgot-password.form.label.password": "Password", + "forgot-password.form.label.password": "Parola", // "forgot-password.form.label.passwordrepeat": "Retype to confirm", - // TODO New key - Add a translation - "forgot-password.form.label.passwordrepeat": "Retype to confirm", + "forgot-password.form.label.passwordrepeat": "Doğrulamak için yeniden yazınız", // "forgot-password.form.error.empty-password": "Please enter a password in the box below.", - // TODO New key - Add a translation - "forgot-password.form.error.empty-password": "Please enter a password in the box below.", + "forgot-password.form.error.empty-password": "Lütfen aşağıdaki kutuya bir parola girin.", // "forgot-password.form.error.matching-passwords": "The passwords do not match.", - // TODO New key - Add a translation - "forgot-password.form.error.matching-passwords": "The passwords do not match.", + "forgot-password.form.error.matching-passwords": "Parolalar eşleşmiyor.", // "forgot-password.form.error.password-length": "The password should be at least 6 characters long.", - // TODO New key - Add a translation - "forgot-password.form.error.password-length": "The password should be at least 6 characters long.", + "forgot-password.form.error.password-length": "Parola en az 6 karakter uzunluğunda olmalıdır.", // "forgot-password.form.notification.error.title": "Error when trying to submit new password", - // TODO New key - Add a translation - "forgot-password.form.notification.error.title": "Error when trying to submit new password", + "forgot-password.form.notification.error.title": "Yeni parola göndermeye çalışırken hata oluştu", // "forgot-password.form.notification.success.content": "The password reset was successful. You have been logged in as the created user.", - // TODO New key - Add a translation - "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": "Parola sıfırlama başarılı oldu. Oluşturulan kullanıcı olarak giriş yaptınız.", // "forgot-password.form.notification.success.title": "Password reset completed", - // TODO New key - Add a translation - "forgot-password.form.notification.success.title": "Password reset completed", + "forgot-password.form.notification.success.title": "Parola sıfırlama tamamlandı", // "forgot-password.form.submit": "Submit password", - // TODO New key - Add a translation - "forgot-password.form.submit": "Submit password", + "forgot-password.form.submit": "Parolayı kaydet", // "form.add": "Add", - // TODO New key - Add a translation - "form.add": "Add", + "form.add": "Ekle", // "form.add-help": "Click here to add the current entry and to add another one", - // TODO New key - Add a translation - "form.add-help": "Click here to add the current entry and to add another one", + "form.add-help": "Geçerli girişi eklemek ve bir tane daha eklemek için buraya tıklayın.", // "form.cancel": "Cancel", - // TODO New key - Add a translation - "form.cancel": "Cancel", + "form.cancel": "İptal", // "form.clear": "Clear", - // TODO New key - Add a translation - "form.clear": "Clear", + "form.clear": "Temizle", // "form.clear-help": "Click here to remove the selected value", - // TODO New key - Add a translation - "form.clear-help": "Click here to remove the selected value", + "form.clear-help": "Seçilen değeri kaldırmak için buraya tıklayın", // "form.edit": "Edit", - // TODO New key - Add a translation - "form.edit": "Edit", + "form.edit": "Düzenle", // "form.edit-help": "Click here to edit the selected value", - // TODO New key - Add a translation - "form.edit-help": "Click here to edit the selected value", + "form.edit-help": "Seçilen değeri düzenlemek için buraya tıklayın", // "form.first-name": "First name", - // TODO New key - Add a translation - "form.first-name": "First name", + "form.first-name": "İlk adı", // "form.group-collapse": "Collapse", - // TODO New key - Add a translation - "form.group-collapse": "Collapse", + "form.group-collapse": "Yığmak", // "form.group-collapse-help": "Click here to collapse", - // TODO New key - Add a translation - "form.group-collapse-help": "Click here to collapse", + "form.group-collapse-help": "Yığmak için buraya tıklayın", // "form.group-expand": "Expand", - // TODO New key - Add a translation - "form.group-expand": "Expand", + "form.group-expand": "Uzat", // "form.group-expand-help": "Click here to expand and add more elements", - // TODO New key - Add a translation - "form.group-expand-help": "Click here to expand and add more elements", + "form.group-expand-help": "Genişletmek ve daha fazla öğe eklemek için buraya tıklayın", // "form.last-name": "Last name", - // TODO New key - Add a translation - "form.last-name": "Last name", + "form.last-name": "Soyadı", // "form.loading": "Loading...", - // TODO New key - Add a translation - "form.loading": "Loading...", + "form.loading": "Yükleniyor...", // "form.lookup": "Lookup", - // TODO New key - Add a translation - "form.lookup": "Lookup", + "form.lookup": "Yukarı Bak", // "form.lookup-help": "Click here to look up an existing relation", - // TODO New key - Add a translation - "form.lookup-help": "Click here to look up an existing relation", + "form.lookup-help": "Mevcut bir bağlantı aramak için buraya tıklayın", // "form.no-results": "No results found", - // TODO New key - Add a translation - "form.no-results": "No results found", + "form.no-results": "Sonuç bulunamadı", // "form.no-value": "No value entered", - // TODO New key - Add a translation - "form.no-value": "No value entered", + "form.no-value": "Değer girilmez", // "form.other-information": {}, - // TODO New key - Add a translation "form.other-information": {}, // "form.remove": "Remove", - // TODO New key - Add a translation - "form.remove": "Remove", + "form.remove": "Kaldır", // "form.save": "Save", - // TODO New key - Add a translation - "form.save": "Save", + "form.save": "Kaydet", // "form.save-help": "Save changes", - // TODO New key - Add a translation - "form.save-help": "Save changes", + "form.save-help": "Değişiklikleri kaydet", // "form.search": "Search", - // TODO New key - Add a translation - "form.search": "Search", + "form.search": "Ara", // "form.search-help": "Click here to look for an existing correspondence", - // TODO New key - Add a translation - "form.search-help": "Click here to look for an existing correspondence", + "form.search-help": "Mevcut bir yazışma aramak için buraya tıklayın", // "form.submit": "Submit", - // TODO New key - Add a translation - "form.submit": "Submit", + "form.submit": "Gönder", // "home.description": "", - // TODO New key - Add a translation "home.description": "", // "home.breadcrumbs": "Home", - // TODO New key - Add a translation - "home.breadcrumbs": "Home", + "home.breadcrumbs": "Anasayfa", // "home.title": "DSpace Angular :: Home", - // TODO New key - Add a translation - "home.title": "DSpace Angular :: Home", + "home.title": "DSpace Açısal :: Anasayfa", // "home.top-level-communities.head": "Communities in DSpace", - // TODO New key - Add a translation - "home.top-level-communities.head": "Communities in DSpace", + "home.top-level-communities.head": "Dspace'deki Topluluklar", // "home.top-level-communities.help": "Select a community to browse its collections.", - // TODO New key - Add a translation - "home.top-level-communities.help": "Select a community to browse its collections.", - + "home.top-level-communities.help": "Koleksiyonlarına göz atmak için bir topluluk seçin.", + + // "home.search-form.placeholder": "Search the repository ...", + "home.search-form.placeholder": "Depoda ara ...", // "info.end-user-agreement.accept": "I have read and I agree to the End User Agreement", - // TODO New key - Add a translation - "info.end-user-agreement.accept": "I have read and I agree to the End User Agreement", + "info.end-user-agreement.accept": "Okudum ve son kullanıcı sözleşmesini kabul ediyorum", // "info.end-user-agreement.accept.error": "An error occurred accepting the End User Agreement", - // TODO New key - Add a translation - "info.end-user-agreement.accept.error": "An error occurred accepting the End User Agreement", + "info.end-user-agreement.accept.error": "Son kullanıcı sözleşmesini kabul eden bir hata oluştu", // "info.end-user-agreement.accept.success": "Successfully updated the End User Agreement", - // TODO New key - Add a translation - "info.end-user-agreement.accept.success": "Successfully updated the End User Agreement", + "info.end-user-agreement.accept.success": "Son Kullanıcı Sözleşmesini başarıyla güncelledi", // "info.end-user-agreement.breadcrumbs": "End User Agreement", - // TODO New key - Add a translation - "info.end-user-agreement.breadcrumbs": "End User Agreement", + "info.end-user-agreement.breadcrumbs": "Son Kullanıcı Sözleşmesi", // "info.end-user-agreement.buttons.cancel": "Cancel", - // TODO New key - Add a translation - "info.end-user-agreement.buttons.cancel": "Cancel", + "info.end-user-agreement.buttons.cancel": "İptal", // "info.end-user-agreement.buttons.save": "Save", - // TODO New key - Add a translation - "info.end-user-agreement.buttons.save": "Save", + "info.end-user-agreement.buttons.save": "Kaydet", // "info.end-user-agreement.head": "End User Agreement", - // TODO New key - Add a translation - "info.end-user-agreement.head": "End User Agreement", + "info.end-user-agreement.head": "Son Kullanıcı Sözleşmesi", // "info.end-user-agreement.title": "End User Agreement", - // TODO New key - Add a translation - "info.end-user-agreement.title": "End User Agreement", + "info.end-user-agreement.title": "Son Kullanıcı Sözleşmesi", // "info.privacy.breadcrumbs": "Privacy Statement", - // TODO New key - Add a translation - "info.privacy.breadcrumbs": "Privacy Statement", + "info.privacy.breadcrumbs": "Gizlilik bildirimi", // "info.privacy.head": "Privacy Statement", - // TODO New key - Add a translation - "info.privacy.head": "Privacy Statement", + "info.privacy.head": "Gizlilik bildirimi", // "info.privacy.title": "Privacy Statement", - // TODO New key - Add a translation - "info.privacy.title": "Privacy Statement", + "info.privacy.title": "Gizlilik bildirimi", // "item.alerts.private": "This item is private", - // TODO New key - Add a translation - "item.alerts.private": "This item is private", + "item.alerts.private": "Bu öğe özel", // "item.alerts.withdrawn": "This item has been withdrawn", - // TODO New key - Add a translation - "item.alerts.withdrawn": "This item has been withdrawn", + "item.alerts.withdrawn": "Bu ürün geri çekildi", // "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.", - // TODO New key - Add a translation - "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": "Bu editör ile bir öğenin politikalarını görüntüleyebilir ve değiştirebilirsiniz, ayrıca bireysel ürün bileşenlerinin politikalarını değiştirebilirsiniz: Paketler ve Veri Akışı. Kısaca, bir öğe bir paket konteynırıdır ve paketler veri akışı konteynırıdır. Konteynerler genellikle, veri akışı yalnızca okuma / yazma politikalarına sahip olur.", // "item.edit.authorizations.title": "Edit item's Policies", - // TODO New key - Add a translation - "item.edit.authorizations.title": "Edit item's Policies", + "item.edit.authorizations.title": "Edit item's Politikalar", // "item.badge.private": "Private", - // TODO New key - Add a translation - "item.badge.private": "Private", + "item.badge.private": "Özel", // "item.badge.withdrawn": "Withdrawn", - // TODO New key - Add a translation - "item.badge.withdrawn": "Withdrawn", + "item.badge.withdrawn": "Çekilmiş", // "item.bitstreams.upload.bundle": "Bundle", - // TODO New key - Add a translation - "item.bitstreams.upload.bundle": "Bundle", + "item.bitstreams.upload.bundle": "Paket", // "item.bitstreams.upload.bundle.placeholder": "Select a bundle", - // TODO New key - Add a translation - "item.bitstreams.upload.bundle.placeholder": "Select a bundle", + "item.bitstreams.upload.bundle.placeholder": "Bir paket seçin", // "item.bitstreams.upload.bundle.new": "Create bundle", - // TODO New key - Add a translation - "item.bitstreams.upload.bundle.new": "Create bundle", + "item.bitstreams.upload.bundle.new": "Paket oluştur", // "item.bitstreams.upload.bundles.empty": "This item doesn\'t contain any bundles to upload a bitstream to.", - // TODO New key - Add a translation - "item.bitstreams.upload.bundles.empty": "This item doesn\'t contain any bundles to upload a bitstream to.", + "item.bitstreams.upload.bundles.empty": "Bu öğe, bir veri akışı yüklemek için herhangi bir paket içermiyor.", // "item.bitstreams.upload.cancel": "Cancel", - // TODO New key - Add a translation - "item.bitstreams.upload.cancel": "Cancel", + "item.bitstreams.upload.cancel": "İptal", // "item.bitstreams.upload.drop-message": "Drop a file to upload", - // TODO New key - Add a translation - "item.bitstreams.upload.drop-message": "Drop a file to upload", + "item.bitstreams.upload.drop-message": "Yüklenecek bir dosya bırak", // "item.bitstreams.upload.item": "Item: ", - // TODO New key - Add a translation - "item.bitstreams.upload.item": "Item: ", + "item.bitstreams.upload.item": "Öğe: ", // "item.bitstreams.upload.notifications.bundle.created.content": "Successfully created new bundle.", - // TODO New key - Add a translation - "item.bitstreams.upload.notifications.bundle.created.content": "Successfully created new bundle.", + "item.bitstreams.upload.notifications.bundle.created.content": "Başarıyla yeni paket oluşturuldu.", // "item.bitstreams.upload.notifications.bundle.created.title": "Created bundle", - // TODO New key - Add a translation - "item.bitstreams.upload.notifications.bundle.created.title": "Created bundle", + "item.bitstreams.upload.notifications.bundle.created.title": "Paket oluşturdu", // "item.bitstreams.upload.notifications.upload.failed": "Upload failed. Please verify the content before retrying.", - // TODO New key - Add a translation - "item.bitstreams.upload.notifications.upload.failed": "Upload failed. Please verify the content before retrying.", + "item.bitstreams.upload.notifications.upload.failed": "Yükleme başarısız. Lütfen yeniden denemeden önce içeriği doğrulayın.", // "item.bitstreams.upload.title": "Upload bitstream", - // TODO New key - Add a translation - "item.bitstreams.upload.title": "Upload bitstream", + "item.bitstreams.upload.title": "Veri akışı yükle", // "item.edit.bitstreams.bundle.edit.buttons.upload": "Upload", - // TODO New key - Add a translation - "item.edit.bitstreams.bundle.edit.buttons.upload": "Upload", + "item.edit.bitstreams.bundle.edit.buttons.upload": "Yükle", // "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", - // TODO New key - Add a translation - "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", + "item.edit.bitstreams.bundle.displaying": "Şu anda görüntülenen {{ amount }} veri akışı {{ total }}.", // "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", - // TODO New key - Add a translation - "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", + "item.edit.bitstreams.bundle.load.all": "Hepsini yükle ({{ total }})", // "item.edit.bitstreams.bundle.load.more": "Load more", - // TODO New key - Add a translation - "item.edit.bitstreams.bundle.load.more": "Load more", + "item.edit.bitstreams.bundle.load.more": "Daha fazla yükle", // "item.edit.bitstreams.bundle.name": "BUNDLE: {{ name }}", - // TODO New key - Add a translation - "item.edit.bitstreams.bundle.name": "BUNDLE: {{ name }}", + "item.edit.bitstreams.bundle.name": "PAKET: {{ name }}", // "item.edit.bitstreams.discard-button": "Discard", - // TODO New key - Add a translation - "item.edit.bitstreams.discard-button": "Discard", + "item.edit.bitstreams.discard-button": "Yoksay", // "item.edit.bitstreams.edit.buttons.download": "Download", - // TODO New key - Add a translation - "item.edit.bitstreams.edit.buttons.download": "Download", + "item.edit.bitstreams.edit.buttons.download": "İndir", // "item.edit.bitstreams.edit.buttons.drag": "Drag", - // TODO New key - Add a translation - "item.edit.bitstreams.edit.buttons.drag": "Drag", + "item.edit.bitstreams.edit.buttons.drag": "Sürükle", // "item.edit.bitstreams.edit.buttons.edit": "Edit", - // TODO New key - Add a translation - "item.edit.bitstreams.edit.buttons.edit": "Edit", + "item.edit.bitstreams.edit.buttons.edit": "Düzenle", // "item.edit.bitstreams.edit.buttons.remove": "Remove", - // TODO New key - Add a translation - "item.edit.bitstreams.edit.buttons.remove": "Remove", - + "item.edit.bitstreams.edit.buttons.remove": "Kaldır", + // "item.edit.bitstreams.edit.buttons.undo": "Undo changes", - // TODO New key - Add a translation - "item.edit.bitstreams.edit.buttons.undo": "Undo changes", + "item.edit.bitstreams.edit.buttons.undo": "Değişiklikleri geri al", // "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", - // TODO New key - Add a translation - "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", + "item.edit.bitstreams.empty": "Bu öge herhangi bir veri içermiyor. Bir tane oluşturmak için yükle düğmesini tıklayınız.", // "item.edit.bitstreams.headers.actions": "Actions", - // TODO New key - Add a translation - "item.edit.bitstreams.headers.actions": "Actions", + "item.edit.bitstreams.headers.actions": "İşlemler", // "item.edit.bitstreams.headers.bundle": "Bundle", - // TODO New key - Add a translation - "item.edit.bitstreams.headers.bundle": "Bundle", + "item.edit.bitstreams.headers.bundle": "Seri", // "item.edit.bitstreams.headers.description": "Description", - // TODO New key - Add a translation - "item.edit.bitstreams.headers.description": "Description", + "item.edit.bitstreams.headers.description": "Açıklama", // "item.edit.bitstreams.headers.format": "Format", - // TODO New key - Add a translation "item.edit.bitstreams.headers.format": "Format", // "item.edit.bitstreams.headers.name": "Name", - // TODO New key - Add a translation - "item.edit.bitstreams.headers.name": "Name", + "item.edit.bitstreams.headers.name": "Ad", // "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.bitstreams.notifications.discarded.content": "Yaptığınız değişiklikler silindi.Yaptığınız değişiklikleri geri yüklemek için 'Geri al' butonuna tıklayınız.", // "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", + "item.edit.bitstreams.notifications.discarded.title": "Değişiklikler silindi.", // "item.edit.bitstreams.notifications.move.failed.title": "Error moving bitstreams", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.move.failed.title": "Error moving bitstreams", + "item.edit.bitstreams.notifications.move.failed.title": "Veri taşınırken bir hata oluştu.", // "item.edit.bitstreams.notifications.move.saved.content": "Your move changes to this item's bitstreams and bundles have been saved.", - // TODO New key - Add a translation - "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": "Bu öğenin veri akışında ve paketlerinde yaptığınız değişiklikler kaydedildi.", // "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", + "item.edit.bitstreams.notifications.move.saved.title": "Değişiklikler kaydedildi.", // "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", - // TODO New key - Add a translation - "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": "Şu anda üzerinde çalıştığınız öğe başka bir kullanıcı tarafından değiştirildi.Mevcut değişiklikleriniz çakışma olmasını önlemek için silindi. ", // "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", + "item.edit.bitstreams.notifications.outdated.title": "Değişiklikler zaman aşımına uğradı.", // "item.edit.bitstreams.notifications.remove.failed.title": "Error deleting bitstream", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.remove.failed.title": "Error deleting bitstream", + "item.edit.bitstreams.notifications.remove.failed.title": "Veri akışı silinirken bir hata oluştu", // "item.edit.bitstreams.notifications.remove.saved.content": "Your removal changes to this item's bitstreams have been saved.", - // TODO New key - Add a translation - "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": "Bu öğenin veri akışında yaptığınız kaldırma değişiklikleri kaydedildi.", // "item.edit.bitstreams.notifications.remove.saved.title": "Removal changes saved", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.remove.saved.title": "Removal changes saved", + "item.edit.bitstreams.notifications.remove.saved.title": "Kaldırma değişiklikleri kaydedildi.", // "item.edit.bitstreams.reinstate-button": "Undo", - // TODO New key - Add a translation - "item.edit.bitstreams.reinstate-button": "Undo", + "item.edit.bitstreams.reinstate-button": "Geri al", // "item.edit.bitstreams.save-button": "Save", - // TODO New key - Add a translation - "item.edit.bitstreams.save-button": "Save", + "item.edit.bitstreams.save-button": "Kaydet", // "item.edit.bitstreams.upload-button": "Upload", - // TODO New key - Add a translation - "item.edit.bitstreams.upload-button": "Upload", + "item.edit.bitstreams.upload-button": "Yükle", // "item.edit.delete.cancel": "Cancel", - // TODO New key - Add a translation - "item.edit.delete.cancel": "Cancel", + "item.edit.delete.cancel": "İptal et", // "item.edit.delete.confirm": "Delete", - // TODO New key - Add a translation - "item.edit.delete.confirm": "Delete", + "item.edit.delete.confirm": "Sil", // "item.edit.delete.description": "Are you sure this item should be completely deleted? Caution: At present, no tombstone would be left.", - // TODO New key - Add a translation - "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": "Bu öğeyi kalıcı olarak silmek istedğinizden emin misiniz? Silme işlemi gerçekleştikten sonra geri alınamaz. ", // "item.edit.delete.error": "An error occurred while deleting the item", - // TODO New key - Add a translation - "item.edit.delete.error": "An error occurred while deleting the item", + "item.edit.delete.error": "Silme işlemi sırasında bir hata oluştu.", // "item.edit.delete.header": "Delete item: {{ id }}", - // TODO New key - Add a translation - "item.edit.delete.header": "Delete item: {{ id }}", + "item.edit.delete.header": "Silinecek öğeler: {{ id }}", // "item.edit.delete.success": "The item has been deleted", - // TODO New key - Add a translation - "item.edit.delete.success": "The item has been deleted", + "item.edit.delete.success": "Öğe silindi.", // "item.edit.head": "Edit Item", - // TODO New key - Add a translation - "item.edit.head": "Edit Item", + "item.edit.head": "Ögeleri düzenle", // "item.edit.breadcrumbs": "Edit Item", - // TODO New key - Add a translation - "item.edit.breadcrumbs": "Edit Item", + "item.edit.breadcrumbs": "Ögeleri düzenle", // "item.edit.tabs.mapper.head": "Collection Mapper", - // TODO New key - Add a translation - "item.edit.tabs.mapper.head": "Collection Mapper", + "item.edit.tabs.mapper.head": "Koleksiyon eşleştiricisi", // "item.edit.tabs.item-mapper.title": "Item Edit - Collection Mapper", - // TODO New key - Add a translation - "item.edit.tabs.item-mapper.title": "Item Edit - Collection Mapper", + "item.edit.tabs.item-mapper.title": "Öge düzenle- Koleksiyon eşleştiricisi", // "item.edit.item-mapper.buttons.add": "Map item to selected collections", - // TODO New key - Add a translation - "item.edit.item-mapper.buttons.add": "Map item to selected collections", + "item.edit.item-mapper.buttons.add": "Ögeyi seçili koleksiyonlarla eşleştir", // "item.edit.item-mapper.buttons.remove": "Remove item's mapping for selected collections", - // TODO New key - Add a translation - "item.edit.item-mapper.buttons.remove": "Remove item's mapping for selected collections", + "item.edit.item-mapper.buttons.remove": "Seçili koleksiyonların öge eşleştirmelerini kaldır", // "item.edit.item-mapper.cancel": "Cancel", - // TODO New key - Add a translation - "item.edit.item-mapper.cancel": "Cancel", + "item.edit.item-mapper.cancel": "İptal et", // "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.", - // TODO New key - Add a translation - "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": "Öge eşleme aracı, yöneticilerin bu öğeyi diğer koleksiyonlarla eşleştirmesini ögeleri eşleştirmesini sağlar. Koleksiyonları arayabilir ve bunları eşleyebilir veya öğenin şu anda eşlendiği koleksiyonların listesine göz atabilirsiniz.", // "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", - // TODO New key - Add a translation - "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", + "item.edit.item-mapper.head": "Öge eşleştirici - Ögeleri koleksiyonlarla eşleştirir", // "item.edit.item-mapper.item": "Item: \"{{name}}\"", - // TODO New key - Add a translation - "item.edit.item-mapper.item": "Item: \"{{name}}\"", + "item.edit.item-mapper.item": "Öge: \"{{name}}\"", // "item.edit.item-mapper.no-search": "Please enter a query to search", - // TODO New key - Add a translation - "item.edit.item-mapper.no-search": "Please enter a query to search", + "item.edit.item-mapper.no-search": "Lütfen arama yapmak için bir soru giriniz.", // "item.edit.item-mapper.notifications.add.error.content": "Errors occurred for mapping of item to {{amount}} collections.", - // TODO New key - Add a translation - "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": "Ögelerin {{amount}} koleksiyonlarla eşleştirirken bir hata oluştu.", // "item.edit.item-mapper.notifications.add.error.head": "Mapping errors", - // TODO New key - Add a translation - "item.edit.item-mapper.notifications.add.error.head": "Mapping errors", + "item.edit.item-mapper.notifications.add.error.head": "Eşleştirme hataları", // "item.edit.item-mapper.notifications.add.success.content": "Successfully mapped item to {{amount}} collections.", - // TODO New key - Add a translation - "item.edit.item-mapper.notifications.add.success.content": "Successfully mapped item to {{amount}} collections.", + "item.edit.item-mapper.notifications.add.success.content": "Ögeler {{amount}} koleksiyonlarla başarıyla eşleştirildi.", // "item.edit.item-mapper.notifications.add.success.head": "Mapping completed", - // TODO New key - Add a translation - "item.edit.item-mapper.notifications.add.success.head": "Mapping completed", + "item.edit.item-mapper.notifications.add.success.head": "Eşleştirme tamamlandı.", // "item.edit.item-mapper.notifications.remove.error.content": "Errors occurred for the removal of the mapping to {{amount}} collections.", - // TODO New key - Add a translation - "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": "Ögelerin {{amount}} koleksiyonlarla eşleştirmeleri kaldırılırken bir hata oluştu.", // "item.edit.item-mapper.notifications.remove.error.head": "Removal of mapping errors", - // TODO New key - Add a translation - "item.edit.item-mapper.notifications.remove.error.head": "Removal of mapping errors", + "item.edit.item-mapper.notifications.remove.error.head": "Eşleştirme hatalarının kaldırılması", // "item.edit.item-mapper.notifications.remove.success.content": "Successfully removed mapping of item to {{amount}} collections.", - // TODO New key - Add a translation - "item.edit.item-mapper.notifications.remove.success.content": "Successfully removed mapping of item to {{amount}} collections.", + "item.edit.item-mapper.notifications.remove.success.content": "Ögeler {{amount}} koleksiyonlarla eşleştirmeleri başarıyla kaldırıldı.", // "item.edit.item-mapper.notifications.remove.success.head": "Removal of mapping completed", - // TODO New key - Add a translation - "item.edit.item-mapper.notifications.remove.success.head": "Removal of mapping completed", + "item.edit.item-mapper.notifications.remove.success.head": "Eşleştirmelerin kaldırılması tamamlandı.", // "item.edit.item-mapper.tabs.browse": "Browse mapped collections", - // TODO New key - Add a translation - "item.edit.item-mapper.tabs.browse": "Browse mapped collections", + "item.edit.item-mapper.tabs.browse": "Eşleştirilen koleksiyonları ara", // "item.edit.item-mapper.tabs.map": "Map new collections", - // TODO New key - Add a translation - "item.edit.item-mapper.tabs.map": "Map new collections", + "item.edit.item-mapper.tabs.map": "Yeni koleksiyonları eşleştir", // "item.edit.metadata.add-button": "Add", - // TODO New key - Add a translation - "item.edit.metadata.add-button": "Add", + "item.edit.metadata.add-button": "Ekle", // "item.edit.metadata.discard-button": "Discard", - // TODO New key - Add a translation - "item.edit.metadata.discard-button": "Discard", + "item.edit.metadata.discard-button": "Sil", // "item.edit.metadata.edit.buttons.edit": "Edit", - // TODO New key - Add a translation - "item.edit.metadata.edit.buttons.edit": "Edit", + "item.edit.metadata.edit.buttons.edit": "Düzenle", // "item.edit.metadata.edit.buttons.remove": "Remove", - // TODO New key - Add a translation - "item.edit.metadata.edit.buttons.remove": "Remove", + "item.edit.metadata.edit.buttons.remove": "Kaldır", // "item.edit.metadata.edit.buttons.undo": "Undo changes", - // TODO New key - Add a translation - "item.edit.metadata.edit.buttons.undo": "Undo changes", + "item.edit.metadata.edit.buttons.undo": "Değişiklikleri geri al", // "item.edit.metadata.edit.buttons.unedit": "Stop editing", - // TODO New key - Add a translation - "item.edit.metadata.edit.buttons.unedit": "Stop editing", + "item.edit.metadata.edit.buttons.unedit": "Düzenlemeyi bitir", // "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", - // TODO New key - Add a translation - "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", + "item.edit.metadata.empty": "Öğe şu anda herhangi bir meta veri içermiyor. Bir meta veri değeri eklemeye başlamak için Ekle'ye tıklayın.", // "item.edit.metadata.headers.edit": "Edit", - // TODO New key - Add a translation - "item.edit.metadata.headers.edit": "Edit", + "item.edit.metadata.headers.edit": "Düzenle", // "item.edit.metadata.headers.field": "Field", - // TODO New key - Add a translation - "item.edit.metadata.headers.field": "Field", + "item.edit.metadata.headers.field": "Alan", // "item.edit.metadata.headers.language": "Lang", - // TODO New key - Add a translation - "item.edit.metadata.headers.language": "Lang", + "item.edit.metadata.headers.language": "Dil", // "item.edit.metadata.headers.value": "Value", - // TODO New key - Add a translation - "item.edit.metadata.headers.value": "Value", + "item.edit.metadata.headers.value": "Değer", // "item.edit.metadata.metadatafield.invalid": "Please choose a valid metadata field", - // TODO New key - Add a translation - "item.edit.metadata.metadatafield.invalid": "Please choose a valid metadata field", + "item.edit.metadata.metadatafield.invalid": "Lütfen geçerli bir meta veri alanı seçin", // "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - // TODO New key - Add a translation - "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.metadata.notifications.discarded.content": "Yaptığınız değişiklikler silindi.Yaptığınız değişiklikleri geri yüklemek için 'Geri al' butonuna tıklayınız.", // "item.edit.metadata.notifications.discarded.title": "Changed discarded", - // TODO New key - Add a translation - "item.edit.metadata.notifications.discarded.title": "Changed discarded", + "item.edit.metadata.notifications.discarded.title": "Değişiklikler silindi", // "item.edit.metadata.notifications.error.title": "An error occurred", - // TODO New key - Add a translation - "item.edit.metadata.notifications.error.title": "An error occurred", + "item.edit.metadata.notifications.error.title": "Bir hata oluştu", // "item.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", - // TODO New key - Add a translation - "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": "Değişiklikleriniz kaydedilmedi. Lütfen kaydetmeden önce tüm alanların geçerli olduğundan emin olun.", // "item.edit.metadata.notifications.invalid.title": "Metadata invalid", - // TODO New key - Add a translation - "item.edit.metadata.notifications.invalid.title": "Metadata invalid", + "item.edit.metadata.notifications.invalid.title": "Meta veri geçersiz", // "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", - // TODO New key - Add a translation - "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": "Şu anda üzerinde çalıştığınız öge başka bir kullanıcı tarafından değiştirildi.Mevcut değişiklikleriniz çakışma olmasını önlemek için silindi.", // "item.edit.metadata.notifications.outdated.title": "Changed outdated", - // TODO New key - Add a translation - "item.edit.metadata.notifications.outdated.title": "Changed outdated", + "item.edit.metadata.notifications.outdated.title": "Değişiklikler zaman aşımına uğradı.", // "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", - // TODO New key - Add a translation - "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", + "item.edit.metadata.notifications.saved.content": "Ögenin meta verilerinde yaptığınız değişiklikler kaydedildi.", // "item.edit.metadata.notifications.saved.title": "Metadata saved", - // TODO New key - Add a translation - "item.edit.metadata.notifications.saved.title": "Metadata saved", + "item.edit.metadata.notifications.saved.title": "Meta veriler kaydedildi", // "item.edit.metadata.reinstate-button": "Undo", - // TODO New key - Add a translation - "item.edit.metadata.reinstate-button": "Undo", + "item.edit.metadata.reinstate-button": "Geri al", // "item.edit.metadata.save-button": "Save", - // TODO New key - Add a translation - "item.edit.metadata.save-button": "Save", + "item.edit.metadata.save-button": "Kaydet", // "item.edit.modify.overview.field": "Field", - // TODO New key - Add a translation - "item.edit.modify.overview.field": "Field", + "item.edit.modify.overview.field": "Alan", // "item.edit.modify.overview.language": "Language", - // TODO New key - Add a translation - "item.edit.modify.overview.language": "Language", + "item.edit.modify.overview.language": "Dil", // "item.edit.modify.overview.value": "Value", - // TODO New key - Add a translation - "item.edit.modify.overview.value": "Value", + "item.edit.modify.overview.value": "Değer", // "item.edit.move.cancel": "Cancel", - // TODO New key - Add a translation - "item.edit.move.cancel": "Cancel", + "item.edit.move.cancel": "İptal et", // "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.", - // TODO New key - Add a translation - "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": "Bu öğeyi taşımak istediğiniz koleksiyonu seçin. Görüntülenen koleksiyonların listesini daraltmak için arama kısmına bir arama sorgusu girebilirsiniz.", // "item.edit.move.error": "An error occurred when attempting to move the item", - // TODO New key - Add a translation - "item.edit.move.error": "An error occurred when attempting to move the item", + "item.edit.move.error": "Öğeyi taşımaya çalışırken bir hata oluştu", // "item.edit.move.head": "Move item: {{id}}", - // TODO New key - Add a translation - "item.edit.move.head": "Move item: {{id}}", + "item.edit.move.head": "Kaldırılacak öge: {{id}}", // "item.edit.move.inheritpolicies.checkbox": "Inherit policies", - // TODO New key - Add a translation - "item.edit.move.inheritpolicies.checkbox": "Inherit policies", + "item.edit.move.inheritpolicies.checkbox": "Poliçeyi devral", // "item.edit.move.inheritpolicies.description": "Inherit the default policies of the destination collection", - // TODO New key - Add a translation - "item.edit.move.inheritpolicies.description": "Inherit the default policies of the destination collection", + "item.edit.move.inheritpolicies.description": "Hedef koleksiyonun varsayılan poliçelerini devral", // "item.edit.move.move": "Move", - // TODO New key - Add a translation - "item.edit.move.move": "Move", + "item.edit.move.move": "Taşı", // "item.edit.move.processing": "Moving...", - // TODO New key - Add a translation - "item.edit.move.processing": "Moving...", + "item.edit.move.processing": "Taşınıyor...", // "item.edit.move.search.placeholder": "Enter a search query to look for collections", - // TODO New key - Add a translation - "item.edit.move.search.placeholder": "Enter a search query to look for collections", + "item.edit.move.search.placeholder": "Lütfen koleksiyonları aramak için bir arama sorgusu giriniz.", // "item.edit.move.success": "The item has been moved successfully", - // TODO New key - Add a translation - "item.edit.move.success": "The item has been moved successfully", + "item.edit.move.success": "Öge başarıyla taşındı", // "item.edit.move.title": "Move item", - // TODO New key - Add a translation - "item.edit.move.title": "Move item", + "item.edit.move.title": "Ögeleri taşı", // "item.edit.private.cancel": "Cancel", - // TODO New key - Add a translation - "item.edit.private.cancel": "Cancel", + "item.edit.private.cancel": "İptal et", // "item.edit.private.confirm": "Make it Private", - // TODO New key - Add a translation - "item.edit.private.confirm": "Make it Private", + "item.edit.private.confirm": "Gizli yap", // "item.edit.private.description": "Are you sure this item should be made private in the archive?", - // TODO New key - Add a translation - "item.edit.private.description": "Are you sure this item should be made private in the archive?", + "item.edit.private.description": "Bu öğenin arşivde gizli yapılması gerektiğinden emin misiniz?", // "item.edit.private.error": "An error occurred while making the item private", - // TODO New key - Add a translation - "item.edit.private.error": "An error occurred while making the item private", + "item.edit.private.error": "Öge gizli yapılırken bir hata oluştu", // "item.edit.private.header": "Make item private: {{ id }}", - // TODO New key - Add a translation - "item.edit.private.header": "Make item private: {{ id }}", + "item.edit.private.header": "Ögeyi gizli yap: {{ id }}", // "item.edit.private.success": "The item is now private", - // TODO New key - Add a translation - "item.edit.private.success": "The item is now private", + "item.edit.private.success": "Öge gizlendi", // "item.edit.public.cancel": "Cancel", - // TODO New key - Add a translation - "item.edit.public.cancel": "Cancel", + "item.edit.public.cancel": "İptal et", // "item.edit.public.confirm": "Make it Public", - // TODO New key - Add a translation - "item.edit.public.confirm": "Make it Public", + "item.edit.public.confirm": "Ögeyi herkese açık yap", // "item.edit.public.description": "Are you sure this item should be made public in the archive?", - // TODO New key - Add a translation - "item.edit.public.description": "Are you sure this item should be made public in the archive?", + "item.edit.public.description": "Bu öğenin arşivde herkese açık yapılması gerektiğinden emin misiniz?", // "item.edit.public.error": "An error occurred while making the item public", - // TODO New key - Add a translation - "item.edit.public.error": "An error occurred while making the item public", + "item.edit.public.error": "Öge herkese açık yapılırken bir hata oluştu", // "item.edit.public.header": "Make item public: {{ id }}", - // TODO New key - Add a translation - "item.edit.public.header": "Make item public: {{ id }}", + "item.edit.public.header": "Herkese açık yapılacak öge: {{ id }}", // "item.edit.public.success": "The item is now public", - // TODO New key - Add a translation - "item.edit.public.success": "The item is now public", + "item.edit.public.success": "Öge herkese açık yapıldı", // "item.edit.reinstate.cancel": "Cancel", - // TODO New key - Add a translation - "item.edit.reinstate.cancel": "Cancel", + "item.edit.reinstate.cancel": "İptal et", // "item.edit.reinstate.confirm": "Reinstate", - // TODO New key - Add a translation - "item.edit.reinstate.confirm": "Reinstate", + "item.edit.reinstate.confirm": "Getir yükle", // "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", - // TODO New key - Add a translation - "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", + "item.edit.reinstate.description": "Bu öğenin arşive geri yüklenmesi gerektiğinden emin misiniz?", // "item.edit.reinstate.error": "An error occurred while reinstating the item", - // TODO New key - Add a translation - "item.edit.reinstate.error": "An error occurred while reinstating the item", + "item.edit.reinstate.error": "Öğe geri yüklenirken bir hata oluştu", // "item.edit.reinstate.header": "Reinstate item: {{ id }}", - // TODO New key - Add a translation - "item.edit.reinstate.header": "Reinstate item: {{ id }}", + "item.edit.reinstate.header": "Geri yüklenecek öge: {{ id }}", // "item.edit.reinstate.success": "The item was reinstated successfully", - // TODO New key - Add a translation - "item.edit.reinstate.success": "The item was reinstated successfully", + "item.edit.reinstate.success": "Öge başarıyla geri yüklendi", // "item.edit.relationships.discard-button": "Discard", - // TODO New key - Add a translation - "item.edit.relationships.discard-button": "Discard", + "item.edit.relationships.discard-button": "Sil", // "item.edit.relationships.edit.buttons.add": "Add", - // TODO New key - Add a translation - "item.edit.relationships.edit.buttons.add": "Add", + "item.edit.relationships.edit.buttons.add": "Ekle", // "item.edit.relationships.edit.buttons.remove": "Remove", - // TODO New key - Add a translation - "item.edit.relationships.edit.buttons.remove": "Remove", + "item.edit.relationships.edit.buttons.remove": "Kaldır", // "item.edit.relationships.edit.buttons.undo": "Undo changes", - // TODO New key - Add a translation - "item.edit.relationships.edit.buttons.undo": "Undo changes", + "item.edit.relationships.edit.buttons.undo": "Değişiklikleri geri al", // "item.edit.relationships.no-relationships": "No relationships", - // TODO New key - Add a translation - "item.edit.relationships.no-relationships": "No relationships", + "item.edit.relationships.no-relationships": "İlişki yok", // "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - // TODO New key - Add a translation - "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.relationships.notifications.discarded.content": "Yaptığınız değişiklikler silindi.Yaptığınız değişiklikleri geri yüklemek için 'Geri al' butonuna tıklayınız.", // "item.edit.relationships.notifications.discarded.title": "Changes discarded", - // TODO New key - Add a translation - "item.edit.relationships.notifications.discarded.title": "Changes discarded", + "item.edit.relationships.notifications.discarded.title": "Değişiklikler silindi", // "item.edit.relationships.notifications.failed.title": "Error editing relationships", - // TODO New key - Add a translation - "item.edit.relationships.notifications.failed.title": "Error editing relationships", + "item.edit.relationships.notifications.failed.title": "İlişkileri düzenlemede hata", // "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", - // TODO New key - Add a translation - "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": "Şu anda üzerinde çalıştığınız öge başka bir kullanıcı tarafından değiştirildi.Mevcut değişiklikleriniz çakışma olmasını önlemek için silindi.", // "item.edit.relationships.notifications.outdated.title": "Changes outdated", - // TODO New key - Add a translation - "item.edit.relationships.notifications.outdated.title": "Changes outdated", + "item.edit.relationships.notifications.outdated.title": "Değişiklikler zaman aşımına uğradı.", // "item.edit.relationships.notifications.saved.content": "Your changes to this item's relationships were saved.", - // TODO New key - Add a translation - "item.edit.relationships.notifications.saved.content": "Your changes to this item's relationships were saved.", + "item.edit.relationships.notifications.saved.content": "Bu öğenin ilişkilerinde yaptığınız değişiklikler kaydedildi.", // "item.edit.relationships.notifications.saved.title": "Relationships saved", - // TODO New key - Add a translation - "item.edit.relationships.notifications.saved.title": "Relationships saved", + "item.edit.relationships.notifications.saved.title": "İlişkiler kaydedildi", // "item.edit.relationships.reinstate-button": "Undo", - // TODO New key - Add a translation - "item.edit.relationships.reinstate-button": "Undo", + "item.edit.relationships.reinstate-button": "Geri al", // "item.edit.relationships.save-button": "Save", - // TODO New key - Add a translation - "item.edit.relationships.save-button": "Save", + "item.edit.relationships.save-button": "Kaydet", // "item.edit.relationships.no-entity-type": "Add 'dspace.entity.type' metadata to enable relationships for this item", - // TODO New key - Add a translation - "item.edit.relationships.no-entity-type": "Add 'dspace.entity.type' metadata to enable relationships for this item", + "item.edit.relationships.no-entity-type": "Bu öğe için ilişkileri etkinleştirmek için 'dspace.entity.type' meta verilerini ekleyin", // "item.edit.tabs.bitstreams.head": "Bitstreams", - // TODO New key - Add a translation - "item.edit.tabs.bitstreams.head": "Bitstreams", + "item.edit.tabs.bitstreams.head": "Veri akışları", // "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", - // TODO New key - Add a translation - "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", + "item.edit.tabs.bitstreams.title": "Öge düzenle - Veri akışları", // "item.edit.tabs.curate.head": "Curate", - // TODO New key - Add a translation - "item.edit.tabs.curate.head": "Curate", + "item.edit.tabs.curate.head": "Düzenleme", // "item.edit.tabs.curate.title": "Item Edit - Curate", - // TODO New key - Add a translation - "item.edit.tabs.curate.title": "Item Edit - Curate", + "item.edit.tabs.curate.title": "Öge düzenle - Düzenleme", // "item.edit.tabs.metadata.head": "Metadata", - // TODO New key - Add a translation - "item.edit.tabs.metadata.head": "Metadata", + "item.edit.tabs.metadata.head": "Meta veri", // "item.edit.tabs.metadata.title": "Item Edit - Metadata", - // TODO New key - Add a translation - "item.edit.tabs.metadata.title": "Item Edit - Metadata", + "item.edit.tabs.metadata.title": "Öge düzenle - Meta veri", // "item.edit.tabs.relationships.head": "Relationships", - // TODO New key - Add a translation - "item.edit.tabs.relationships.head": "Relationships", + "item.edit.tabs.relationships.head": "İlişkiler", // "item.edit.tabs.relationships.title": "Item Edit - Relationships", - // TODO New key - Add a translation - "item.edit.tabs.relationships.title": "Item Edit - Relationships", + "item.edit.tabs.relationships.title": "Öge düzenle - İlişkiler", // "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", + "item.edit.tabs.status.buttons.authorizations.button": "Yetkilendiriliyor...", // "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", + "item.edit.tabs.status.buttons.authorizations.label": "Öğenin yetkilendirme politikalarını düzenle", // "item.edit.tabs.status.buttons.delete.button": "Permanently delete", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.delete.button": "Permanently delete", + "item.edit.tabs.status.buttons.delete.button": "Kalıcı olarak sil", // "item.edit.tabs.status.buttons.delete.label": "Completely expunge item", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.delete.label": "Completely expunge item", + "item.edit.tabs.status.buttons.delete.label": "Ögeyi kalıcı olarak sil", // "item.edit.tabs.status.buttons.mappedCollections.button": "Mapped collections", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.mappedCollections.button": "Mapped collections", + "item.edit.tabs.status.buttons.mappedCollections.button": "Eşleştirilmiş koleksiyonlar", // "item.edit.tabs.status.buttons.mappedCollections.label": "Manage mapped collections", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.mappedCollections.label": "Manage mapped collections", + "item.edit.tabs.status.buttons.mappedCollections.label": "Eşlenen koleksiyonları yönetin", // "item.edit.tabs.status.buttons.move.button": "Move...", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.move.button": "Move...", + "item.edit.tabs.status.buttons.move.button": "Taşınıyor...", // "item.edit.tabs.status.buttons.move.label": "Move item to another collection", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.move.label": "Move item to another collection", + "item.edit.tabs.status.buttons.move.label": "Öğeyi başka bir koleksiyona taşı", // "item.edit.tabs.status.buttons.private.button": "Make it private...", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.private.button": "Make it private...", + "item.edit.tabs.status.buttons.private.button": "Gizleniyor...", // "item.edit.tabs.status.buttons.private.label": "Make item private", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.private.label": "Make item private", + "item.edit.tabs.status.buttons.private.label": "Ögeyi gizle", // "item.edit.tabs.status.buttons.public.button": "Make it public...", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.public.button": "Make it public...", + "item.edit.tabs.status.buttons.public.button": "Öge herkese açık yapılıyor...", // "item.edit.tabs.status.buttons.public.label": "Make item public", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.public.label": "Make item public", + "item.edit.tabs.status.buttons.public.label": "Herkese açık yap", // "item.edit.tabs.status.buttons.reinstate.button": "Reinstate...", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.reinstate.button": "Reinstate...", + "item.edit.tabs.status.buttons.reinstate.button": "Geri yükleniyor...", // "item.edit.tabs.status.buttons.reinstate.label": "Reinstate item into the repository", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.reinstate.label": "Reinstate item into the repository", + "item.edit.tabs.status.buttons.reinstate.label": "Öğeyi depoya geri yükle", // "item.edit.tabs.status.buttons.withdraw.button": "Withdraw...", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.withdraw.button": "Withdraw...", + "item.edit.tabs.status.buttons.withdraw.button": "Çıkar...", // "item.edit.tabs.status.buttons.withdraw.label": "Withdraw item from the repository", - // TODO New key - Add a translation - "item.edit.tabs.status.buttons.withdraw.label": "Withdraw item from the repository", + "item.edit.tabs.status.buttons.withdraw.label": "Depodan öğeyi çıkar", // "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.", - // TODO New key - Add a translation - "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": "Öğe yönetimi sayfasına hoş geldiniz. Buradan öğeyi çıkarabilir, geri yükleyebilir, taşıyabilir veya silebilirsiniz. Diğer sekmelerde de güncelleyebilir veya yeni meta veri / bit akışları ekleyebilirsiniz.", // "item.edit.tabs.status.head": "Status", - // TODO New key - Add a translation - "item.edit.tabs.status.head": "Status", + "item.edit.tabs.status.head": "Durum", // "item.edit.tabs.status.labels.handle": "Handle", - // TODO New key - Add a translation - "item.edit.tabs.status.labels.handle": "Handle", + "item.edit.tabs.status.labels.handle": "Takma ad", // "item.edit.tabs.status.labels.id": "Item Internal ID", - // TODO New key - Add a translation - "item.edit.tabs.status.labels.id": "Item Internal ID", + "item.edit.tabs.status.labels.id": "Öge Dahili Kimliğ", // "item.edit.tabs.status.labels.itemPage": "Item Page", - // TODO New key - Add a translation - "item.edit.tabs.status.labels.itemPage": "Item Page", + "item.edit.tabs.status.labels.itemPage": "Öge sayfası", // "item.edit.tabs.status.labels.lastModified": "Last Modified", - // TODO New key - Add a translation - "item.edit.tabs.status.labels.lastModified": "Last Modified", + "item.edit.tabs.status.labels.lastModified": "Son düzenleme", // "item.edit.tabs.status.title": "Item Edit - Status", - // TODO New key - Add a translation - "item.edit.tabs.status.title": "Item Edit - Status", + "item.edit.tabs.status.title": "Öge düzenle - Durum", // "item.edit.tabs.versionhistory.head": "Version History", - // TODO New key - Add a translation - "item.edit.tabs.versionhistory.head": "Version History", + "item.edit.tabs.versionhistory.head": "Sürüm Geçmişi", // "item.edit.tabs.versionhistory.title": "Item Edit - Version History", - // TODO New key - Add a translation - "item.edit.tabs.versionhistory.title": "Item Edit - Version History", + "item.edit.tabs.versionhistory.title": "Öge düzenle - Sürüm Geçmişi", // "item.edit.tabs.versionhistory.under-construction": "Editing or adding new versions is not yet possible in this user interface.", - // TODO New key - Add a translation - "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": "Bu kullanıcı arayüzünde henüz yeni sürümleri düzenlemek veya eklemek mümkün değil.", // "item.edit.tabs.view.head": "View Item", - // TODO New key - Add a translation - "item.edit.tabs.view.head": "View Item", + "item.edit.tabs.view.head": "Ürünü incele", // "item.edit.tabs.view.title": "Item Edit - View", - // TODO New key - Add a translation - "item.edit.tabs.view.title": "Item Edit - View", + "item.edit.tabs.view.title": "Öge düzenle - incele", // "item.edit.withdraw.cancel": "Cancel", - // TODO New key - Add a translation - "item.edit.withdraw.cancel": "Cancel", + "item.edit.withdraw.cancel": "İptal et", // "item.edit.withdraw.confirm": "Withdraw", - // TODO New key - Add a translation - "item.edit.withdraw.confirm": "Withdraw", + "item.edit.withdraw.confirm": "Çıkar", // "item.edit.withdraw.description": "Are you sure this item should be withdrawn from the archive?", - // TODO New key - Add a translation - "item.edit.withdraw.description": "Are you sure this item should be withdrawn from the archive?", + "item.edit.withdraw.description": "Bu öğenin arşivden çıkartılması gerektiğinden emin misiniz?", // "item.edit.withdraw.error": "An error occurred while withdrawing the item", - // TODO New key - Add a translation - "item.edit.withdraw.error": "An error occurred while withdrawing the item", + "item.edit.withdraw.error": "Öğe çıkartılırken bir hata oluştu", // "item.edit.withdraw.header": "Withdraw item: {{ id }}", - // TODO New key - Add a translation - "item.edit.withdraw.header": "Withdraw item: {{ id }}", + "item.edit.withdraw.header": "Çıkarılan öge: {{ id }}", // "item.edit.withdraw.success": "The item was withdrawn successfully", - // TODO New key - Add a translation - "item.edit.withdraw.success": "The item was withdrawn successfully", + "item.edit.withdraw.success": "Öğe başarıyla çıkartıldı", // "item.listelement.badge": "Item", - // TODO New key - Add a translation - "item.listelement.badge": "Item", + "item.listelement.badge": "Öge", // "item.page.description": "Description", - // TODO New key - Add a translation - "item.page.description": "Description", + "item.page.description": "Açıklama", // "item.page.edit": "Edit this item", - // TODO New key - Add a translation - "item.page.edit": "Edit this item", + "item.page.edit": "Bu ögeyi düzenle", // "item.page.journal-issn": "Journal ISSN", - // TODO New key - Add a translation - "item.page.journal-issn": "Journal ISSN", + "item.page.journal-issn": "Süreli Yayın ISSN", // "item.page.journal-title": "Journal Title", - // TODO New key - Add a translation - "item.page.journal-title": "Journal Title", + "item.page.journal-title": "Süreli Yayın başlığı", // "item.page.publisher": "Publisher", - // TODO New key - Add a translation - "item.page.publisher": "Publisher", + "item.page.publisher": "Yayınevi", // "item.page.titleprefix": "Item: ", - // TODO New key - Add a translation - "item.page.titleprefix": "Item: ", + "item.page.titleprefix": "Öge: ", // "item.page.volume-title": "Volume Title", - // TODO New key - Add a translation - "item.page.volume-title": "Volume Title", + "item.page.volume-title": "Cilt Başlığı", // "item.search.results.head": "Item Search Results", - // TODO New key - Add a translation - "item.search.results.head": "Item Search Results", + "item.search.results.head": "Öge Arama Sonuçları", // "item.search.title": "DSpace Angular :: Item Search", - // TODO New key - Add a translation - "item.search.title": "DSpace Angular :: Item Search", - + "item.search.title": "DSpace Angular :: Öge Arama", // "item.page.abstract": "Abstract", - // TODO New key - Add a translation - "item.page.abstract": "Abstract", + "item.page.abstract": "Özet", // "item.page.author": "Authors", - // TODO New key - Add a translation - "item.page.author": "Authors", + "item.page.author": "Yazarlar", // "item.page.citation": "Citation", - // TODO New key - Add a translation - "item.page.citation": "Citation", + "item.page.citation": "Alıntı", // "item.page.collections": "Collections", - // TODO New key - Add a translation - "item.page.collections": "Collections", + "item.page.collections": "Koleksiyonlar", // "item.page.date": "Date", - // TODO New key - Add a translation - "item.page.date": "Date", + "item.page.date": "Tarih", // "item.page.edit": "Edit this item", - // TODO New key - Add a translation - "item.page.edit": "Edit this item", + "item.page.edit": "Bu öğeyi düzenle", // "item.page.files": "Files", - // TODO New key - Add a translation - "item.page.files": "Files", + "item.page.files": "Dosyalar", // "item.page.filesection.description": "Description:", - // TODO New key - Add a translation - "item.page.filesection.description": "Description:", + "item.page.filesection.description": "Açıklama", // "item.page.filesection.download": "Download", - // TODO New key - Add a translation - "item.page.filesection.download": "Download", + "item.page.filesection.download": "İndir", // "item.page.filesection.format": "Format:", - // TODO New key - Add a translation "item.page.filesection.format": "Format:", // "item.page.filesection.name": "Name:", - // TODO New key - Add a translation - "item.page.filesection.name": "Name:", + "item.page.filesection.name": "Ad:", // "item.page.filesection.size": "Size:", - // TODO New key - Add a translation - "item.page.filesection.size": "Size:", + "item.page.filesection.size": "Boyut:", // "item.page.journal.search.title": "Articles in this journal", - // TODO New key - Add a translation - "item.page.journal.search.title": "Articles in this journal", + "item.page.journal.search.title": "Bu süreli yayındaki makaleler", // "item.page.link.full": "Full item page", - // TODO New key - Add a translation - "item.page.link.full": "Full item page", + "item.page.link.full": "Tam öğe sayfası", // "item.page.link.simple": "Simple item page", - // TODO New key - Add a translation - "item.page.link.simple": "Simple item page", + "item.page.link.simple": "Sadeleştirilmiş öğe sayfası", // "item.page.person.search.title": "Articles by this author", - // TODO New key - Add a translation - "item.page.person.search.title": "Articles by this author", + "item.page.person.search.title": "Bu yazarın makaleleri", // "item.page.related-items.view-more": "Show {{ amount }} more", - // TODO New key - Add a translation - "item.page.related-items.view-more": "Show {{ amount }} more", + "item.page.related-items.view-more": "Daha fazla göster {{ amount }}", // "item.page.related-items.view-less": "Hide last {{ amount }}", - // TODO New key - Add a translation - "item.page.related-items.view-less": "Hide last {{ amount }}", + "item.page.related-items.view-less": "Sonuncuyu gizle {{ amount }}", // "item.page.relationships.isAuthorOfPublication": "Publications", - // TODO New key - Add a translation - "item.page.relationships.isAuthorOfPublication": "Publications", + "item.page.relationships.isAuthorOfPublication": "Yayınlar", // "item.page.relationships.isJournalOfPublication": "Publications", - // TODO New key - Add a translation - "item.page.relationships.isJournalOfPublication": "Publications", + "item.page.relationships.isJournalOfPublication": "Yayınlar", // "item.page.relationships.isOrgUnitOfPerson": "Authors", - // TODO New key - Add a translation - "item.page.relationships.isOrgUnitOfPerson": "Authors", + "item.page.relationships.isOrgUnitOfPerson": "Yazarlar", // "item.page.relationships.isOrgUnitOfProject": "Research Projects", - // TODO New key - Add a translation - "item.page.relationships.isOrgUnitOfProject": "Research Projects", + "item.page.relationships.isOrgUnitOfProject": "Araştırma projeleri", // "item.page.subject": "Keywords", - // TODO New key - Add a translation - "item.page.subject": "Keywords", + "item.page.subject": "Anahtar kelimeler", // "item.page.uri": "URI", - // TODO New key - Add a translation "item.page.uri": "URI", // "item.page.bitstreams.view-more": "Show more", - // TODO New key - Add a translation - "item.page.bitstreams.view-more": "Show more", + "item.page.bitstreams.view-more": "Daha fazla göster", // "item.page.bitstreams.collapse": "Collapse", - // TODO New key - Add a translation - "item.page.bitstreams.collapse": "Collapse", + "item.page.bitstreams.collapse": "Daralt", // "item.page.filesection.original.bundle" : "Original bundle", - // TODO New key - Add a translation - "item.page.filesection.original.bundle" : "Original bundle", + "item.page.filesection.original.bundle" : "Orijinal seri", // "item.page.filesection.license.bundle" : "License bundle", - // TODO New key - Add a translation - "item.page.filesection.license.bundle" : "License bundle", + "item.page.filesection.license.bundle" : "Lisanslı seri", // "item.preview.dc.identifier.uri": "Identifier:", - // TODO New key - Add a translation - "item.preview.dc.identifier.uri": "Identifier:", + "item.preview.dc.identifier.uri": "Belirteç:", // "item.preview.dc.contributor.author": "Authors:", - // TODO New key - Add a translation - "item.preview.dc.contributor.author": "Authors:", + "item.preview.dc.contributor.author": "Yazarlar:", // "item.preview.dc.date.issued": "Published date:", - // TODO New key - Add a translation - "item.preview.dc.date.issued": "Published date:", + "item.preview.dc.date.issued": "Yayınlanma tarihi:", // "item.preview.dc.description.abstract": "Abstract:", - // TODO New key - Add a translation - "item.preview.dc.description.abstract": "Abstract:", + "item.preview.dc.description.abstract": "Özet:", // "item.preview.dc.identifier.other": "Other identifier:", - // TODO New key - Add a translation - "item.preview.dc.identifier.other": "Other identifier:", + "item.preview.dc.identifier.other": "Diğer Belirteçler:", // "item.preview.dc.language.iso": "Language:", - // TODO New key - Add a translation - "item.preview.dc.language.iso": "Language:", + "item.preview.dc.language.iso": "Dil:", // "item.preview.dc.subject": "Subjects:", - // TODO New key - Add a translation - "item.preview.dc.subject": "Subjects:", + "item.preview.dc.subject": "Konular:", // "item.preview.dc.title": "Title:", - // TODO New key - Add a translation - "item.preview.dc.title": "Title:", + "item.preview.dc.title": "Başlık:", // "item.preview.person.familyName": "Surname:", - // TODO New key - Add a translation - "item.preview.person.familyName": "Surname:", + "item.preview.person.familyName": "Soyad:", // "item.preview.person.givenName": "Name:", - // TODO New key - Add a translation - "item.preview.person.givenName": "Name:", + "item.preview.person.givenName": "Ad:", // "item.preview.person.identifier.orcid": "ORCID:", - // TODO New key - Add a translation "item.preview.person.identifier.orcid": "ORCID:", // "item.select.confirm": "Confirm selected", - // TODO New key - Add a translation - "item.select.confirm": "Confirm selected", + "item.select.confirm": "Seçileni onayla", // "item.select.empty": "No items to show", - // TODO New key - Add a translation - "item.select.empty": "No items to show", + "item.select.empty": "Gösterilecek öğe yok", // "item.select.table.author": "Author", - // TODO New key - Add a translation - "item.select.table.author": "Author", + "item.select.table.author": "Yazar", // "item.select.table.collection": "Collection", - // TODO New key - Add a translation - "item.select.table.collection": "Collection", + "item.select.table.collection": "Koleksiyon", // "item.select.table.title": "Title", - // TODO New key - Add a translation - "item.select.table.title": "Title", + "item.select.table.title": "Başlık", // "item.version.history.empty": "There are no other versions for this item yet.", - // TODO New key - Add a translation - "item.version.history.empty": "There are no other versions for this item yet.", + "item.version.history.empty": "Bu öğe için henüz başka sürüm yok.", // "item.version.history.head": "Version History", - // TODO New key - Add a translation - "item.version.history.head": "Version History", + "item.version.history.head": "Sürüm Geçmişi", // "item.version.history.return": "Return", - // TODO New key - Add a translation - "item.version.history.return": "Return", + "item.version.history.return": "Geri dön", // "item.version.history.selected": "Selected version", - // TODO New key - Add a translation - "item.version.history.selected": "Selected version", + "item.version.history.selected": "Seçilen sürüm", // "item.version.history.table.version": "Version", - // TODO New key - Add a translation - "item.version.history.table.version": "Version", + "item.version.history.table.version": "Sürüm", // "item.version.history.table.item": "Item", - // TODO New key - Add a translation - "item.version.history.table.item": "Item", + "item.version.history.table.item": "Öge", // "item.version.history.table.editor": "Editor", - // TODO New key - Add a translation - "item.version.history.table.editor": "Editor", + "item.version.history.table.editor": "Editör", // "item.version.history.table.date": "Date", - // TODO New key - Add a translation - "item.version.history.table.date": "Date", + "item.version.history.table.date": "Tarih", // "item.version.history.table.summary": "Summary", - // TODO New key - Add a translation - "item.version.history.table.summary": "Summary", + "item.version.history.table.summary": "Özet", // "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", - // TODO New key - Add a translation - "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", + "item.version.notice": "Bu, bu öğenin en son sürümü değil. En son sürüm burada bulunabilir.", // "journal.listelement.badge": "Journal", - // TODO New key - Add a translation - "journal.listelement.badge": "Journal", + "journal.listelement.badge": "Süreli yayın", // "journal.page.description": "Description", - // TODO New key - Add a translation - "journal.page.description": "Description", + "journal.page.description": "Açıklama", // "journal.page.edit": "Edit this item", - // TODO New key - Add a translation - "journal.page.edit": "Edit this item", + "journal.page.edit": "Bu öğeyi düzenle", // "journal.page.editor": "Editor-in-Chief", - // TODO New key - Add a translation - "journal.page.editor": "Editor-in-Chief", + "journal.page.editor": "Genel Yayın Yönetmeni", // "journal.page.issn": "ISSN", - // TODO New key - Add a translation "journal.page.issn": "ISSN", // "journal.page.publisher": "Publisher", - // TODO New key - Add a translation - "journal.page.publisher": "Publisher", + "journal.page.publisher": "Yayınevi", // "journal.page.titleprefix": "Journal: ", - // TODO New key - Add a translation - "journal.page.titleprefix": "Journal: ", + "journal.page.titleprefix": "Süreli yayın: ", // "journal.search.results.head": "Journal Search Results", - // TODO New key - Add a translation - "journal.search.results.head": "Journal Search Results", + "journal.search.results.head": "Süreli Yayın Arama Sonuçları", // "journal.search.title": "DSpace Angular :: Journal Search", - // TODO New key - Add a translation - "journal.search.title": "DSpace Angular :: Journal Search", + "journal.search.title": "DSpace Angular :: Süreli Yayın Arama", // "journalissue.listelement.badge": "Journal Issue", - // TODO New key - Add a translation - "journalissue.listelement.badge": "Journal Issue", + "journalissue.listelement.badge": "Süreli Yayın Sayısı", // "journalissue.page.description": "Description", - // TODO New key - Add a translation - "journalissue.page.description": "Description", + "journalissue.page.description": "Açıklama", // "journalissue.page.edit": "Edit this item", - // TODO New key - Add a translation - "journalissue.page.edit": "Edit this item", + "journalissue.page.edit": "Bu öğeyi düzenle", // "journalissue.page.issuedate": "Issue Date", - // TODO New key - Add a translation - "journalissue.page.issuedate": "Issue Date", + "journalissue.page.issuedate": "Basım tarihi", // "journalissue.page.journal-issn": "Journal ISSN", - // TODO New key - Add a translation - "journalissue.page.journal-issn": "Journal ISSN", + "journalissue.page.journal-issn": "Süreli yayın ISSN", // "journalissue.page.journal-title": "Journal Title", - // TODO New key - Add a translation - "journalissue.page.journal-title": "Journal Title", + "journalissue.page.journal-title": "Süreli yayın Başlığı", // "journalissue.page.keyword": "Keywords", - // TODO New key - Add a translation - "journalissue.page.keyword": "Keywords", + "journalissue.page.keyword": "Anahtar kelimeler", // "journalissue.page.number": "Number", - // TODO New key - Add a translation - "journalissue.page.number": "Number", + "journalissue.page.number": "Sayı", // "journalissue.page.titleprefix": "Journal Issue: ", - // TODO New key - Add a translation - "journalissue.page.titleprefix": "Journal Issue: ", + "journalissue.page.titleprefix": "Süreli yayın sayısı: ", // "journalvolume.listelement.badge": "Journal Volume", - // TODO New key - Add a translation - "journalvolume.listelement.badge": "Journal Volume", + "journalvolume.listelement.badge": "Süreli yayın cilti", // "journalvolume.page.description": "Description", - // TODO New key - Add a translation - "journalvolume.page.description": "Description", + "journalvolume.page.description": "Açıklama", // "journalvolume.page.edit": "Edit this item", - // TODO New key - Add a translation - "journalvolume.page.edit": "Edit this item", + "journalvolume.page.edit": "Bu öğeyi düzenle", // "journalvolume.page.issuedate": "Issue Date", - // TODO New key - Add a translation - "journalvolume.page.issuedate": "Issue Date", + "journalvolume.page.issuedate": "Basım tarihi", // "journalvolume.page.titleprefix": "Journal Volume: ", - // TODO New key - Add a translation - "journalvolume.page.titleprefix": "Journal Volume: ", + "journalvolume.page.titleprefix": "Süreli yayın cilti: ", // "journalvolume.page.volume": "Volume", - // TODO New key - Add a translation - "journalvolume.page.volume": "Volume", + "journalvolume.page.volume": "Cilt", // "loading.bitstream": "Loading bitstream...", - // TODO New key - Add a translation - "loading.bitstream": "Loading bitstream...", + "loading.bitstream": "Veri akışı yükleniyor...", // "loading.bitstreams": "Loading bitstreams...", - // TODO New key - Add a translation - "loading.bitstreams": "Loading bitstreams...", + "loading.bitstreams": "Veri akışı yükleniyor...", // "loading.browse-by": "Loading items...", - // TODO New key - Add a translation - "loading.browse-by": "Loading items...", + "loading.browse-by": "Veri akışı yükleniyor...", // "loading.browse-by-page": "Loading page...", - // TODO New key - Add a translation - "loading.browse-by-page": "Loading page...", + "loading.browse-by-page": "Yükleme sayfası...", // "loading.collection": "Loading collection...", - // TODO New key - Add a translation - "loading.collection": "Loading collection...", + "loading.collection": "Koleksiyon yükleniyor...", // "loading.collections": "Loading collections...", - // TODO New key - Add a translation - "loading.collections": "Loading collections...", + "loading.collections": "Koleksiyon yükleniyor...", // "loading.content-source": "Loading content source...", - // TODO New key - Add a translation - "loading.content-source": "Loading content source...", + "loading.content-source": "İçerik kaynağı yükleniyor...", // "loading.community": "Loading community...", - // TODO New key - Add a translation - "loading.community": "Loading community...", + "loading.community": "Topluluk yükleniyor...", // "loading.default": "Loading...", - // TODO New key - Add a translation - "loading.default": "Loading...", + "loading.default": "Yükleniyor...", // "loading.item": "Loading item...", - // TODO New key - Add a translation - "loading.item": "Loading item...", + "loading.item": "Ögeler yükleniyor...", // "loading.items": "Loading items...", - // TODO New key - Add a translation - "loading.items": "Loading items...", + "loading.items": "Ögeler yükleniyor...", // "loading.mydspace-results": "Loading items...", - // TODO New key - Add a translation - "loading.mydspace-results": "Loading items...", + "loading.mydspace-results": "Ögeler yükleniyor...", // "loading.objects": "Loading...", - // TODO New key - Add a translation - "loading.objects": "Loading...", + "loading.objects": "Yükleniyor...", // "loading.recent-submissions": "Loading recent submissions...", - // TODO New key - Add a translation - "loading.recent-submissions": "Loading recent submissions...", + "loading.recent-submissions": "Son gönderiler yükleniyor...", // "loading.search-results": "Loading search results...", - // TODO New key - Add a translation - "loading.search-results": "Loading search results...", + "loading.search-results": "Arama sonuçları yükleniyor...", // "loading.sub-collections": "Loading sub-collections...", - // TODO New key - Add a translation - "loading.sub-collections": "Loading sub-collections...", + "loading.sub-collections": "Alt koleksiyonlar yükleniyor...", // "loading.sub-communities": "Loading sub-communities...", - // TODO New key - Add a translation - "loading.sub-communities": "Loading sub-communities...", + "loading.sub-communities": "Alt topluluklar yükleniyor...", // "loading.top-level-communities": "Loading top-level communities...", - // TODO New key - Add a translation - "loading.top-level-communities": "Loading top-level communities...", + "loading.top-level-communities": "Üst düzey topluluklar yükleniyor...", // "login.form.email": "Email address", - // TODO New key - Add a translation - "login.form.email": "Email address", + "login.form.email": "E-posta adresi", // "login.form.forgot-password": "Have you forgotten your password?", - // TODO New key - Add a translation - "login.form.forgot-password": "Have you forgotten your password?", + "login.form.forgot-password": "Parolanızı unuttunuz mu?", // "login.form.header": "Please log in to DSpace", - // TODO New key - Add a translation - "login.form.header": "Please log in to DSpace", + "login.form.header": "Lütfen DSpace'e giriş yapın", // "login.form.new-user": "New user? Click here to register.", - // TODO New key - Add a translation - "login.form.new-user": "New user? Click here to register.", + "login.form.new-user": "Yeni kullanıcı mısınız? Kayıt olmak için buraya tıklayın.", // "login.form.or-divider": "or", - // TODO New key - Add a translation - "login.form.or-divider": "or", + "login.form.or-divider": "ya da", // "login.form.password": "Password", - // TODO New key - Add a translation - "login.form.password": "Password", + "login.form.password": "Parola", // "login.form.shibboleth": "Log in with Shibboleth", - // TODO New key - Add a translation - "login.form.shibboleth": "Log in with Shibboleth", + "login.form.shibboleth": "Shibboleth ile giriş yapın", // "login.form.submit": "Log in", - // TODO New key - Add a translation - "login.form.submit": "Log in", + "login.form.submit": "Giriş yap", // "login.title": "Login", - // TODO New key - Add a translation - "login.title": "Login", + "login.title": "Giriş", // "login.breadcrumbs": "Login", - // TODO New key - Add a translation - "login.breadcrumbs": "Login", + "login.breadcrumbs": "Giriş", // "logout.form.header": "Log out from DSpace", - // TODO New key - Add a translation - "logout.form.header": "Log out from DSpace", + "logout.form.header": "DSpace'den çıkış yapın", // "logout.form.submit": "Log out", - // TODO New key - Add a translation - "logout.form.submit": "Log out", + "logout.form.submit": "Çıkış yap", // "logout.title": "Logout", - // TODO New key - Add a translation - "logout.title": "Logout", + "logout.title": "Çıkış yap", // "menu.header.admin": "Admin", - // TODO New key - Add a translation - "menu.header.admin": "Admin", + "menu.header.admin": "Yönetici", // "menu.header.image.logo": "Repository logo", - // TODO New key - Add a translation - "menu.header.image.logo": "Repository logo", + "menu.header.image.logo": "Depo logosu", // "menu.section.access_control": "Access Control", - // TODO New key - Add a translation - "menu.section.access_control": "Access Control", + "menu.section.access_control": "Giriş kontrolü", // "menu.section.access_control_authorizations": "Authorizations", - // TODO New key - Add a translation - "menu.section.access_control_authorizations": "Authorizations", + "menu.section.access_control_authorizations": "Yetkilendirmeler", // "menu.section.access_control_groups": "Groups", - // TODO New key - Add a translation - "menu.section.access_control_groups": "Groups", + "menu.section.access_control_groups": "Gruplar", // "menu.section.access_control_people": "People", - // TODO New key - Add a translation - "menu.section.access_control_people": "People", + "menu.section.access_control_people": "Kişiler", // "menu.section.admin_search": "Admin Search", - // TODO New key - Add a translation - "menu.section.admin_search": "Admin Search", + "menu.section.admin_search": "Yönetici araması", // "menu.section.browse_community": "This Community", - // TODO New key - Add a translation - "menu.section.browse_community": "This Community", + "menu.section.browse_community": "Bu Topluluk", // "menu.section.browse_community_by_author": "By Author", - // TODO New key - Add a translation - "menu.section.browse_community_by_author": "By Author", + "menu.section.browse_community_by_author": "Yazara göre", // "menu.section.browse_community_by_issue_date": "By Issue Date", - // TODO New key - Add a translation - "menu.section.browse_community_by_issue_date": "By Issue Date", + "menu.section.browse_community_by_issue_date": "Basım tarihine göre", // "menu.section.browse_community_by_title": "By Title", - // TODO New key - Add a translation - "menu.section.browse_community_by_title": "By Title", + "menu.section.browse_community_by_title": "Başlığa göre", // "menu.section.browse_global": "All of DSpace", - // TODO New key - Add a translation - "menu.section.browse_global": "All of DSpace", + "menu.section.browse_global": "Tümü", // "menu.section.browse_global_by_author": "By Author", - // TODO New key - Add a translation - "menu.section.browse_global_by_author": "By Author", + "menu.section.browse_global_by_author": "Yazara göre", // "menu.section.browse_global_by_dateissued": "By Issue Date", - // TODO New key - Add a translation - "menu.section.browse_global_by_dateissued": "By Issue Date", + "menu.section.browse_global_by_dateissued": "Basım tarihine göre", // "menu.section.browse_global_by_subject": "By Subject", - // TODO New key - Add a translation - "menu.section.browse_global_by_subject": "By Subject", + "menu.section.browse_global_by_subject": "Konuya göre", // "menu.section.browse_global_by_title": "By Title", - // TODO New key - Add a translation - "menu.section.browse_global_by_title": "By Title", + "menu.section.browse_global_by_title": "Başlığa göre", // "menu.section.browse_global_communities_and_collections": "Communities & Collections", - // TODO New key - Add a translation - "menu.section.browse_global_communities_and_collections": "Communities & Collections", + "menu.section.browse_global_communities_and_collections": "Topluluklar ve Koleksiyonlar", // "menu.section.control_panel": "Control Panel", - // TODO New key - Add a translation - "menu.section.control_panel": "Control Panel", + "menu.section.control_panel": "Kontrol Paneli", // "menu.section.curation_task": "Curation Task", - // TODO New key - Add a translation - "menu.section.curation_task": "Curation Task", + "menu.section.curation_task": "Düzenleme görevi", // "menu.section.edit": "Edit", - // TODO New key - Add a translation - "menu.section.edit": "Edit", + "menu.section.edit": "Düzenle", // "menu.section.edit_collection": "Collection", - // TODO New key - Add a translation - "menu.section.edit_collection": "Collection", + "menu.section.edit_collection": "Koleksiyon", // "menu.section.edit_community": "Community", - // TODO New key - Add a translation - "menu.section.edit_community": "Community", + "menu.section.edit_community": "Topluluk", // "menu.section.edit_item": "Item", - // TODO New key - Add a translation - "menu.section.edit_item": "Item", + "menu.section.edit_item": "Öge", // "menu.section.export": "Export", - // TODO New key - Add a translation - "menu.section.export": "Export", + "menu.section.export": "Dışa aktar", // "menu.section.export_collection": "Collection", - // TODO New key - Add a translation - "menu.section.export_collection": "Collection", + "menu.section.export_collection": "Koleksiyon", // "menu.section.export_community": "Community", - // TODO New key - Add a translation - "menu.section.export_community": "Community", + "menu.section.export_community": "Topluluk", // "menu.section.export_item": "Item", - // TODO New key - Add a translation - "menu.section.export_item": "Item", + "menu.section.export_item": "Öge", // "menu.section.export_metadata": "Metadata", - // TODO New key - Add a translation - "menu.section.export_metadata": "Metadata", + "menu.section.export_metadata": "Meta veri", // "menu.section.icon.access_control": "Access Control menu section", - // TODO New key - Add a translation - "menu.section.icon.access_control": "Access Control menu section", + "menu.section.icon.access_control": "Erişim Kontrolü menüsü bölümü", // "menu.section.icon.admin_search": "Admin search menu section", - // TODO New key - Add a translation - "menu.section.icon.admin_search": "Admin search menu section", + "menu.section.icon.admin_search": "Yönetici arama menüsü bölümü", // "menu.section.icon.control_panel": "Control Panel menu section", - // TODO New key - Add a translation - "menu.section.icon.control_panel": "Control Panel menu section", + "menu.section.icon.control_panel": "Kontrol Paneli menü bölümü", // "menu.section.icon.curation_task": "Curation Task menu section", - // TODO New key - Add a translation - "menu.section.icon.curation_task": "Curation Task menu section", + "menu.section.icon.curation_task": "Düzenleme Görevi menüsü bölümü", // "menu.section.icon.edit": "Edit menu section", - // TODO New key - Add a translation - "menu.section.icon.edit": "Edit menu section", + "menu.section.icon.edit": "Menü bölümünü düzenle", // "menu.section.icon.export": "Export menu section", - // TODO New key - Add a translation - "menu.section.icon.export": "Export menu section", + "menu.section.icon.export": "Menü bölümünü dışa aktar", // "menu.section.icon.find": "Find menu section", - // TODO New key - Add a translation - "menu.section.icon.find": "Find menu section", + "menu.section.icon.find": "Menü bölümünü bulun", // "menu.section.icon.import": "Import menu section", - // TODO New key - Add a translation - "menu.section.icon.import": "Import menu section", + "menu.section.icon.import": "Menü bölümünü içe aktar", // "menu.section.icon.new": "New menu section", - // TODO New key - Add a translation - "menu.section.icon.new": "New menu section", + "menu.section.icon.new": "Yeni menü bölümü", // "menu.section.icon.pin": "Pin sidebar", - // TODO New key - Add a translation - "menu.section.icon.pin": "Pin sidebar", + "menu.section.icon.pin": "Yan çubuğu sabitle", // "menu.section.icon.processes": "Processes menu section", - // TODO New key - Add a translation - "menu.section.icon.processes": "Processes menu section", + "menu.section.icon.processes": "İşlemler menüsü bölümü", // "menu.section.icon.registries": "Registries menu section", - // TODO New key - Add a translation - "menu.section.icon.registries": "Registries menu section", + "menu.section.icon.registries": "Kayıtlar menüsü bölümü", // "menu.section.icon.statistics_task": "Statistics Task menu section", - // TODO New key - Add a translation - "menu.section.icon.statistics_task": "Statistics Task menu section", + "menu.section.icon.statistics_task": "İstatistik Görev menüsü bölümü", // "menu.section.icon.unpin": "Unpin sidebar", - // TODO New key - Add a translation - "menu.section.icon.unpin": "Unpin sidebar", + "menu.section.icon.unpin": "Kenar çubuğunu kaldır", // "menu.section.import": "Import", - // TODO New key - Add a translation - "menu.section.import": "Import", + "menu.section.import": "İçe aktar", // "menu.section.import_batch": "Batch Import (ZIP)", - // TODO New key - Add a translation - "menu.section.import_batch": "Batch Import (ZIP)", + "menu.section.import_batch": "Toplu İçe Aktarma (ZIP)", // "menu.section.import_metadata": "Metadata", - // TODO New key - Add a translation - "menu.section.import_metadata": "Metadata", - - - + "menu.section.import_metadata": "Meta veri", + + + // "menu.section.new": "New", - // TODO New key - Add a translation - "menu.section.new": "New", + "menu.section.new": "Yeni", // "menu.section.new_collection": "Collection", - // TODO New key - Add a translation - "menu.section.new_collection": "Collection", + "menu.section.new_collection": "Koleksiyon", // "menu.section.new_community": "Community", - // TODO New key - Add a translation - "menu.section.new_community": "Community", + "menu.section.new_community": "Topluluk", // "menu.section.new_item": "Item", - // TODO New key - Add a translation - "menu.section.new_item": "Item", + "menu.section.new_item": "Öğe", // "menu.section.new_item_version": "Item Version", - // TODO New key - Add a translation - "menu.section.new_item_version": "Item Version", + "menu.section.new_item_version": "Öğe Sürümü", // "menu.section.new_process": "Process", - // TODO New key - Add a translation - "menu.section.new_process": "Process", + "menu.section.new_process": "Süreç", // "menu.section.pin": "Pin sidebar", - // TODO New key - Add a translation - "menu.section.pin": "Pin sidebar", + "menu.section.pin": "Kenar çubuğunu sabitle", // "menu.section.unpin": "Unpin sidebar", - // TODO New key - Add a translation - "menu.section.unpin": "Unpin sidebar", + "menu.section.unpin": "Kenar çubuğunun sabitlemesini kaldır", // "menu.section.processes": "Processes", - // TODO New key - Add a translation - "menu.section.processes": "Processes", + "menu.section.processes": "Süreçler", // "menu.section.registries": "Registries", - // TODO New key - Add a translation - "menu.section.registries": "Registries", + "menu.section.registries": "Kayıt", // "menu.section.registries_format": "Format", - // TODO New key - Add a translation "menu.section.registries_format": "Format", // "menu.section.registries_metadata": "Metadata", - // TODO New key - Add a translation "menu.section.registries_metadata": "Metadata", // "menu.section.statistics": "Statistics", - // TODO New key - Add a translation - "menu.section.statistics": "Statistics", + "menu.section.statistics": "İstatistik", // "menu.section.statistics_task": "Statistics Task", - // TODO New key - Add a translation - "menu.section.statistics_task": "Statistics Task", + "menu.section.statistics_task": "İstatistiksel Görev", // "menu.section.toggle.access_control": "Toggle Access Control section", - // TODO New key - Add a translation - "menu.section.toggle.access_control": "Toggle Access Control section", + "menu.section.toggle.access_control": "Erişim kontrolü bölümünü aç/kapat", // "menu.section.toggle.control_panel": "Toggle Control Panel section", - // TODO New key - Add a translation - "menu.section.toggle.control_panel": "Toggle Control Panel section", + "menu.section.toggle.control_panel": "Kontrol Paneli bölümünü aç/kapat", // "menu.section.toggle.curation_task": "Toggle Curation Task section", - // TODO New key - Add a translation - "menu.section.toggle.curation_task": "Toggle Curation Task section", + "menu.section.toggle.curation_task": "İyileştirme Görevi bölümünü aç/kapat", // "menu.section.toggle.edit": "Toggle Edit section", - // TODO New key - Add a translation - "menu.section.toggle.edit": "Toggle Edit section", + "menu.section.toggle.edit": "Düzenleme bölümünü aç/kapat", // "menu.section.toggle.export": "Toggle Export section", - // TODO New key - Add a translation - "menu.section.toggle.export": "Toggle Export section", + "menu.section.toggle.export": "Dışa Aktarma bölümünü aç/kapat", // "menu.section.toggle.find": "Toggle Find section", - // TODO New key - Add a translation - "menu.section.toggle.find": "Toggle Find section", + "menu.section.toggle.find": "Arama bölümünü aç/kapat", // "menu.section.toggle.import": "Toggle Import section", - // TODO New key - Add a translation - "menu.section.toggle.import": "Toggle Import section", + "menu.section.toggle.import": "İçe Aktarma bölümünü aç/kapat", // "menu.section.toggle.new": "Toggle New section", - // TODO New key - Add a translation - "menu.section.toggle.new": "Toggle New section", + "menu.section.toggle.new": "Yeni bölümü aç/kapat", // "menu.section.toggle.registries": "Toggle Registries section", - // TODO New key - Add a translation - "menu.section.toggle.registries": "Toggle Registries section", + "menu.section.toggle.registries": "Kayıtlar bölümünü aç/kapat", // "menu.section.toggle.statistics_task": "Toggle Statistics Task section", - // TODO New key - Add a translation - "menu.section.toggle.statistics_task": "Toggle Statistics Task section", + "menu.section.toggle.statistics_task": "İstatistik Görev bölümünü aç/kapat", // "menu.section.workflow": "Administer Workflow", - // TODO New key - Add a translation - "menu.section.workflow": "Administer Workflow", + "menu.section.workflow": "İş Akışını Yönet", // "mydspace.description": "", - // TODO New key - Add a translation "mydspace.description": "", // "mydspace.general.text-here": "here", - // TODO New key - Add a translation - "mydspace.general.text-here": "here", + "mydspace.general.text-here": "Burada", // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", - // TODO New key - Add a translation - "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", + "mydspace.messages.controller-help": "Öğeyi gönderene bir mesaj göndermek için bu seçeneği seçin.", // "mydspace.messages.description-placeholder": "Insert your message here...", - // TODO New key - Add a translation - "mydspace.messages.description-placeholder": "Insert your message here...", + "mydspace.messages.description-placeholder": "Mesajınızı buraya ekleyin...", // "mydspace.messages.hide-msg": "Hide message", - // TODO New key - Add a translation - "mydspace.messages.hide-msg": "Hide message", + "mydspace.messages.hide-msg": "Mesajı gizle", // "mydspace.messages.mark-as-read": "Mark as read", - // TODO New key - Add a translation - "mydspace.messages.mark-as-read": "Mark as read", + "mydspace.messages.mark-as-read": "Okundu olarak işaretle", // "mydspace.messages.mark-as-unread": "Mark as unread", - // TODO New key - Add a translation - "mydspace.messages.mark-as-unread": "Mark as unread", + "mydspace.messages.mark-as-unread": "Okunmamış olarak işaretle", // "mydspace.messages.no-content": "No content.", - // TODO New key - Add a translation - "mydspace.messages.no-content": "No content.", + "mydspace.messages.no-content": "İçerik yok.", // "mydspace.messages.no-messages": "No messages yet.", - // TODO New key - Add a translation - "mydspace.messages.no-messages": "No messages yet.", + "mydspace.messages.no-messages": "Henüz mesaj yok.", // "mydspace.messages.send-btn": "Send", - // TODO New key - Add a translation - "mydspace.messages.send-btn": "Send", + "mydspace.messages.send-btn": "Gönder", // "mydspace.messages.show-msg": "Show message", - // TODO New key - Add a translation - "mydspace.messages.show-msg": "Show message", + "mydspace.messages.show-msg": "Mesajı göster", // "mydspace.messages.subject-placeholder": "Subject...", - // TODO New key - Add a translation - "mydspace.messages.subject-placeholder": "Subject...", + "mydspace.messages.subject-placeholder": "Konu...", // "mydspace.messages.submitter-help": "Select this option to send a message to controller.", - // TODO New key - Add a translation - "mydspace.messages.submitter-help": "Select this option to send a message to controller.", + "mydspace.messages.submitter-help": "Kontrolöre mesaj göndermek için bu seçeneği seçin.", // "mydspace.messages.title": "Messages", - // TODO New key - Add a translation - "mydspace.messages.title": "Messages", + "mydspace.messages.title": "Mesajlar", // "mydspace.messages.to": "To", - // TODO New key - Add a translation - "mydspace.messages.to": "To", + "mydspace.messages.to": "-e", // "mydspace.new-submission": "New submission", - // TODO New key - Add a translation - "mydspace.new-submission": "New submission", + "mydspace.new-submission": "Yeni talep", // "mydspace.new-submission-external": "Import metadata from external source", - // TODO New key - Add a translation - "mydspace.new-submission-external": "Import metadata from external source", + "mydspace.new-submission-external": "Harici kaynaktan metadataları içe aktar", // "mydspace.new-submission-external-short": "Import metadata", - // TODO New key - Add a translation - "mydspace.new-submission-external-short": "Import metadata", + "mydspace.new-submission-external-short": "Metadataları içeri aktar.", // "mydspace.results.head": "Your submissions", - // TODO New key - Add a translation - "mydspace.results.head": "Your submissions", + "mydspace.results.head": "Gönderimleriniz", // "mydspace.results.no-abstract": "No Abstract", - // TODO New key - Add a translation - "mydspace.results.no-abstract": "No Abstract", + "mydspace.results.no-abstract": "Özet yok", // "mydspace.results.no-authors": "No Authors", - // TODO New key - Add a translation - "mydspace.results.no-authors": "No Authors", + "mydspace.results.no-authors": "Yazar yok.", // "mydspace.results.no-collections": "No Collections", - // TODO New key - Add a translation - "mydspace.results.no-collections": "No Collections", + "mydspace.results.no-collections": "Koleksiyon yok", // "mydspace.results.no-date": "No Date", - // TODO New key - Add a translation - "mydspace.results.no-date": "No Date", + "mydspace.results.no-date": "Tarih yok", // "mydspace.results.no-files": "No Files", - // TODO New key - Add a translation - "mydspace.results.no-files": "No Files", + "mydspace.results.no-files": "Dosya yok", // "mydspace.results.no-results": "There were no items to show", - // TODO New key - Add a translation - "mydspace.results.no-results": "There were no items to show", + "mydspace.results.no-results": "Gösterilecek öğe yok.", // "mydspace.results.no-title": "No title", - // TODO New key - Add a translation - "mydspace.results.no-title": "No title", + "mydspace.results.no-title": "Başlık yok", // "mydspace.results.no-uri": "No Uri", - // TODO New key - Add a translation - "mydspace.results.no-uri": "No Uri", + "mydspace.results.no-uri": "Uri yok", // "mydspace.show.workflow": "All tasks", - // TODO New key - Add a translation - "mydspace.show.workflow": "All tasks", + "mydspace.show.workflow": "Tüm görevler", // "mydspace.show.workspace": "Your Submissions", - // TODO New key - Add a translation - "mydspace.show.workspace": "Your Submissions", + "mydspace.show.workspace": "Gönderimleriniz", // "mydspace.status.archived": "Archived", - // TODO New key - Add a translation - "mydspace.status.archived": "Archived", + "mydspace.status.archived": "Arşivlendi", // "mydspace.status.validation": "Validation", - // TODO New key - Add a translation - "mydspace.status.validation": "Validation", + "mydspace.status.validation": "Doğrulama", // "mydspace.status.waiting-for-controller": "Waiting for controller", - // TODO New key - Add a translation - "mydspace.status.waiting-for-controller": "Waiting for controller", + "mydspace.status.waiting-for-controller": "Kontrolör bekleniyor", // "mydspace.status.workflow": "Workflow", - // TODO New key - Add a translation - "mydspace.status.workflow": "Workflow", + "mydspace.status.workflow": "İş akışı", // "mydspace.status.workspace": "Workspace", - // TODO New key - Add a translation - "mydspace.status.workspace": "Workspace", + "mydspace.status.workspace": "Çalışma alanı", // "mydspace.title": "MyDSpace", - // TODO New key - Add a translation "mydspace.title": "MyDSpace", // "mydspace.upload.upload-failed": "Error creating new workspace. Please verify the content uploaded before retry.", - // TODO New key - Add a translation - "mydspace.upload.upload-failed": "Error creating new workspace. Please verify the content uploaded before retry.", + "mydspace.upload.upload-failed": "Yeni çalışma alanı oluşturulurken hata oluştu. Lütfen yeniden denemeden önce yüklenen içeriği doğrulayın.", // "mydspace.upload.upload-failed-manyentries": "Unprocessable file. Detected too many entries but allowed only one for file.", - // TODO New key - Add a translation - "mydspace.upload.upload-failed-manyentries": "Unprocessable file. Detected too many entries but allowed only one for file.", + "mydspace.upload.upload-failed-manyentries": "İşlenemeyen dosya. Çok fazla giriş algılandı fakat dosya için yalnızca bir girişe izin verildi.", // "mydspace.upload.upload-failed-moreonefile": "Unprocessable request. Only one file is allowed.", - // TODO New key - Add a translation - "mydspace.upload.upload-failed-moreonefile": "Unprocessable request. Only one file is allowed.", + "mydspace.upload.upload-failed-moreonefile": "İşlenemeyen istek. Yalnızca bir dosyaya izin verilir.", // "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", - // TODO New key - Add a translation - "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", + "mydspace.upload.upload-multiple-successful": "{{qty}} yeni çalışma alanı öğeleri oluşturuldu.", // "mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.", - // TODO New key - Add a translation - "mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.", + "mydspace.upload.upload-successful": "Yeni çalışma alanı öğesi oluşturuldu. Düzenlemek için {{here}} tıklayın.", // "mydspace.view-btn": "View", - // TODO New key - Add a translation - "mydspace.view-btn": "View", + "mydspace.view-btn": "Görünüm", // "nav.browse.header": "All of DSpace", - // TODO New key - Add a translation - "nav.browse.header": "All of DSpace", + "nav.browse.header": "DSpace'in tümü", // "nav.community-browse.header": "By Community", - // TODO New key - Add a translation - "nav.community-browse.header": "By Community", + "nav.community-browse.header": "Topluluk tarafından", // "nav.language": "Language switch", - // TODO New key - Add a translation - "nav.language": "Language switch", + "nav.language": "Dil değiştirme", // "nav.login": "Log In", - // TODO New key - Add a translation - "nav.login": "Log In", + "nav.login": "Giriş yap", // "nav.logout": "Log Out", - // TODO New key - Add a translation - "nav.logout": "Log Out", + "nav.logout": "Çıkış yap", // "nav.mydspace": "MyDSpace", - // TODO New key - Add a translation - "nav.mydspace": "MyDSpace", + "nav.mydspace": "BenimDSpace'im", // "nav.profile": "Profile", - // TODO New key - Add a translation - "nav.profile": "Profile", + "nav.profile": "Profil", // "nav.search": "Search", - // TODO New key - Add a translation - "nav.search": "Search", + "nav.search": "Arama", // "nav.statistics.header": "Statistics", - // TODO New key - Add a translation - "nav.statistics.header": "Statistics", + "nav.statistics.header": "İstatistik", // "nav.stop-impersonating": "Stop impersonating EPerson", - // TODO New key - Add a translation - "nav.stop-impersonating": "Stop impersonating EPerson", + "nav.stop-impersonating": "EPerson'ı taklit etmeyi bırakın", // "orgunit.listelement.badge": "Organizational Unit", - // TODO New key - Add a translation - "orgunit.listelement.badge": "Organizational Unit", + "orgunit.listelement.badge": "Organizasyon Birimi", // "orgunit.page.city": "City", - // TODO New key - Add a translation - "orgunit.page.city": "City", + "orgunit.page.city": "Şehir", // "orgunit.page.country": "Country", - // TODO New key - Add a translation - "orgunit.page.country": "Country", + "orgunit.page.country": "Ülke", // "orgunit.page.dateestablished": "Date established", - // TODO New key - Add a translation - "orgunit.page.dateestablished": "Date established", + "orgunit.page.dateestablished": "Kuruluş tarihi", // "orgunit.page.description": "Description", - // TODO New key - Add a translation - "orgunit.page.description": "Description", + "orgunit.page.description": "Açıklama", // "orgunit.page.edit": "Edit this item", - // TODO New key - Add a translation - "orgunit.page.edit": "Edit this item", + "orgunit.page.edit": "Bu öğeyi düzenle", // "orgunit.page.id": "ID", - // TODO New key - Add a translation - "orgunit.page.id": "ID", + "orgunit.page.id": "Kimlik", // "orgunit.page.titleprefix": "Organizational Unit: ", - // TODO New key - Add a translation - "orgunit.page.titleprefix": "Organizational Unit: ", + "orgunit.page.titleprefix": "Organizasyon Birimi: ", // "pagination.results-per-page": "Results Per Page", - // TODO New key - Add a translation - "pagination.results-per-page": "Results Per Page", + "pagination.results-per-page": "Sayfa başına sonuç", // "pagination.showing.detail": "{{ range }} of {{ total }}", - // TODO New key - Add a translation - "pagination.showing.detail": "{{ range }} of {{ total }}", + "pagination.showing.detail": "{{ range }} / {{ total }}", // "pagination.showing.label": "Now showing ", - // TODO New key - Add a translation - "pagination.showing.label": "Now showing ", + "pagination.showing.label": "Şimdi gösteriliyor ", // "pagination.sort-direction": "Sort Options", - // TODO New key - Add a translation - "pagination.sort-direction": "Sort Options", + "pagination.sort-direction": "Sıralama Seçenekleri", // "person.listelement.badge": "Person", - // TODO New key - Add a translation - "person.listelement.badge": "Person", + "person.listelement.badge": "Kişi", // "person.listelement.no-title": "No name found", - // TODO New key - Add a translation - "person.listelement.no-title": "No name found", + "person.listelement.no-title": "İsim bulunamadı", // "person.page.birthdate": "Birth Date", - // TODO New key - Add a translation - "person.page.birthdate": "Birth Date", + "person.page.birthdate": "Doğum Tarihi", // "person.page.edit": "Edit this item", - // TODO New key - Add a translation - "person.page.edit": "Edit this item", + "person.page.edit": "Bu öğeyi düzenle", // "person.page.email": "Email Address", - // TODO New key - Add a translation - "person.page.email": "Email Address", + "person.page.email": "E-posta Adresi", // "person.page.firstname": "First Name", - // TODO New key - Add a translation - "person.page.firstname": "First Name", + "person.page.firstname": "Ad", // "person.page.jobtitle": "Job Title", - // TODO New key - Add a translation - "person.page.jobtitle": "Job Title", + "person.page.jobtitle": "İş Adı", // "person.page.lastname": "Last Name", - // TODO New key - Add a translation - "person.page.lastname": "Last Name", + "person.page.lastname": "Soyad", // "person.page.link.full": "Show all metadata", - // TODO New key - Add a translation - "person.page.link.full": "Show all metadata", + "person.page.link.full": "Tüm metadata'yı göster", // "person.page.orcid": "ORCID", - // TODO New key - Add a translation "person.page.orcid": "ORCID", // "person.page.staffid": "Staff ID", - // TODO New key - Add a translation - "person.page.staffid": "Staff ID", + "person.page.staffid": "Personel Kimliği", // "person.page.titleprefix": "Person: ", - // TODO New key - Add a translation - "person.page.titleprefix": "Person: ", + "person.page.titleprefix": "Kişi: ", // "person.search.results.head": "Person Search Results", - // TODO New key - Add a translation - "person.search.results.head": "Person Search Results", + "person.search.results.head": "Kişi Arama Sonuçları", // "person.search.title": "DSpace Angular :: Person Search", - // TODO New key - Add a translation - "person.search.title": "DSpace Angular :: Person Search", + "person.search.title": "DSpace Angular :: Kişi Arama", // "process.new.select-parameters": "Parameters", - // TODO New key - Add a translation - "process.new.select-parameters": "Parameters", + "process.new.select-parameters": "Parametreler", // "process.new.cancel": "Cancel", - // TODO New key - Add a translation - "process.new.cancel": "Cancel", + "process.new.cancel": "İptal etmek", // "process.new.submit": "Submit", - // TODO New key - Add a translation - "process.new.submit": "Submit", + "process.new.submit": "Göndermek", // "process.new.select-script": "Script", - // TODO New key - Add a translation - "process.new.select-script": "Script", + "process.new.select-script": "Betik", // "process.new.select-script.placeholder": "Choose a script...", - // TODO New key - Add a translation - "process.new.select-script.placeholder": "Choose a script...", + "process.new.select-script.placeholder": "Betik Seçiniz...", // "process.new.select-script.required": "Script is required", - // TODO New key - Add a translation - "process.new.select-script.required": "Script is required", + "process.new.select-script.required": "Betik gerekli", // "process.new.parameter.file.upload-button": "Select file...", - // TODO New key - Add a translation - "process.new.parameter.file.upload-button": "Select file...", + "process.new.parameter.file.upload-button": "Dosya seç...", // "process.new.parameter.file.required": "Please select a file", - // TODO New key - Add a translation - "process.new.parameter.file.required": "Please select a file", + "process.new.parameter.file.required": "Lütfen dosya seçiniz.", // "process.new.parameter.string.required": "Parameter value is required", - // TODO New key - Add a translation - "process.new.parameter.string.required": "Parameter value is required", + "process.new.parameter.string.required": "Parametre değeri gerekli", // "process.new.parameter.type.value": "value", - // TODO New key - Add a translation - "process.new.parameter.type.value": "value", + "process.new.parameter.type.value": "Değer", // "process.new.parameter.type.file": "file", - // TODO New key - Add a translation - "process.new.parameter.type.file": "file", + "process.new.parameter.type.file": "dosya", // "process.new.parameter.required.missing": "The following parameters are required but still missing:", - // TODO New key - Add a translation - "process.new.parameter.required.missing": "The following parameters are required but still missing:", + "process.new.parameter.required.missing": "Aşağıdaki parametreler gerekli ancak yine de eksik:", // "process.new.notification.success.title": "Success", - // TODO New key - Add a translation - "process.new.notification.success.title": "Success", + "process.new.notification.success.title": "Başarı", // "process.new.notification.success.content": "The process was successfully created", - // TODO New key - Add a translation - "process.new.notification.success.content": "The process was successfully created", + "process.new.notification.success.content": "Süreç başarıyla oluşturuldu", // "process.new.notification.error.title": "Error", - // TODO New key - Add a translation - "process.new.notification.error.title": "Error", + "process.new.notification.error.title": "Hata", // "process.new.notification.error.content": "An error occurred while creating this process", - // TODO New key - Add a translation - "process.new.notification.error.content": "An error occurred while creating this process", + "process.new.notification.error.content": "Bu süreç oluşturulurken bir hata oluştu", // "process.new.header": "Create a new process", - // TODO New key - Add a translation - "process.new.header": "Create a new process", + "process.new.header": "Yeni bir süreç oluştur", // "process.new.title": "Create a new process", - // TODO New key - Add a translation - "process.new.title": "Create a new process", + "process.new.title": "Yeni bir süreç oluştur", // "process.new.breadcrumbs": "Create a new process", - // TODO New key - Add a translation - "process.new.breadcrumbs": "Create a new process", + "process.new.breadcrumbs": "Yeni bir süreç oluştur", // "process.detail.arguments" : "Arguments", - // TODO New key - Add a translation - "process.detail.arguments" : "Arguments", + "process.detail.arguments" : "Argümanlar", // "process.detail.arguments.empty" : "This process doesn't contain any arguments", - // TODO New key - Add a translation - "process.detail.arguments.empty" : "This process doesn't contain any arguments", + "process.detail.arguments.empty" : "Bu süreç herhangi bir argüman içermiyor", // "process.detail.back" : "Back", - // TODO New key - Add a translation - "process.detail.back" : "Back", + "process.detail.back" : "Geri", // "process.detail.output" : "Process Output", - // TODO New key - Add a translation - "process.detail.output" : "Process Output", + "process.detail.output" : "Süreç Çıktısı", // "process.detail.logs.button": "Retrieve process output", - // TODO New key - Add a translation - "process.detail.logs.button": "Retrieve process output", + "process.detail.logs.button": "Süreç çıktısını geri al", // "process.detail.logs.loading": "Retrieving", - // TODO New key - Add a translation - "process.detail.logs.loading": "Retrieving", + "process.detail.logs.loading": "Geri almak", // "process.detail.logs.none": "This process has no output", - // TODO New key - Add a translation - "process.detail.logs.none": "This process has no output", + "process.detail.logs.none": "Bu sürecin çıktısı yok", // "process.detail.output-files" : "Output Files", - // TODO New key - Add a translation - "process.detail.output-files" : "Output Files", + "process.detail.output-files" : "Çıktı dosyaları", // "process.detail.output-files.empty" : "This process doesn't contain any output files", - // TODO New key - Add a translation - "process.detail.output-files.empty" : "This process doesn't contain any output files", + "process.detail.output-files.empty" : "Bu süreç herhangi bir çıktı dosyası içermiyor", // "process.detail.script" : "Script", - // TODO New key - Add a translation - "process.detail.script" : "Script", + "process.detail.script" : "Betik", // "process.detail.title" : "Process: {{ id }} - {{ name }}", - // TODO New key - Add a translation - "process.detail.title" : "Process: {{ id }} - {{ name }}", + "process.detail.title" : "Süreç: {{ id }} - {{ name }}", // "process.detail.start-time" : "Start time", - // TODO New key - Add a translation - "process.detail.start-time" : "Start time", + "process.detail.start-time" : "Başlangıç saati", // "process.detail.end-time" : "Finish time", - // TODO New key - Add a translation - "process.detail.end-time" : "Finish time", + "process.detail.end-time" : "Bitiş zamanı", // "process.detail.status" : "Status", - // TODO New key - Add a translation - "process.detail.status" : "Status", + "process.detail.status" : "Durum", // "process.detail.create" : "Create similar process", - // TODO New key - Add a translation - "process.detail.create" : "Create similar process", + "process.detail.create" : "Benzer süreç oluştur", // "process.overview.table.finish" : "Finish time", - // TODO New key - Add a translation - "process.overview.table.finish" : "Finish time", + "process.overview.table.finish" : "Bitiş zamanı", // "process.overview.table.id" : "Process ID", - // TODO New key - Add a translation - "process.overview.table.id" : "Process ID", + "process.overview.table.id" : "Süreç kimliği", // "process.overview.table.name" : "Name", - // TODO New key - Add a translation - "process.overview.table.name" : "Name", + "process.overview.table.name" : "Ad", // "process.overview.table.start" : "Start time", - // TODO New key - Add a translation - "process.overview.table.start" : "Start time", + "process.overview.table.start" : "Başlangıç zamanı", // "process.overview.table.status" : "Status", - // TODO New key - Add a translation - "process.overview.table.status" : "Status", + "process.overview.table.status" : "Durum", // "process.overview.table.user" : "User", - // TODO New key - Add a translation - "process.overview.table.user" : "User", + "process.overview.table.user" : "Kullanıcı", // "process.overview.title": "Processes Overview", - // TODO New key - Add a translation - "process.overview.title": "Processes Overview", + "process.overview.title": "Süreçlere Genel Bakış", // "process.overview.breadcrumbs": "Processes Overview", - // TODO New key - Add a translation - "process.overview.breadcrumbs": "Processes Overview", + "process.overview.breadcrumbs": "Süreçlere Genel Bakış", // "process.overview.new": "New", - // TODO New key - Add a translation - "process.overview.new": "New", + "process.overview.new": "Yeni", // "profile.breadcrumbs": "Update Profile", - // TODO New key - Add a translation - "profile.breadcrumbs": "Update Profile", + "profile.breadcrumbs": "Profili Güncelle", // "profile.card.identify": "Identify", - // TODO New key - Add a translation - "profile.card.identify": "Identify", + "profile.card.identify": "Kimlik", // "profile.card.security": "Security", - // TODO New key - Add a translation - "profile.card.security": "Security", + "profile.card.security": "Güvenlik", // "profile.form.submit": "Update Profile", - // TODO New key - Add a translation - "profile.form.submit": "Update Profile", + "profile.form.submit": "Profili Güncelle", // "profile.groups.head": "Authorization groups you belong to", - // TODO New key - Add a translation - "profile.groups.head": "Authorization groups you belong to", + "profile.groups.head": "Ait olduğunuz yetkilendirme grupları", // "profile.head": "Update Profile", - // TODO New key - Add a translation - "profile.head": "Update Profile", + "profile.head": "Profili Güncelle", // "profile.metadata.form.error.firstname.required": "First Name is required", - // TODO New key - Add a translation - "profile.metadata.form.error.firstname.required": "First Name is required", + "profile.metadata.form.error.firstname.required": "Ad gereklidir", // "profile.metadata.form.error.lastname.required": "Last Name is required", - // TODO New key - Add a translation - "profile.metadata.form.error.lastname.required": "Last Name is required", + "profile.metadata.form.error.lastname.required": "Soyadı gerekli", // "profile.metadata.form.label.email": "Email Address", - // TODO New key - Add a translation - "profile.metadata.form.label.email": "Email Address", + "profile.metadata.form.label.email": "E-posta Adresi", // "profile.metadata.form.label.firstname": "First Name", - // TODO New key - Add a translation - "profile.metadata.form.label.firstname": "First Name", + "profile.metadata.form.label.firstname": "Ad", // "profile.metadata.form.label.language": "Language", - // TODO New key - Add a translation - "profile.metadata.form.label.language": "Language", + "profile.metadata.form.label.language": "Dil", // "profile.metadata.form.label.lastname": "Last Name", - // TODO New key - Add a translation - "profile.metadata.form.label.lastname": "Last Name", + "profile.metadata.form.label.lastname": "Soyadı", // "profile.metadata.form.label.phone": "Contact Telephone", - // TODO New key - Add a translation - "profile.metadata.form.label.phone": "Contact Telephone", + "profile.metadata.form.label.phone": "İletişim telefonu", // "profile.metadata.form.notifications.success.content": "Your changes to the profile were saved.", - // TODO New key - Add a translation - "profile.metadata.form.notifications.success.content": "Your changes to the profile were saved.", + "profile.metadata.form.notifications.success.content": "Profilde yaptığınız değişiklikler kaydedildi.", // "profile.metadata.form.notifications.success.title": "Profile saved", - // TODO New key - Add a translation - "profile.metadata.form.notifications.success.title": "Profile saved", + "profile.metadata.form.notifications.success.title": "Profil kaydedildi", // "profile.notifications.warning.no-changes.content": "No changes were made to the Profile.", - // TODO New key - Add a translation - "profile.notifications.warning.no-changes.content": "No changes were made to the Profile.", + "profile.notifications.warning.no-changes.content": "Profilde herhangi bir değişiklik yapılmadı.", // "profile.notifications.warning.no-changes.title": "No changes", - // TODO New key - Add a translation - "profile.notifications.warning.no-changes.title": "No changes", + "profile.notifications.warning.no-changes.title": "Değişiklik yok", // "profile.security.form.error.matching-passwords": "The passwords do not match.", - // TODO New key - Add a translation - "profile.security.form.error.matching-passwords": "The passwords do not match.", + "profile.security.form.error.matching-passwords": "Parolalar eşleşmiyor.", // "profile.security.form.error.password-length": "The password should be at least 6 characters long.", - // TODO New key - Add a translation - "profile.security.form.error.password-length": "The password should be at least 6 characters long.", + "profile.security.form.error.password-length": "Parola en az 6 karakter uzunluğunda olmalıdır.", // "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. It should be at least six characters long.", - // TODO New key - Add a translation - "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. It should be at least six characters long.", + "profile.security.form.info": "İsteğe bağlı olarak aşağıdaki kutucuğa yeni bir parola girebilir ve ikinci kutucuğa tekrar yazarak onaylayabilirsiniz. En az altı karakter uzunluğunda olmalıdır.", // "profile.security.form.label.password": "Password", - // TODO New key - Add a translation - "profile.security.form.label.password": "Password", + "profile.security.form.label.password": "Parola", // "profile.security.form.label.passwordrepeat": "Retype to confirm", - // TODO New key - Add a translation - "profile.security.form.label.passwordrepeat": "Retype to confirm", + "profile.security.form.label.passwordrepeat": "Doğrulamak için yeniden yazınız", // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", - // TODO New key - Add a translation - "profile.security.form.notifications.success.content": "Your changes to the password were saved.", + "profile.security.form.notifications.success.content": "Parola değişiklikleriniz kaydedildi.", // "profile.security.form.notifications.success.title": "Password saved", - // TODO New key - Add a translation - "profile.security.form.notifications.success.title": "Password saved", + "profile.security.form.notifications.success.title": "Parola kaydedildi", // "profile.security.form.notifications.error.title": "Error changing passwords", - // TODO New key - Add a translation - "profile.security.form.notifications.error.title": "Error changing passwords", + "profile.security.form.notifications.error.title": "Parolalar değiştirilirken hata oluştu", // "profile.security.form.notifications.error.not-long-enough": "The password has to be at least 6 characters long.", - // TODO New key - Add a translation - "profile.security.form.notifications.error.not-long-enough": "The password has to be at least 6 characters long.", + "profile.security.form.notifications.error.not-long-enough": "Parola en az 6 karakter uzunluğunda olmalıdır.", // "profile.security.form.notifications.error.not-same": "The provided passwords are not the same.", - // TODO New key - Add a translation - "profile.security.form.notifications.error.not-same": "The provided passwords are not the same.", + "profile.security.form.notifications.error.not-same": "Sağlanan parolalar aynı değil.", // "profile.title": "Update Profile", - // TODO New key - Add a translation - "profile.title": "Update Profile", + "profile.title": "Profili Güncelle", // "project.listelement.badge": "Research Project", - // TODO New key - Add a translation - "project.listelement.badge": "Research Project", + "project.listelement.badge": "Araştırma projesi", // "project.page.contributor": "Contributors", - // TODO New key - Add a translation - "project.page.contributor": "Contributors", + "project.page.contributor": "Katkıda Bulunanlar", // "project.page.description": "Description", - // TODO New key - Add a translation - "project.page.description": "Description", + "project.page.description": "Açıklama", // "project.page.edit": "Edit this item", - // TODO New key - Add a translation - "project.page.edit": "Edit this item", + "project.page.edit": "Bu öğeyi düzenle", // "project.page.expectedcompletion": "Expected Completion", - // TODO New key - Add a translation - "project.page.expectedcompletion": "Expected Completion", + "project.page.expectedcompletion": "Beklenen Tamamlanma", // "project.page.funder": "Funders", - // TODO New key - Add a translation - "project.page.funder": "Funders", + "project.page.funder": "Fon Sağlayıcılar", // "project.page.id": "ID", - // TODO New key - Add a translation - "project.page.id": "ID", + "project.page.id": "Kimlik", // "project.page.keyword": "Keywords", - // TODO New key - Add a translation - "project.page.keyword": "Keywords", + "project.page.keyword": "Anahtar kelimeler", // "project.page.status": "Status", - // TODO New key - Add a translation - "project.page.status": "Status", + "project.page.status": "Durum", // "project.page.titleprefix": "Research Project: ", - // TODO New key - Add a translation - "project.page.titleprefix": "Research Project: ", + "project.page.titleprefix": "Araştırma Projesi: ", // "project.search.results.head": "Project Search Results", - // TODO New key - Add a translation - "project.search.results.head": "Project Search Results", + "project.search.results.head": "Proje Arama Sonuçları", // "publication.listelement.badge": "Publication", - // TODO New key - Add a translation - "publication.listelement.badge": "Publication", + "publication.listelement.badge": "Yayın", // "publication.page.description": "Description", - // TODO New key - Add a translation - "publication.page.description": "Description", + "publication.page.description": "Açıklama", // "publication.page.edit": "Edit this item", - // TODO New key - Add a translation - "publication.page.edit": "Edit this item", + "publication.page.edit": "Bu öğeyi düzenle", // "publication.page.journal-issn": "Journal ISSN", - // TODO New key - Add a translation - "publication.page.journal-issn": "Journal ISSN", + "publication.page.journal-issn": "Dergi ISSN", // "publication.page.journal-title": "Journal Title", - // TODO New key - Add a translation - "publication.page.journal-title": "Journal Title", + "publication.page.journal-title": "Dergi Başlığı", // "publication.page.publisher": "Publisher", - // TODO New key - Add a translation - "publication.page.publisher": "Publisher", + "publication.page.publisher": "Yayımcı", // "publication.page.titleprefix": "Publication: ", - // TODO New key - Add a translation - "publication.page.titleprefix": "Publication: ", + "publication.page.titleprefix": "Yayın: ", // "publication.page.volume-title": "Volume Title", - // TODO New key - Add a translation - "publication.page.volume-title": "Volume Title", + "publication.page.volume-title": "Cilt Başlığı", // "publication.search.results.head": "Publication Search Results", - // TODO New key - Add a translation - "publication.search.results.head": "Publication Search Results", + "publication.search.results.head": "Yayın Arama Sonuçları", // "publication.search.title": "DSpace Angular :: Publication Search", - // TODO New key - Add a translation - "publication.search.title": "DSpace Angular :: Publication Search", + "publication.search.title": "DSpace Angular :: Yayın Arama", // "register-email.title": "New user registration", - // TODO New key - Add a translation - "register-email.title": "New user registration", + "register-email.title": "Yeni kullanıcı kaydı", // "register-page.create-profile.header": "Create Profile", - // TODO New key - Add a translation - "register-page.create-profile.header": "Create Profile", + "register-page.create-profile.header": "Profil oluştur", // "register-page.create-profile.identification.header": "Identify", - // TODO New key - Add a translation - "register-page.create-profile.identification.header": "Identify", + "register-page.create-profile.identification.header": "Tanımlamak", // "register-page.create-profile.identification.email": "Email Address", - // TODO New key - Add a translation - "register-page.create-profile.identification.email": "Email Address", + "register-page.create-profile.identification.email": "E-posta Adresi", // "register-page.create-profile.identification.first-name": "First Name *", - // TODO New key - Add a translation - "register-page.create-profile.identification.first-name": "First Name *", + "register-page.create-profile.identification.first-name": "Ad *", // "register-page.create-profile.identification.first-name.error": "Please fill in a First Name", - // TODO New key - Add a translation - "register-page.create-profile.identification.first-name.error": "Please fill in a First Name", + "register-page.create-profile.identification.first-name.error": "Lütfen bir ad girin", // "register-page.create-profile.identification.last-name": "Last Name *", - // TODO New key - Add a translation - "register-page.create-profile.identification.last-name": "Last Name *", + "register-page.create-profile.identification.last-name": "Soyadı *", // "register-page.create-profile.identification.last-name.error": "Please fill in a Last Name", - // TODO New key - Add a translation - "register-page.create-profile.identification.last-name.error": "Please fill in a Last Name", + "register-page.create-profile.identification.last-name.error": "Lütfen bir soyadı girin", // "register-page.create-profile.identification.contact": "Contact Telephone", - // TODO New key - Add a translation - "register-page.create-profile.identification.contact": "Contact Telephone", + "register-page.create-profile.identification.contact": "İletişim telefonu", // "register-page.create-profile.identification.language": "Language", - // TODO New key - Add a translation - "register-page.create-profile.identification.language": "Language", + "register-page.create-profile.identification.language": "Dil", // "register-page.create-profile.security.header": "Security", - // TODO New key - Add a translation - "register-page.create-profile.security.header": "Security", + "register-page.create-profile.security.header": "Güvenlik", // "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. It should be at least six characters long.", - // TODO New key - Add a translation - "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. It should be at least six characters long.", + "register-page.create-profile.security.info": "Lütfen aşağıdaki kutuya bir parola girin ve ikinci kutuya tekrar yazarak onaylayın. En az altı karakter uzunluğunda olmalıdır.", // "register-page.create-profile.security.label.password": "Password *", - // TODO New key - Add a translation - "register-page.create-profile.security.label.password": "Password *", + "register-page.create-profile.security.label.password": "Parola *", // "register-page.create-profile.security.label.passwordrepeat": "Retype to confirm *", - // TODO New key - Add a translation - "register-page.create-profile.security.label.passwordrepeat": "Retype to confirm *", + "register-page.create-profile.security.label.passwordrepeat": "Doğrulamak için yeniden yazınız *", // "register-page.create-profile.security.error.empty-password": "Please enter a password in the box below.", - // TODO New key - Add a translation - "register-page.create-profile.security.error.empty-password": "Please enter a password in the box below.", + "register-page.create-profile.security.error.empty-password": "Lütfen aşağıdaki kutuya bir parola girin.", // "register-page.create-profile.security.error.matching-passwords": "The passwords do not match.", - // TODO New key - Add a translation - "register-page.create-profile.security.error.matching-passwords": "The passwords do not match.", + "register-page.create-profile.security.error.matching-passwords": "Parolalar eşleşmiyor.", // "register-page.create-profile.security.error.password-length": "The password should be at least 6 characters long.", - // TODO New key - Add a translation - "register-page.create-profile.security.error.password-length": "The password should be at least 6 characters long.", + "register-page.create-profile.security.error.password-length": "Parola en az 6 karakter uzunluğunda olmalıdır.", // "register-page.create-profile.submit": "Complete Registration", - // TODO New key - Add a translation - "register-page.create-profile.submit": "Complete Registration", + "register-page.create-profile.submit": "Kaydı Tamamla", // "register-page.create-profile.submit.error.content": "Something went wrong while registering a new user.", - // TODO New key - Add a translation - "register-page.create-profile.submit.error.content": "Something went wrong while registering a new user.", + "register-page.create-profile.submit.error.content": "Yeni bir kullanıcı kaydedilirken bir şeyler ters gitti.", // "register-page.create-profile.submit.error.head": "Registration failed", - // TODO New key - Add a translation - "register-page.create-profile.submit.error.head": "Registration failed", + "register-page.create-profile.submit.error.head": "Kayıt başarısız", // "register-page.create-profile.submit.success.content": "The registration was successful. You have been logged in as the created user.", - // TODO New key - Add a translation - "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": "Kayıt başarıyla tamamlandı. Oluşturulan kullanıcı olarak giriş yaptınız", // "register-page.create-profile.submit.success.head": "Registration completed", - // TODO New key - Add a translation - "register-page.create-profile.submit.success.head": "Registration completed", + "register-page.create-profile.submit.success.head": "Kayıt tamamlandı", // "register-page.registration.header": "New user registration", - // TODO New key - Add a translation - "register-page.registration.header": "New user registration", + "register-page.registration.header": "Yeni kullanıcı kaydı", // "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", - // TODO New key - Add a translation - "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + "register-page.registration.info": "E-mail güncellemeleri için koleksiyonlara abone olup hesap açın. Ve DSapce’e yeni öğeler kaydetin.", // "register-page.registration.email": "Email Address *", - // TODO New key - Add a translation - "register-page.registration.email": "Email Address *", + "register-page.registration.email": "E-posta Adresi *", // "register-page.registration.email.error.required": "Please fill in an email address", - // TODO New key - Add a translation - "register-page.registration.email.error.required": "Please fill in an email address", + "register-page.registration.email.error.required": "Lütfen bir e-posta adresi girin", // "register-page.registration.email.error.pattern": "Please fill in a valid email address", - // TODO New key - Add a translation - "register-page.registration.email.error.pattern": "Please fill in a valid email address", + "register-page.registration.email.error.pattern": "Lütfen geçerli bir email adresi girin", // "register-page.registration.email.hint": "This address will be verified and used as your login name.", - // TODO New key - Add a translation - "register-page.registration.email.hint": "This address will be verified and used as your login name.", + "register-page.registration.email.hint": "Bu adres doğrulanacak ve oturum açma adınız olarak kullanılacaktır.", // "register-page.registration.submit": "Register", - // TODO New key - Add a translation - "register-page.registration.submit": "Register", + "register-page.registration.submit": "Kayıt olmak", // "register-page.registration.success.head": "Verification email sent", - // TODO New key - Add a translation - "register-page.registration.success.head": "Verification email sent", + "register-page.registration.success.head": "Doğrulama e-postası gönderildi", // "register-page.registration.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", - // TODO New key - Add a translation - "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 }} adresine özel bir URL ve daha fazla talimat içeren bir e-posta gönderildi.", // "register-page.registration.error.head": "Error when trying to register email", - // TODO New key - Add a translation - "register-page.registration.error.head": "Error when trying to register email", + "register-page.registration.error.head": "E-posta kaydetmeye çalışırken hata", // "register-page.registration.error.content": "An error occured when registering the following email address: {{ email }}", - // TODO New key - Add a translation - "register-page.registration.error.content": "An error occured when registering the following email address: {{ email }}", + "register-page.registration.error.content": "Aşağıdaki e-posta adresi kaydedilirken bir hata oluştu: {{ email }}", // "relationships.add.error.relationship-type.content": "No suitable match could be found for relationship type {{ type }} between the two items", - // TODO New key - Add a translation - "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": "İki öğe arasında {{ type }} ilişki türü için uygun bir eşleşme bulunamadı", // "relationships.add.error.server.content": "The server returned an error", - // TODO New key - Add a translation - "relationships.add.error.server.content": "The server returned an error", + "relationships.add.error.server.content": "Sunucu bir hata verdi", // "relationships.add.error.title": "Unable to add relationship", - // TODO New key - Add a translation - "relationships.add.error.title": "Unable to add relationship", + "relationships.add.error.title": "İlişki eklenemedi", // "relationships.isAuthorOf": "Authors", - // TODO New key - Add a translation - "relationships.isAuthorOf": "Authors", + "relationships.isAuthorOf": "Yazarlar", // "relationships.isAuthorOf.Person": "Authors (persons)", - // TODO New key - Add a translation - "relationships.isAuthorOf.Person": "Authors (persons)", + "relationships.isAuthorOf.Person": "Yazarlar (kişiler)", // "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", - // TODO New key - Add a translation - "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", + "relationships.isAuthorOf.OrgUnit": "Yazarlar (organizasyon birimleri)", // "relationships.isIssueOf": "Journal Issues", - // TODO New key - Add a translation - "relationships.isIssueOf": "Journal Issues", + "relationships.isIssueOf": "Dergi Sayıları", // "relationships.isJournalIssueOf": "Journal Issue", - // TODO New key - Add a translation - "relationships.isJournalIssueOf": "Journal Issue", + "relationships.isJournalIssueOf": "Dergi Sayısı", // "relationships.isJournalOf": "Journals", - // TODO New key - Add a translation - "relationships.isJournalOf": "Journals", + "relationships.isJournalOf": "Dergiler", // "relationships.isOrgUnitOf": "Organizational Units", - // TODO New key - Add a translation - "relationships.isOrgUnitOf": "Organizational Units", + "relationships.isOrgUnitOf": "Organizasyon Birimleri", // "relationships.isPersonOf": "Authors", - // TODO New key - Add a translation - "relationships.isPersonOf": "Authors", + "relationships.isPersonOf": "Yazarlar", // "relationships.isProjectOf": "Research Projects", - // TODO New key - Add a translation - "relationships.isProjectOf": "Research Projects", + "relationships.isProjectOf": "Araştırma Projeleri", // "relationships.isPublicationOf": "Publications", - // TODO New key - Add a translation - "relationships.isPublicationOf": "Publications", + "relationships.isPublicationOf": "Yayınlar", // "relationships.isPublicationOfJournalIssue": "Articles", - // TODO New key - Add a translation - "relationships.isPublicationOfJournalIssue": "Articles", + "relationships.isPublicationOfJournalIssue": "Makaleler", // "relationships.isSingleJournalOf": "Journal", - // TODO New key - Add a translation - "relationships.isSingleJournalOf": "Journal", + "relationships.isSingleJournalOf": "Dergi", // "relationships.isSingleVolumeOf": "Journal Volume", - // TODO New key - Add a translation - "relationships.isSingleVolumeOf": "Journal Volume", + "relationships.isSingleVolumeOf": "Dergi Cilti", // "relationships.isVolumeOf": "Journal Volumes", - // TODO New key - Add a translation - "relationships.isVolumeOf": "Journal Volumes", + "relationships.isVolumeOf": "Dergi Ciltleri", // "relationships.isContributorOf": "Contributors", - // TODO New key - Add a translation - "relationships.isContributorOf": "Contributors", + "relationships.isContributorOf": "Katkıda Bulunanlar", // "resource-policies.add.button": "Add", - // TODO New key - Add a translation - "resource-policies.add.button": "Add", + "resource-policies.add.button": "Ekle", // "resource-policies.add.for.": "Add a new policy", - // TODO New key - Add a translation - "resource-policies.add.for.": "Add a new policy", + "resource-policies.add.for.": "Yeni bir politika ekle", // "resource-policies.add.for.bitstream": "Add a new Bitstream policy", - // TODO New key - Add a translation - "resource-policies.add.for.bitstream": "Add a new Bitstream policy", + "resource-policies.add.for.bitstream": "Yeni bir Bitstream ilkesi ekleyin", // "resource-policies.add.for.bundle": "Add a new Bundle policy", - // TODO New key - Add a translation - "resource-policies.add.for.bundle": "Add a new Bundle policy", + "resource-policies.add.for.bundle": "Yeni bir Bundle ilkesi ekleyin", // "resource-policies.add.for.item": "Add a new Item policy", - // TODO New key - Add a translation - "resource-policies.add.for.item": "Add a new Item policy", + "resource-policies.add.for.item": "Yeni bir öğe ilkesi ekleyin", // "resource-policies.add.for.community": "Add a new Community policy", - // TODO New key - Add a translation - "resource-policies.add.for.community": "Add a new Community policy", + "resource-policies.add.for.community": "Yeni bir Topluluk politikası ekle", // "resource-policies.add.for.collection": "Add a new Collection policy", - // TODO New key - Add a translation - "resource-policies.add.for.collection": "Add a new Collection policy", + "resource-policies.add.for.collection": "Yeni bir Koleksiyon politikası ekle", // "resource-policies.create.page.heading": "Create new resource policy for ", - // TODO New key - Add a translation - "resource-policies.create.page.heading": "Create new resource policy for ", + "resource-policies.create.page.heading": "Şunun için yeni kaynak ilkesi oluşturun: ", // "resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.", - // TODO New key - Add a translation - "resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.", + "resource-policies.create.page.failure.content": "Kaynak ilkesi oluşturulurken bir hata oluştu.", // "resource-policies.create.page.success.content": "Operation successful", - // TODO New key - Add a translation - "resource-policies.create.page.success.content": "Operation successful", + "resource-policies.create.page.success.content": "Operasyon başarılı", // "resource-policies.create.page.title": "Create new resource policy", - // TODO New key - Add a translation - "resource-policies.create.page.title": "Create new resource policy", + "resource-policies.create.page.title": "Yeni kaynak politikası oluştur", // "resource-policies.delete.btn": "Delete selected", - // TODO New key - Add a translation - "resource-policies.delete.btn": "Delete selected", + "resource-policies.delete.btn": "Seçileni sil", // "resource-policies.delete.btn.title": "Delete selected resource policies", - // TODO New key - Add a translation - "resource-policies.delete.btn.title": "Delete selected resource policies", + "resource-policies.delete.btn.title": "Seçili kaynak politikalarını sil", // "resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.", - // TODO New key - Add a translation - "resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.", + "resource-policies.delete.failure.content": "Seçili kaynak ilkeleri silinirken bir hata oluştu.", // "resource-policies.delete.success.content": "Operation successful", - // TODO New key - Add a translation - "resource-policies.delete.success.content": "Operation successful", + "resource-policies.delete.success.content": "İşlem başarılı", // "resource-policies.edit.page.heading": "Edit resource policy ", - // TODO New key - Add a translation - "resource-policies.edit.page.heading": "Edit resource policy ", + "resource-policies.edit.page.heading": "Kaynak politikasını düzenle ", // "resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.", - // TODO New key - Add a translation - "resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.", + "resource-policies.edit.page.failure.content": "Kaynak ilkesi düzenlenirken bir hata oluştu.", // "resource-policies.edit.page.success.content": "Operation successful", - // TODO New key - Add a translation - "resource-policies.edit.page.success.content": "Operation successful", + "resource-policies.edit.page.success.content": "İşlem başarılı", // "resource-policies.edit.page.title": "Edit resource policy", - // TODO New key - Add a translation - "resource-policies.edit.page.title": "Edit resource policy", + "resource-policies.edit.page.title": "Kaynak politikasını düzenle", // "resource-policies.form.action-type.label": "Select the action type", - // TODO New key - Add a translation - "resource-policies.form.action-type.label": "Select the action type", + "resource-policies.form.action-type.label": "Eylem türünü seçin", // "resource-policies.form.action-type.required": "You must select the resource policy action.", - // TODO New key - Add a translation - "resource-policies.form.action-type.required": "You must select the resource policy action.", + "resource-policies.form.action-type.required": "Kaynak ilkesi eylemini seçmelisiniz.", // "resource-policies.form.eperson-group-list.label": "The eperson or group that will be granted the permission", - // TODO New key - Add a translation - "resource-policies.form.eperson-group-list.label": "The eperson or group that will be granted the permission", + "resource-policies.form.eperson-group-list.label": "İzin verilecek e-kişi veya grup", // "resource-policies.form.eperson-group-list.select.btn": "Select", - // TODO New key - Add a translation - "resource-policies.form.eperson-group-list.select.btn": "Select", + "resource-policies.form.eperson-group-list.select.btn": "Seç", // "resource-policies.form.eperson-group-list.tab.eperson": "Search for a ePerson", - // TODO New key - Add a translation - "resource-policies.form.eperson-group-list.tab.eperson": "Search for a ePerson", + "resource-policies.form.eperson-group-list.tab.eperson": "e-kişi arayın", // "resource-policies.form.eperson-group-list.tab.group": "Search for a group", - // TODO New key - Add a translation - "resource-policies.form.eperson-group-list.tab.group": "Search for a group", + "resource-policies.form.eperson-group-list.tab.group": "Grup arayın", // "resource-policies.form.eperson-group-list.table.headers.action": "Action", - // TODO New key - Add a translation - "resource-policies.form.eperson-group-list.table.headers.action": "Action", + "resource-policies.form.eperson-group-list.table.headers.action": "Eylem", // "resource-policies.form.eperson-group-list.table.headers.id": "ID", - // TODO New key - Add a translation - "resource-policies.form.eperson-group-list.table.headers.id": "ID", + "resource-policies.form.eperson-group-list.table.headers.id": "Kimlik", // "resource-policies.form.eperson-group-list.table.headers.name": "Name", - // TODO New key - Add a translation - "resource-policies.form.eperson-group-list.table.headers.name": "Name", + "resource-policies.form.eperson-group-list.table.headers.name": "Ad", // "resource-policies.form.date.end.label": "End Date", - // TODO New key - Add a translation - "resource-policies.form.date.end.label": "End Date", + "resource-policies.form.date.end.label": "Bitiş Tarihi", // "resource-policies.form.date.start.label": "Start Date", - // TODO New key - Add a translation - "resource-policies.form.date.start.label": "Start Date", + "resource-policies.form.date.start.label": "Başlangıç tarihi", // "resource-policies.form.description.label": "Description", - // TODO New key - Add a translation - "resource-policies.form.description.label": "Description", + "resource-policies.form.description.label": "Açıklama", // "resource-policies.form.name.label": "Name", - // TODO New key - Add a translation - "resource-policies.form.name.label": "Name", + "resource-policies.form.name.label": "Ad", // "resource-policies.form.policy-type.label": "Select the policy type", - // TODO New key - Add a translation - "resource-policies.form.policy-type.label": "Select the policy type", + "resource-policies.form.policy-type.label": "Politika türünü seçin", // "resource-policies.form.policy-type.required": "You must select the resource policy type.", - // TODO New key - Add a translation - "resource-policies.form.policy-type.required": "You must select the resource policy type.", + "resource-policies.form.policy-type.required": "Kaynak ilkesi türünü seçmelisiniz.", // "resource-policies.table.headers.action": "Action", - // TODO New key - Add a translation - "resource-policies.table.headers.action": "Action", + "resource-policies.table.headers.action": "Eylem", // "resource-policies.table.headers.date.end": "End Date", - // TODO New key - Add a translation - "resource-policies.table.headers.date.end": "End Date", + "resource-policies.table.headers.date.end": "Bitiş tarihi", // "resource-policies.table.headers.date.start": "Start Date", - // TODO New key - Add a translation - "resource-policies.table.headers.date.start": "Start Date", + "resource-policies.table.headers.date.start": "Başlangıç Tarihi", // "resource-policies.table.headers.edit": "Edit", - // TODO New key - Add a translation - "resource-policies.table.headers.edit": "Edit", + "resource-policies.table.headers.edit": "Düzenle", // "resource-policies.table.headers.edit.group": "Edit group", - // TODO New key - Add a translation - "resource-policies.table.headers.edit.group": "Edit group", + "resource-policies.table.headers.edit.group": "Grubu düzenle", // "resource-policies.table.headers.edit.policy": "Edit policy", - // TODO New key - Add a translation - "resource-policies.table.headers.edit.policy": "Edit policy", + "resource-policies.table.headers.edit.policy": "Politikayı düzenle", - // "resource-policies.table.headers.eperson": "EPerson", - // TODO New key - Add a translation - "resource-policies.table.headers.eperson": "EPerson", + // "resource-policies.table.headers.eperson": "E-kişi", + "resource-policies.table.headers.eperson": "E-kişi", - // "resource-policies.table.headers.group": "Group", - // TODO New key - Add a translation - "resource-policies.table.headers.group": "Group", + // "resource-policies.table.headers.group": "Grup", + "resource-policies.table.headers.group": "Grup", // "resource-policies.table.headers.id": "ID", - // TODO New key - Add a translation - "resource-policies.table.headers.id": "ID", + "resource-policies.table.headers.id": "Kimlik", // "resource-policies.table.headers.name": "Name", - // TODO New key - Add a translation - "resource-policies.table.headers.name": "Name", + "resource-policies.table.headers.name": "Ad", // "resource-policies.table.headers.policyType": "type", - // TODO New key - Add a translation - "resource-policies.table.headers.policyType": "type", + "resource-policies.table.headers.policyType": "tür", // "resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream", + "resource-policies.table.headers.title.for.bitstream": "BitStream Politikaları", // "resource-policies.table.headers.title.for.bundle": "Policies for Bundle", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.bundle": "Policies for Bundle", + "resource-policies.table.headers.title.for.bundle": "Bundle Politikaları", // "resource-policies.table.headers.title.for.item": "Policies for Item", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.item": "Policies for Item", + "resource-policies.table.headers.title.for.item": "Öğe Politikaları", // "resource-policies.table.headers.title.for.community": "Policies for Community", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.community": "Policies for Community", + "resource-policies.table.headers.title.for.community": "Topluluk Politikaları", // "resource-policies.table.headers.title.for.collection": "Policies for Collection", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.collection": "Policies for Collection", + "resource-policies.table.headers.title.for.collection": "Koleksiyon Politikaları", // "search.description": "", - // TODO New key - Add a translation "search.description": "", // "search.switch-configuration.title": "Show", - // TODO New key - Add a translation - "search.switch-configuration.title": "Show", + "search.switch-configuration.title": "Göster", // "search.title": "DSpace Angular :: Search", - // TODO New key - Add a translation - "search.title": "DSpace Angular :: Search", + "search.title": "DSpace Angular :: Ara", // "search.breadcrumbs": "Search", - // TODO New key - Add a translation - "search.breadcrumbs": "Search", + "search.breadcrumbs": "Ara", // "search.filters.applied.f.author": "Author", - // TODO New key - Add a translation - "search.filters.applied.f.author": "Author", + "search.filters.applied.f.author": "Yazar", // "search.filters.applied.f.dateIssued.max": "End date", - // TODO New key - Add a translation - "search.filters.applied.f.dateIssued.max": "End date", + "search.filters.applied.f.dateIssued.max": "Bitiş tarihi", // "search.filters.applied.f.dateIssued.min": "Start date", - // TODO New key - Add a translation - "search.filters.applied.f.dateIssued.min": "Start date", + "search.filters.applied.f.dateIssued.min": "Başlangıç Tarihi", // "search.filters.applied.f.dateSubmitted": "Date submitted", - // TODO New key - Add a translation - "search.filters.applied.f.dateSubmitted": "Date submitted", + "search.filters.applied.f.dateSubmitted": "Gönderilme tarihi", // "search.filters.applied.f.discoverable": "Private", - // TODO New key - Add a translation - "search.filters.applied.f.discoverable": "Private", + "search.filters.applied.f.discoverable": "Özel", // "search.filters.applied.f.entityType": "Item Type", - // TODO New key - Add a translation - "search.filters.applied.f.entityType": "Item Type", + "search.filters.applied.f.entityType": "Öğe Türü", // "search.filters.applied.f.has_content_in_original_bundle": "Has files", - // TODO New key - Add a translation - "search.filters.applied.f.has_content_in_original_bundle": "Has files", + "search.filters.applied.f.has_content_in_original_bundle": "Has dosyaları", // "search.filters.applied.f.itemtype": "Type", - // TODO New key - Add a translation - "search.filters.applied.f.itemtype": "Type", + "search.filters.applied.f.itemtype": "Tür", // "search.filters.applied.f.namedresourcetype": "Status", - // TODO New key - Add a translation - "search.filters.applied.f.namedresourcetype": "Status", + "search.filters.applied.f.namedresourcetype": "Durum", // "search.filters.applied.f.subject": "Subject", - // TODO New key - Add a translation - "search.filters.applied.f.subject": "Subject", + "search.filters.applied.f.subject": "Konu", // "search.filters.applied.f.submitter": "Submitter", - // TODO New key - Add a translation - "search.filters.applied.f.submitter": "Submitter", + "search.filters.applied.f.submitter": "Gönderen", // "search.filters.applied.f.jobTitle": "Job Title", - // TODO New key - Add a translation - "search.filters.applied.f.jobTitle": "Job Title", + "search.filters.applied.f.jobTitle": "İş Adı", // "search.filters.applied.f.birthDate.max": "End birth date", - // TODO New key - Add a translation - "search.filters.applied.f.birthDate.max": "End birth date", + "search.filters.applied.f.birthDate.max": "Doğum Tarih Sonu", // "search.filters.applied.f.birthDate.min": "Start birth date", - // TODO New key - Add a translation - "search.filters.applied.f.birthDate.min": "Start birth date", + "search.filters.applied.f.birthDate.min": "Doğum Tarih Başlangıcı", // "search.filters.applied.f.withdrawn": "Withdrawn", - // TODO New key - Add a translation - "search.filters.applied.f.withdrawn": "Withdrawn", + "search.filters.applied.f.withdrawn": "Geri çekildi", // "search.filters.filter.author.head": "Author", - // TODO New key - Add a translation - "search.filters.filter.author.head": "Author", + "search.filters.filter.author.head": "Yazar", // "search.filters.filter.author.placeholder": "Author name", - // TODO New key - Add a translation - "search.filters.filter.author.placeholder": "Author name", + "search.filters.filter.author.placeholder": "Yazar adı", // "search.filters.filter.birthDate.head": "Birth Date", - // TODO New key - Add a translation - "search.filters.filter.birthDate.head": "Birth Date", + "search.filters.filter.birthDate.head": "Doğum Tarihi", // "search.filters.filter.birthDate.placeholder": "Birth Date", - // TODO New key - Add a translation - "search.filters.filter.birthDate.placeholder": "Birth Date", + "search.filters.filter.birthDate.placeholder": "Doğum Tarihi", // "search.filters.filter.creativeDatePublished.head": "Date Published", - // TODO New key - Add a translation - "search.filters.filter.creativeDatePublished.head": "Date Published", + "search.filters.filter.creativeDatePublished.head": "Yayınlanma Tarihi", // "search.filters.filter.creativeDatePublished.placeholder": "Date Published", - // TODO New key - Add a translation - "search.filters.filter.creativeDatePublished.placeholder": "Date Published", + "search.filters.filter.creativeDatePublished.placeholder": "Yayınlanma Tarihi", // "search.filters.filter.creativeWorkEditor.head": "Editor", - // TODO New key - Add a translation - "search.filters.filter.creativeWorkEditor.head": "Editor", + "search.filters.filter.creativeWorkEditor.head": "Editör", // "search.filters.filter.creativeWorkEditor.placeholder": "Editor", - // TODO New key - Add a translation - "search.filters.filter.creativeWorkEditor.placeholder": "Editor", + "search.filters.filter.creativeWorkEditor.placeholder": "Editör", // "search.filters.filter.creativeWorkKeywords.head": "Subject", - // TODO New key - Add a translation - "search.filters.filter.creativeWorkKeywords.head": "Subject", + "search.filters.filter.creativeWorkKeywords.head": "Konu", // "search.filters.filter.creativeWorkKeywords.placeholder": "Subject", - // TODO New key - Add a translation - "search.filters.filter.creativeWorkKeywords.placeholder": "Subject", + "search.filters.filter.creativeWorkKeywords.placeholder": "Konu", // "search.filters.filter.creativeWorkPublisher.head": "Publisher", - // TODO New key - Add a translation - "search.filters.filter.creativeWorkPublisher.head": "Publisher", + "search.filters.filter.creativeWorkPublisher.head": "Yayımcı", // "search.filters.filter.creativeWorkPublisher.placeholder": "Publisher", - // TODO New key - Add a translation - "search.filters.filter.creativeWorkPublisher.placeholder": "Publisher", + "search.filters.filter.creativeWorkPublisher.placeholder": "Yayımcı", // "search.filters.filter.dateIssued.head": "Date", - // TODO New key - Add a translation - "search.filters.filter.dateIssued.head": "Date", - + "search.filters.filter.dateIssued.head": "Tarih", + // "search.filters.filter.dateIssued.max.placeholder": "Minimum Date", - // TODO New key - Add a translation - "search.filters.filter.dateIssued.max.placeholder": "Minimum Date", + "search.filters.filter.dateIssued.max.placeholder": "En Erken Tarih", // "search.filters.filter.dateIssued.min.placeholder": "Maximum Date", - // TODO New key - Add a translation - "search.filters.filter.dateIssued.min.placeholder": "Maximum Date", + "search.filters.filter.dateIssued.min.placeholder": "En Geç Tarih", // "search.filters.filter.dateSubmitted.head": "Date submitted", - // TODO New key - Add a translation - "search.filters.filter.dateSubmitted.head": "Date submitted", + "search.filters.filter.dateSubmitted.head": "Teslim Edilen Tarih", // "search.filters.filter.dateSubmitted.placeholder": "Date submitted", - // TODO New key - Add a translation - "search.filters.filter.dateSubmitted.placeholder": "Date submitted", + "search.filters.filter.dateSubmitted.placeholder": "Teslim Edilen Tarih", // "search.filters.filter.discoverable.head": "Private", - // TODO New key - Add a translation - "search.filters.filter.discoverable.head": "Private", + "search.filters.filter.discoverable.head": "Özel", // "search.filters.filter.withdrawn.head": "Withdrawn", - // TODO New key - Add a translation - "search.filters.filter.withdrawn.head": "Withdrawn", + "search.filters.filter.withdrawn.head": "Alınmış", // "search.filters.filter.entityType.head": "Item Type", - // TODO New key - Add a translation - "search.filters.filter.entityType.head": "Item Type", + "search.filters.filter.entityType.head": "Materyal Türü", // "search.filters.filter.entityType.placeholder": "Item Type", - // TODO New key - Add a translation - "search.filters.filter.entityType.placeholder": "Item Type", + "search.filters.filter.entityType.placeholder": "Materyal Türü", // "search.filters.filter.has_content_in_original_bundle.head": "Has files", - // TODO New key - Add a translation - "search.filters.filter.has_content_in_original_bundle.head": "Has files", + "search.filters.filter.has_content_in_original_bundle.head": "Dosyalara Sahip", // "search.filters.filter.itemtype.head": "Type", - // TODO New key - Add a translation - "search.filters.filter.itemtype.head": "Type", + "search.filters.filter.itemtype.head": "Tür", // "search.filters.filter.itemtype.placeholder": "Type", - // TODO New key - Add a translation - "search.filters.filter.itemtype.placeholder": "Type", + "search.filters.filter.itemtype.placeholder": "Tür", // "search.filters.filter.jobTitle.head": "Job Title", - // TODO New key - Add a translation - "search.filters.filter.jobTitle.head": "Job Title", + "search.filters.filter.jobTitle.head": "İş Ünvanı", // "search.filters.filter.jobTitle.placeholder": "Job Title", - // TODO New key - Add a translation - "search.filters.filter.jobTitle.placeholder": "Job Title", + "search.filters.filter.jobTitle.placeholder": "İş Ünvanı", // "search.filters.filter.knowsLanguage.head": "Known language", - // TODO New key - Add a translation - "search.filters.filter.knowsLanguage.head": "Known language", + "search.filters.filter.knowsLanguage.head": "Bilinen Diller", // "search.filters.filter.knowsLanguage.placeholder": "Known language", - // TODO New key - Add a translation - "search.filters.filter.knowsLanguage.placeholder": "Known language", + "search.filters.filter.knowsLanguage.placeholder": "Bilinen Diller", // "search.filters.filter.namedresourcetype.head": "Status", - // TODO New key - Add a translation - "search.filters.filter.namedresourcetype.head": "Status", + "search.filters.filter.namedresourcetype.head": "Durum", // "search.filters.filter.namedresourcetype.placeholder": "Status", - // TODO New key - Add a translation - "search.filters.filter.namedresourcetype.placeholder": "Status", + "search.filters.filter.namedresourcetype.placeholder": "Durum", // "search.filters.filter.objectpeople.head": "People", - // TODO New key - Add a translation - "search.filters.filter.objectpeople.head": "People", + "search.filters.filter.objectpeople.head": "İnsanlar", // "search.filters.filter.objectpeople.placeholder": "People", - // TODO New key - Add a translation - "search.filters.filter.objectpeople.placeholder": "People", + "search.filters.filter.objectpeople.placeholder": "İnsanlar", // "search.filters.filter.organizationAddressCountry.head": "Country", - // TODO New key - Add a translation - "search.filters.filter.organizationAddressCountry.head": "Country", + "search.filters.filter.organizationAddressCountry.head": "Ülke", // "search.filters.filter.organizationAddressCountry.placeholder": "Country", - // TODO New key - Add a translation - "search.filters.filter.organizationAddressCountry.placeholder": "Country", + "search.filters.filter.organizationAddressCountry.placeholder": "Ülke", // "search.filters.filter.organizationAddressLocality.head": "City", - // TODO New key - Add a translation - "search.filters.filter.organizationAddressLocality.head": "City", + "search.filters.filter.organizationAddressLocality.head": "Şehir", // "search.filters.filter.organizationAddressLocality.placeholder": "City", - // TODO New key - Add a translation - "search.filters.filter.organizationAddressLocality.placeholder": "City", + "search.filters.filter.organizationAddressLocality.placeholder": "Şehir", // "search.filters.filter.organizationFoundingDate.head": "Date Founded", - // TODO New key - Add a translation - "search.filters.filter.organizationFoundingDate.head": "Date Founded", + "search.filters.filter.organizationFoundingDate.head": "Bulunduğu Tarih", // "search.filters.filter.organizationFoundingDate.placeholder": "Date Founded", - // TODO New key - Add a translation - "search.filters.filter.organizationFoundingDate.placeholder": "Date Founded", + "search.filters.filter.organizationFoundingDate.placeholder": "Bulunduğu Tarih", // "search.filters.filter.scope.head": "Scope", - // TODO New key - Add a translation - "search.filters.filter.scope.head": "Scope", + "search.filters.filter.scope.head": "Kapsam", // "search.filters.filter.scope.placeholder": "Scope filter", - // TODO New key - Add a translation - "search.filters.filter.scope.placeholder": "Scope filter", + "search.filters.filter.scope.placeholder": "Kapsam Filtresi", // "search.filters.filter.show-less": "Collapse", - // TODO New key - Add a translation - "search.filters.filter.show-less": "Collapse", + "search.filters.filter.show-less": "Yığılmış", // "search.filters.filter.show-more": "Show more", - // TODO New key - Add a translation - "search.filters.filter.show-more": "Show more", + "search.filters.filter.show-more": "Daha Fazla Göster", // "search.filters.filter.subject.head": "Subject", - // TODO New key - Add a translation - "search.filters.filter.subject.head": "Subject", + "search.filters.filter.subject.head": "Konu", // "search.filters.filter.subject.placeholder": "Subject", - // TODO New key - Add a translation - "search.filters.filter.subject.placeholder": "Subject", + "search.filters.filter.subject.placeholder": "Konu", // "search.filters.filter.submitter.head": "Submitter", - // TODO New key - Add a translation - "search.filters.filter.submitter.head": "Submitter", + "search.filters.filter.submitter.head": "Teslim Eden", // "search.filters.filter.submitter.placeholder": "Submitter", - // TODO New key - Add a translation - "search.filters.filter.submitter.placeholder": "Submitter", + "search.filters.filter.submitter.placeholder": "Teslim Eden", // "search.filters.entityType.JournalIssue": "Journal Issue", - // TODO New key - Add a translation - "search.filters.entityType.JournalIssue": "Journal Issue", + "search.filters.entityType.JournalIssue": "Makale Konusu", // "search.filters.entityType.JournalVolume": "Journal Volume", - // TODO New key - Add a translation - "search.filters.entityType.JournalVolume": "Journal Volume", + "search.filters.entityType.JournalVolume": "Cilt Sayısı", // "search.filters.entityType.OrgUnit": "Organizational Unit", - // TODO New key - Add a translation - "search.filters.entityType.OrgUnit": "Organizational Unit", + "search.filters.entityType.OrgUnit": "Ait Olduğu Organizasyon", // "search.filters.has_content_in_original_bundle.true": "Yes", - // TODO New key - Add a translation - "search.filters.has_content_in_original_bundle.true": "Yes", + "search.filters.has_content_in_original_bundle.true": "Evet", // "search.filters.has_content_in_original_bundle.false": "No", - // TODO New key - Add a translation - "search.filters.has_content_in_original_bundle.false": "No", + "search.filters.has_content_in_original_bundle.false": "Hayır", // "search.filters.discoverable.true": "No", - // TODO New key - Add a translation - "search.filters.discoverable.true": "No", + "search.filters.discoverable.true": "Hayır", // "search.filters.discoverable.false": "Yes", - // TODO New key - Add a translation - "search.filters.discoverable.false": "Yes", + "search.filters.discoverable.false": "Evet", // "search.filters.withdrawn.true": "Yes", - // TODO New key - Add a translation - "search.filters.withdrawn.true": "Yes", + "search.filters.withdrawn.true": "Evet", // "search.filters.withdrawn.false": "No", - // TODO New key - Add a translation - "search.filters.withdrawn.false": "No", + "search.filters.withdrawn.false": "Hayır", // "search.filters.head": "Filters", - // TODO New key - Add a translation - "search.filters.head": "Filters", + "search.filters.head": "Filtreler", // "search.filters.reset": "Reset filters", - // TODO New key - Add a translation - "search.filters.reset": "Reset filters", + "search.filters.reset": "Filtreleri Sıfırla", // "search.form.search": "Search", - // TODO New key - Add a translation - "search.form.search": "Search", + "search.form.search": "Ara", // "search.form.search_dspace": "Search DSpace", - // TODO New key - Add a translation - "search.form.search_dspace": "Search DSpace", + "search.form.search_dspace": "DSpace içinde Ara", // "search.form.search_mydspace": "Search MyDSpace", - // TODO New key - Add a translation - "search.form.search_mydspace": "Search MyDSpace", + "search.form.search_mydspace": "MyDSpace içinde Ara", // "search.results.head": "Search Results", - // TODO New key - Add a translation - "search.results.head": "Search Results", + "search.results.head": "Sonuçları Ara", // "search.results.no-results": "Your search returned no results. Having trouble finding what you're looking for? Try putting", - // TODO New key - Add a translation - "search.results.no-results": "Your search returned no results. Having trouble finding what you're looking for? Try putting", + "search.results.no-results": "Aramanız hiçbir sonuç vermedi. Aradığınızı bulmakta sorun mu yaşıyorsunuz? Bir daha deneyin.", // "search.results.no-results-link": "quotes around it", - // TODO New key - Add a translation - "search.results.no-results-link": "quotes around it", + "search.results.no-results-link": "Çevresindeki Alıntılar", // "search.results.empty": "Your search returned no results.", - // TODO New key - Add a translation - "search.results.empty": "Your search returned no results.", + "search.results.empty": "Aramanız hiçbir sonuç vermedi.", // "search.sidebar.close": "Back to results", - // TODO New key - Add a translation - "search.sidebar.close": "Back to results", + "search.sidebar.close": "Sonuçlara Dön", // "search.sidebar.filters.title": "Filters", - // TODO New key - Add a translation - "search.sidebar.filters.title": "Filters", + "search.sidebar.filters.title": "Filtreler", // "search.sidebar.open": "Search Tools", - // TODO New key - Add a translation - "search.sidebar.open": "Search Tools", + "search.sidebar.open": "Araç Gereç Ara", // "search.sidebar.results": "results", - // TODO New key - Add a translation - "search.sidebar.results": "results", + "search.sidebar.results": "Sonuçlar", // "search.sidebar.settings.rpp": "Results per page", - // TODO New key - Add a translation - "search.sidebar.settings.rpp": "Results per page", + "search.sidebar.settings.rpp": "Sayfa Sonuçları", // "search.sidebar.settings.sort-by": "Sort By", - // TODO New key - Add a translation - "search.sidebar.settings.sort-by": "Sort By", + "search.sidebar.settings.sort-by": "Göre Sıralanmış", // "search.sidebar.settings.title": "Settings", - // TODO New key - Add a translation - "search.sidebar.settings.title": "Settings", + "search.sidebar.settings.title": "Ayarlar", // "search.view-switch.show-detail": "Show detail", - // TODO New key - Add a translation - "search.view-switch.show-detail": "Show detail", + "search.view-switch.show-detail": "Detayları Göster", // "search.view-switch.show-grid": "Show as grid", - // TODO New key - Add a translation - "search.view-switch.show-grid": "Show as grid", + "search.view-switch.show-grid": "Ağ Dizge Olarak Göster", // "search.view-switch.show-list": "Show as list", - // TODO New key - Add a translation - "search.view-switch.show-list": "Show as list", + "search.view-switch.show-list": "Liste Olarak Göster", // "sorting.ASC": "Ascending", - // TODO New key - Add a translation - "sorting.ASC": "Ascending", + "sorting.ASC": "Artan", // "sorting.DESC": "Descending", - // TODO New key - Add a translation - "sorting.DESC": "Descending", + "sorting.DESC": "Azalan", // "sorting.dc.title.ASC": "Title Ascending", - // TODO New key - Add a translation - "sorting.dc.title.ASC": "Title Ascending", + "sorting.dc.title.ASC": "Artan Başlıklar", // "sorting.dc.title.DESC": "Title Descending", - // TODO New key - Add a translation - "sorting.dc.title.DESC": "Title Descending", + "sorting.dc.title.DESC": "Azalan Başlıklar", // "sorting.score.DESC": "Relevance", - // TODO New key - Add a translation - "sorting.score.DESC": "Relevance", + "sorting.score.DESC": "Bağıntılı", // "statistics.title": "Statistics", - // TODO New key - Add a translation - "statistics.title": "Statistics", + "statistics.title": "İstatistikler", // "statistics.header": "Statistics for {{ scope }}", - // TODO New key - Add a translation - "statistics.header": "Statistics for {{ scope }}", + "statistics.header": "{{ scope }} için İstatistikler", // "statistics.breadcrumbs": "Statistics", - // TODO New key - Add a translation - "statistics.breadcrumbs": "Statistics", + "statistics.breadcrumbs": "İstatistikler", // "statistics.page.no-data": "No data available", - // TODO New key - Add a translation - "statistics.page.no-data": "No data available", + "statistics.page.no-data": "Data Bulunamadı.", // "statistics.table.no-data": "No data available", - // TODO New key - Add a translation - "statistics.table.no-data": "No data available", + "statistics.table.no-data": "Data Bulunamadı.", // "statistics.table.title.TotalVisits": "Total visits", - // TODO New key - Add a translation - "statistics.table.title.TotalVisits": "Total visits", + "statistics.table.title.TotalVisits": "Toplam Ziyaretler", // "statistics.table.title.TotalVisitsPerMonth": "Total visits per month", - // TODO New key - Add a translation - "statistics.table.title.TotalVisitsPerMonth": "Total visits per month", + "statistics.table.title.TotalVisitsPerMonth": "Aylık Toplam Ziyaretler", // "statistics.table.title.TotalDownloads": "File Visits", - // TODO New key - Add a translation - "statistics.table.title.TotalDownloads": "File Visits", + "statistics.table.title.TotalDownloads": "Dosya Ziyaretleri", // "statistics.table.title.TopCountries": "Top country views", - // TODO New key - Add a translation - "statistics.table.title.TopCountries": "Top country views", + "statistics.table.title.TopCountries": "En Çok Gösterilen Ülke", // "statistics.table.title.TopCities": "Top city views", - // TODO New key - Add a translation - "statistics.table.title.TopCities": "Top city views", + "statistics.table.title.TopCities": "En Çok Gösterilen Şehir", // "statistics.table.header.views": "Views", - // TODO New key - Add a translation - "statistics.table.header.views": "Views", + "statistics.table.header.views": "Gösterilmeler", // "submission.edit.title": "Edit Submission", - // TODO New key - Add a translation - "submission.edit.title": "Edit Submission", + "submission.edit.title": "Teslimi Düzenle", // "submission.general.cannot_submit": "You have not the privilege to make a new submission.", - // TODO New key - Add a translation - "submission.general.cannot_submit": "You have not the privilege to make a new submission.", + "submission.general.cannot_submit": "Yeni bir teslim yapamazsınız.", // "submission.general.deposit": "Deposit", - // TODO New key - Add a translation - "submission.general.deposit": "Deposit", + "submission.general.deposit": "Para Yatır", // "submission.general.discard.confirm.cancel": "Cancel", - // TODO New key - Add a translation - "submission.general.discard.confirm.cancel": "Cancel", + "submission.general.discard.confirm.cancel": "Vazgeç", // "submission.general.discard.confirm.info": "This operation can't be undone. Are you sure?", - // TODO New key - Add a translation - "submission.general.discard.confirm.info": "This operation can't be undone. Are you sure?", + "submission.general.discard.confirm.info": "Bu işlem geri alınamaz. Emin misiniz?", // "submission.general.discard.confirm.submit": "Yes, I'm sure", - // TODO New key - Add a translation - "submission.general.discard.confirm.submit": "Yes, I'm sure", + "submission.general.discard.confirm.submit": "Evet eminim", // "submission.general.discard.confirm.title": "Discard submission", - // TODO New key - Add a translation - "submission.general.discard.confirm.title": "Discard submission", + "submission.general.discard.confirm.title": "Teslimi İptal Et", // "submission.general.discard.submit": "Discard", - // TODO New key - Add a translation - "submission.general.discard.submit": "Discard", + "submission.general.discard.submit": "İptal", // "submission.general.save": "Save", - // TODO New key - Add a translation - "submission.general.save": "Save", + "submission.general.save": "Kaydet", // "submission.general.save-later": "Save for later", - // TODO New key - Add a translation - "submission.general.save-later": "Save for later", + "submission.general.save-later": "Sonrası İçin Kaydet", // "submission.import-external.page.title": "Import metadata from an external source", - // TODO New key - Add a translation - "submission.import-external.page.title": "Import metadata from an external source", + "submission.import-external.page.title": "Harici bir kaynaktan meta verileri içe aktarın", // "submission.import-external.title": "Import metadata from an external source", - // TODO New key - Add a translation - "submission.import-external.title": "Import metadata from an external source", + "submission.import-external.title": "Harici bir kaynaktan meta verileri içe aktarın", // "submission.import-external.page.hint": "Enter a query above to find items from the web to import in to DSpace.", - // TODO New key - Add a translation - "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": "Web'den DSpace'e içe aktarılacak öğeleri bulmak için yukarıya bir sorgu girin.", // "submission.import-external.back-to-my-dspace": "Back to MyDSpace", - // TODO New key - Add a translation - "submission.import-external.back-to-my-dspace": "Back to MyDSpace", + "submission.import-external.back-to-my-dspace": "MyDSpace'e Geri Dön", // "submission.import-external.search.placeholder": "Search the external source", - // TODO New key - Add a translation - "submission.import-external.search.placeholder": "Search the external source", + "submission.import-external.search.placeholder": "Dış Kaynaktan Ara", // "submission.import-external.search.button": "Search", - // TODO New key - Add a translation - "submission.import-external.search.button": "Search", + "submission.import-external.search.button": "Ara", // "submission.import-external.search.button.hint": "Write some words to search", - // TODO New key - Add a translation - "submission.import-external.search.button.hint": "Write some words to search", + "submission.import-external.search.button.hint": "Aramak için Kelime Girin", // "submission.import-external.search.source.hint": "Pick an external source", - // TODO New key - Add a translation - "submission.import-external.search.source.hint": "Pick an external source", + "submission.import-external.search.source.hint": "Dış Kaynak Seçin", // "submission.import-external.source.arxiv": "arXiv", - // TODO New key - Add a translation "submission.import-external.source.arxiv": "arXiv", // "submission.import-external.source.loading": "Loading ...", - // TODO New key - Add a translation - "submission.import-external.source.loading": "Loading ...", + "submission.import-external.source.loading": "Yükleniyor ...", // "submission.import-external.source.sherpaJournal": "SHERPA Journals", - // TODO New key - Add a translation "submission.import-external.source.sherpaJournal": "SHERPA Journals", // "submission.import-external.source.sherpaPublisher": "SHERPA Publishers", - // TODO New key - Add a translation "submission.import-external.source.sherpaPublisher": "SHERPA Publishers", // "submission.import-external.source.orcid": "ORCID", - // TODO New key - Add a translation "submission.import-external.source.orcid": "ORCID", // "submission.import-external.source.pubmed": "Pubmed", - // TODO New key - Add a translation "submission.import-external.source.pubmed": "Pubmed", // "submission.import-external.source.lcname": "Library of Congress Names", - // TODO New key - Add a translation - "submission.import-external.source.lcname": "Library of Congress Names", + "submission.import-external.source.lcname": "Kongre İsimleri Kütüphanesi", // "submission.import-external.preview.title": "Item Preview", - // TODO New key - Add a translation - "submission.import-external.preview.title": "Item Preview", + "submission.import-external.preview.title": "Materyal Önizlenimi", // "submission.import-external.preview.subtitle": "The metadata below was imported from an external source. It will be pre-filled when you start the submission.", - // TODO New key - Add a translation - "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": "Aşağıdaki meta veriler harici bir kaynaktan içe aktarıldı. Gönderime başladığınızda önceden doldurulacaktır.", // "submission.import-external.preview.button.import": "Start submission", - // TODO New key - Add a translation - "submission.import-external.preview.button.import": "Start submission", + "submission.import-external.preview.button.import": "Gönderimi Başlat", // "submission.import-external.preview.error.import.title": "Submission error", - // TODO New key - Add a translation - "submission.import-external.preview.error.import.title": "Submission error", + "submission.import-external.preview.error.import.title": "Gönderim Sırasında Hata", // "submission.import-external.preview.error.import.body": "An error occurs during the external source entry import process.", - // TODO New key - Add a translation - "submission.import-external.preview.error.import.body": "An error occurs during the external source entry import process.", + "submission.import-external.preview.error.import.body": "Dış kaynak girişi içe aktarma işlemi sırasında bir hata oluştu.", // "submission.sections.describe.relationship-lookup.close": "Close", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.close": "Close", + "submission.sections.describe.relationship-lookup.close": "Kapat", // "submission.sections.describe.relationship-lookup.external-source.added": "Successfully added local entry to the selection", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.external-source.added": "Successfully added local entry to the selection", + "submission.sections.describe.relationship-lookup.external-source.added": "Giriş seçime başarıyla eklendi", // "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "Import remote author", - // TODO New key - Add a translation - "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": "Dış Kaynak Yazarı İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Import remote journal", - // TODO New key - Add a translation - "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": "Dış Kaynak Makaleyi İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Import remote journal issue", - // TODO New key - Add a translation - "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": "Dış Kaynak Makale Konusu İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume", - // TODO New key - Add a translation - "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": "Dış Kaynak Makale Cilt Sayısı İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", - // TODO New key - Add a translation - "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": "Dış Kaynak Yazarı İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Successfully added local author to the selection", - // TODO New key - Add a translation - "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": "Yazar seçime başarıyla eklendi", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Successfully imported and added external author to the selection", - // TODO New key - Add a translation - "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": "Harici yazar başarıyla içe aktarıldı ve seçime eklendi", // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority", + "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Yetkili", // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "Import as a new local authority entry", - // TODO New key - Add a translation - "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": "Yeni bir yerel yetkili girişi olarak içe aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "Cancel", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "Cancel", + "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "İptal", // "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "Select a collection to import new entries to", - // TODO New key - Add a translation - "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": "Yeni girişleri içe aktarmak için bir koleksiyon seçin", // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities", + "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Varlıklar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "Import as a new local entity", - // TODO New key - Add a translation - "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": "Yeni bir yerel varlık olarak içe aktar", - // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "Importing from LC Name", - // TODO New key - Add a translation + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "LC Adına göre İçe Aktar", "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.orcid": "Importing from ORCID", - // TODO New key - Add a translation - "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": "ORCID'den İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaJournal": "Importing from Sherpa Journal", - // TODO New key - Add a translation - "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": "Sherpa Journal'den İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaPublisher": "Importing from Sherpa Publisher", - // TODO New key - Add a translation - "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": "Sherpa Publisher'den İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.pubmed": "Importing from PubMed", - // TODO New key - Add a translation - "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'den İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.arxiv": "Importing from arXiv", - // TODO New key - Add a translation - "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'den İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "Import", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "Import", + "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "Import Remote Journal", - // TODO New key - Add a translation - "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": "Makaleyi Dışardan İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "Successfully added local journal to the selection", - // TODO New key - Add a translation - "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": " Makale seçime başarıyla eklendi", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "Successfully imported and added external journal to the selection", - // TODO New key - Add a translation - "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": "Harici makale başarıyla içe aktarıldı ve seçime eklendi", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.title": "Import Remote Journal Issue", - // TODO New key - Add a translation - "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": "Dış Kaynak Makale Konusu İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "Successfully added local journal issue to the selection", - // TODO New key - Add a translation - "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": "Dış Kaynak Makale Konusu Başarıyla İçe Aktarıldı.", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "Successfully imported and added external journal issue to the selection", - // TODO New key - Add a translation - "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": "Başarıyla içe aktarıldı ve seçime harici makale sayısı eklendi", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "Import Remote Journal Volume", - // TODO New key - Add a translation - "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": "Dış Kaynak Makale Cilt Sayısı İçe Aktar", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "Successfully added local journal volume to the selection", - // TODO New key - Add a translation - "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": "Dış Kaynak Makale Cilt Sayısı Başarıyla İçe Aktarıldı.", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "Successfully imported and added external journal volume to the selection", - // TODO New key - Add a translation - "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": "Harici makale cilti başarıyla içe aktarıldı ve seçime eklendi", // "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Select a local match:", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Select a local match:", + "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Yerel Eşleşmeyi Seç", // "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all", + "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Tümünü Seçmeyi Bırak", // "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page", + "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Sayfa Seçimin Bırak", // "submission.sections.describe.relationship-lookup.search-tab.loading": "Loading...", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.loading": "Loading...", + "submission.sections.describe.relationship-lookup.search-tab.loading": "Yükleniyor...", // "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Search query", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Search query", + "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Arama Sorgusu", // "submission.sections.describe.relationship-lookup.search-tab.search": "Go", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.search": "Go", + "submission.sections.describe.relationship-lookup.search-tab.search": "Git", // "submission.sections.describe.relationship-lookup.search-tab.select-all": "Select all", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.select-all": "Select all", + "submission.sections.describe.relationship-lookup.search-tab.select-all": "Hepsini Seç", // "submission.sections.describe.relationship-lookup.search-tab.select-page": "Select page", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.select-page": "Select page", + "submission.sections.describe.relationship-lookup.search-tab.select-page": "Sayfa Seç", // "submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items", + "submission.sections.describe.relationship-lookup.selected": "{{ size }} boyutundaki Seçili Materyaller ", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": " Yerel Yazarlar({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Yerel Makaleler ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Local Projects ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Local Projects ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Yerel Projeler ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Local Publications ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Local Publications ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Yerel Yayınlar ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Yerel Yazarlar ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Yerel Organizasyonlar({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Local Data Packages ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Local Data Packages ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Yerel Veri Paketleri ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Local Data Files ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Local Data Files ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Yerel Veri Dosyaları ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Local Journals ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Local Journals ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Yerel Makaleler ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Local Journal Issues ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Local Journal Issues ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Yerel Makale Konuları ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Local Journal Issues ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Local Journal Issues ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Yerel Makale Konuları ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Local Journal Volumes ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Local Journal Volumes ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Yerel Makale Cilt ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Local Journal Volumes ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Local Journal Volumes ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Yerel Makale Cilt ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "Sherpa Journals ({{ count }})", - // TODO New key - Add a translation "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "Sherpa Journals ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaPublisher": "Sherpa Publishers ({{ count }})", - // TODO New key - Add a translation "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaPublisher": "Sherpa Publishers ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcid": "ORCID ({{ count }})", - // TODO New key - Add a translation "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcid": "ORCID ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "LC Names ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "LC Names ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "LC Adları ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "PubMed ({{ count }})", - // TODO New key - Add a translation "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "PubMed ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{ count }})", - // TODO New key - Add a translation "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Search for Funding Agencies", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Search for Funding Agencies", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Finansman Kuruluşlarını Arama", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Search for Funding", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Search for Funding", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Finansman Arama", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Search for Organizational Units", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Search for Organizational Units", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Organizasyonları Arama", // "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Current Selection ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Current Selection ({{ count }})", + "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Mevcut Seçim ({{ count }})", // "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Journal Issues", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Journal Issues", + "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Makale Konuları", // "submission.sections.describe.relationship-lookup.title.JournalIssue": "Journal Issues", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.JournalIssue": "Journal Issues", + "submission.sections.describe.relationship-lookup.title.JournalIssue": "Makale Konuları", // "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Journal Volumes", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Journal Volumes", + "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Makale Ciltleri", // "submission.sections.describe.relationship-lookup.title.JournalVolume": "Journal Volumes", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.JournalVolume": "Journal Volumes", + "submission.sections.describe.relationship-lookup.title.JournalVolume": "Makale Ciltleri", // "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "Journals", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "Journals", + "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "Makaleler", // "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Authors", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Authors", + "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Yazarlar", // "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Funding Agency", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Funding Agency", + "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Finansman Kuruluşu", // "submission.sections.describe.relationship-lookup.title.Project": "Projects", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.Project": "Projects", + "submission.sections.describe.relationship-lookup.title.Project": "Projeler", // "submission.sections.describe.relationship-lookup.title.Publication": "Publications", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.Publication": "Publications", + "submission.sections.describe.relationship-lookup.title.Publication": "Yayınlar", // "submission.sections.describe.relationship-lookup.title.Person": "Authors", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.Person": "Authors", + "submission.sections.describe.relationship-lookup.title.Person": "Yazarlar", // "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organizational Units", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organizational Units", + "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organizasyonlar", // "submission.sections.describe.relationship-lookup.title.DataPackage": "Data Packages", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.DataPackage": "Data Packages", + "submission.sections.describe.relationship-lookup.title.DataPackage": "Veri Paketler", // "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", + "submission.sections.describe.relationship-lookup.title.DataFile": "Veri Dosyaları", // "submission.sections.describe.relationship-lookup.title.Funding Agency": "Funding Agency", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.Funding Agency": "Funding Agency", + "submission.sections.describe.relationship-lookup.title.Funding Agency": "Finansman Kuruluşu", // "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", + "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Finansman", // "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", + "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Ana Organizasyon", // "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Toggle dropdown", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Toggle dropdown", + "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Açılır menüyü aç/kapat", // "submission.sections.describe.relationship-lookup.selection-tab.settings": "Settings", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.settings": "Settings", + "submission.sections.describe.relationship-lookup.selection-tab.settings": "Ayarlar", // "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Your selection is currently empty.", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Your selection is currently empty.", + "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Mevcut seçiminiz boş. ", // "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Selected Authors", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Selected Authors", + "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Seçili Yazarlar", // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Selected Journals", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Selected Journals", + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Seçili Makaleler", // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Selected Journal Volume", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Selected Journal Volume", + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Seçili Makale Ciltleri", // "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Selected Projects", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Selected Projects", + "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Seçili Projeler", // "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "Selected Publications", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "Selected Publications", + "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "Seçili Yayınlar", // "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Selected Authors", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Selected Authors", + "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Seçili Yazarlar", // "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Selected Organizational Units", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Selected Organizational Units", + "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Seçili Organizasyonlar", // "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Selected Data Packages", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Selected Data Packages", + "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Seçili Veri Paketleri", // "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", + "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Seçili Veri Dosyaları", // "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Selected Journals", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Selected Journals", + "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Seçili Makaleler", // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Selected Issue", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Selected Issue", + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Seçili Makale Konuları", // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Selected Journal Volume", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Selected Journal Volume", + "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Seçili Makale Ciltleri", // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "Selected Funding Agency", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "Selected Funding Agency", + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "Seçili Finansman Kuruluşu", // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Selected Funding", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Selected Funding", + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Seçili Finansman", // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Selected Issue", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Selected Issue", + "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Seçili Makale Konuları", // "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "Selected Organizational Unit", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "Selected Organizational Unit", + "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "Seçili Organizasyonlar", // "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "Search Results", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "Sonuçları Ara", // "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "Search Results", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "Sonuçları Ara", // "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "Search Results", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "Sonuçları Ara", // "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "Search Results", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "Sonuçları Ara", // "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "Search Results", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "Sonuçları Ara", // "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "Search Results", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "Sonuçları Ara", // "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Search Results", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Sonuçları Ara", // "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.", - // TODO New key - Add a translation - "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": "Bu kişi için \"{{ value }}\" ilerideki gönderilerde kullanılabilmek için Yeni İsim olarak kaydedilsin mi? Bunu yapmazsanız, yine de bu gönderim için kullanabilirsiniz .", // "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant", + "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Yeni İsim değişikliğini kaydet.", // "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "Use only for this submission", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "Use only for this submission", + "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "Sadece bu gönderim için kullan.", // "submission.sections.ccLicense.type": "License Type", - // TODO New key - Add a translation - "submission.sections.ccLicense.type": "License Type", + "submission.sections.ccLicense.type": "Lisans Türü", // "submission.sections.ccLicense.select": "Select a license type…", - // TODO New key - Add a translation - "submission.sections.ccLicense.select": "Select a license type…", + "submission.sections.ccLicense.select": "Lisans Türünü Seç…", // "submission.sections.ccLicense.change": "Change your license type…", - // TODO New key - Add a translation - "submission.sections.ccLicense.change": "Change your license type…", + "submission.sections.ccLicense.change": "Lisans Türünü Değiştir…", // "submission.sections.ccLicense.none": "No licenses available", - // TODO New key - Add a translation - "submission.sections.ccLicense.none": "No licenses available", + "submission.sections.ccLicense.none": "Lisans Mevcut Değil", // "submission.sections.ccLicense.option.select": "Select an option…", - // TODO New key - Add a translation - "submission.sections.ccLicense.option.select": "Select an option…", + "submission.sections.ccLicense.option.select": "Seçenek Seç…", // "submission.sections.ccLicense.link": "You’ve selected the following license:", - // TODO New key - Add a translation - "submission.sections.ccLicense.link": "You’ve selected the following license:", + "submission.sections.ccLicense.link": "Seçtiğiniz Lisans Türü:", // "submission.sections.ccLicense.confirmation": "I grant the license above", - // TODO New key - Add a translation - "submission.sections.ccLicense.confirmation": "I grant the license above", + "submission.sections.ccLicense.confirmation": "Yukarıdaki lisansı veriyorum", // "submission.sections.general.add-more": "Add more", - // TODO New key - Add a translation - "submission.sections.general.add-more": "Add more", + "submission.sections.general.add-more": "Ekle", // "submission.sections.general.collection": "Collection", - // TODO New key - Add a translation - "submission.sections.general.collection": "Collection", + "submission.sections.general.collection": "Koleksiyon", // "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", - // TODO New key - Add a translation - "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", + "submission.sections.general.deposit_error_notice": "Öğe gönderilirken bir sorun oluştu, lütfen daha sonra tekrar deneyin.", // "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", - // TODO New key - Add a translation - "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", + "submission.sections.general.deposit_success_notice": "Gönderim başarıyla yatırıldı.", // "submission.sections.general.discard_error_notice": "There was an issue when discarding the item, please try again later.", - // TODO New key - Add a translation - "submission.sections.general.discard_error_notice": "There was an issue when discarding the item, please try again later.", + "submission.sections.general.discard_error_notice": "Öğe gönderilirken bir sorun oluştu, lütfen daha sonra tekrar deneyin.", // "submission.sections.general.discard_success_notice": "Submission discarded successfully.", - // TODO New key - Add a translation - "submission.sections.general.discard_success_notice": "Submission discarded successfully.", + "submission.sections.general.discard_success_notice": "Gönderim başarıyla silindi.", // "submission.sections.general.metadata-extracted": "New metadata have been extracted and added to the {{sectionId}} section.", - // TODO New key - Add a translation - "submission.sections.general.metadata-extracted": "New metadata have been extracted and added to the {{sectionId}} section.", + "submission.sections.general.metadata-extracted": "Yeni meta veriler çıkarıldı ve {{sectionId}} bölümüne eklendi.", // "submission.sections.general.metadata-extracted-new-section": "New {{sectionId}} section has been added to submission.", - // TODO New key - Add a translation - "submission.sections.general.metadata-extracted-new-section": "New {{sectionId}} section has been added to submission.", + "submission.sections.general.metadata-extracted-new-section": "Gönderime yeni {{sectionId}} bölümü eklendi.", // "submission.sections.general.no-collection": "No collection found", - // TODO New key - Add a translation - "submission.sections.general.no-collection": "No collection found", + "submission.sections.general.no-collection": "Koleksiyon bulunamadı", // "submission.sections.general.no-sections": "No options available", - // TODO New key - Add a translation - "submission.sections.general.no-sections": "No options available", + "submission.sections.general.no-sections": "Seçenekler Bulunamadı.", // "submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.", - // TODO New key - Add a translation - "submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.", + "submission.sections.general.save_error_notice": "Öğe kaydedilirken bir sorun oluştu, lütfen daha sonra tekrar deneyin.", // "submission.sections.general.save_success_notice": "Submission saved successfully.", - // TODO New key - Add a translation - "submission.sections.general.save_success_notice": "Submission saved successfully.", + "submission.sections.general.save_success_notice": "Gönderim başarıyla kaydedildi.", // "submission.sections.general.search-collection": "Search for a collection", - // TODO New key - Add a translation - "submission.sections.general.search-collection": "Search for a collection", + "submission.sections.general.search-collection": "Koleksiyon ara", // "submission.sections.general.sections_not_valid": "There are incomplete sections.", - // TODO New key - Add a translation - "submission.sections.general.sections_not_valid": "There are incomplete sections.", + "submission.sections.general.sections_not_valid": "Eksik bölümler var.", // "submission.sections.submit.progressbar.CClicense": "Creative commons license", - // TODO New key - Add a translation - "submission.sections.submit.progressbar.CClicense": "Creative commons license", + "submission.sections.submit.progressbar.CClicense": "Yaratıcı Ortak Lisansları", // "submission.sections.submit.progressbar.describe.recycle": "Recycle", - // TODO New key - Add a translation - "submission.sections.submit.progressbar.describe.recycle": "Recycle", + "submission.sections.submit.progressbar.describe.recycle": "Geri Dönüştür", // "submission.sections.submit.progressbar.describe.stepcustom": "Describe", - // TODO New key - Add a translation - "submission.sections.submit.progressbar.describe.stepcustom": "Describe", + "submission.sections.submit.progressbar.describe.stepcustom": "Tanımla", // "submission.sections.submit.progressbar.describe.stepone": "Describe", - // TODO New key - Add a translation - "submission.sections.submit.progressbar.describe.stepone": "Describe", + "submission.sections.submit.progressbar.describe.stepone": "Tanımla", // "submission.sections.submit.progressbar.describe.steptwo": "Describe", - // TODO New key - Add a translation - "submission.sections.submit.progressbar.describe.steptwo": "Describe", + "submission.sections.submit.progressbar.describe.steptwo": "Tanımla", // "submission.sections.submit.progressbar.detect-duplicate": "Potential duplicates", - // TODO New key - Add a translation - "submission.sections.submit.progressbar.detect-duplicate": "Potential duplicates", + "submission.sections.submit.progressbar.detect-duplicate": "Olası Kopyalar", // "submission.sections.submit.progressbar.license": "Deposit license", - // TODO New key - Add a translation - "submission.sections.submit.progressbar.license": "Deposit license", + "submission.sections.submit.progressbar.license": "Lisansı Yerleştir", // "submission.sections.submit.progressbar.upload": "Upload files", - // TODO New key - Add a translation - "submission.sections.submit.progressbar.upload": "Upload files", + "submission.sections.submit.progressbar.upload": "Dosyaları yükle", // "submission.sections.upload.delete.confirm.cancel": "Cancel", - // TODO New key - Add a translation - "submission.sections.upload.delete.confirm.cancel": "Cancel", + "submission.sections.upload.delete.confirm.cancel": "İptal", // "submission.sections.upload.delete.confirm.info": "This operation can't be undone. Are you sure?", - // TODO New key - Add a translation - "submission.sections.upload.delete.confirm.info": "This operation can't be undone. Are you sure?", + "submission.sections.upload.delete.confirm.info": "Bu işlem geri alınamaz. Emin misin?", // "submission.sections.upload.delete.confirm.submit": "Yes, I'm sure", - // TODO New key - Add a translation - "submission.sections.upload.delete.confirm.submit": "Yes, I'm sure", + "submission.sections.upload.delete.confirm.submit": "Evet eminim.", // "submission.sections.upload.delete.confirm.title": "Delete bitstream", - // TODO New key - Add a translation - "submission.sections.upload.delete.confirm.title": "Delete bitstream", + "submission.sections.upload.delete.confirm.title": "Veri Akışını Sil", // "submission.sections.upload.delete.submit": "Delete", - // TODO New key - Add a translation - "submission.sections.upload.delete.submit": "Delete", + "submission.sections.upload.delete.submit": "Sil", // "submission.sections.upload.drop-message": "Drop files to attach them to the item", - // TODO New key - Add a translation - "submission.sections.upload.drop-message": "Drop files to attach them to the item", + "submission.sections.upload.drop-message": "Öğeye eklemek için dosyaları bırakın", // "submission.sections.upload.form.access-condition-label": "Access condition type", - // TODO New key - Add a translation - "submission.sections.upload.form.access-condition-label": "Access condition type", + "submission.sections.upload.form.access-condition-label": "Erişim Koşulu Türü", // "submission.sections.upload.form.date-required": "Date is required.", - // TODO New key - Add a translation - "submission.sections.upload.form.date-required": "Date is required.", + "submission.sections.upload.form.date-required": "Tarih gerekli.", // "submission.sections.upload.form.from-label": "Grant access from", - // TODO New key - Add a translation - "submission.sections.upload.form.from-label": "Grant access from", + "submission.sections.upload.form.from-label": "Şuradan erişim izni ver:", // "submission.sections.upload.form.from-placeholder": "From", - // TODO New key - Add a translation - "submission.sections.upload.form.from-placeholder": "From", + "submission.sections.upload.form.from-placeholder": "İtibaren", // "submission.sections.upload.form.group-label": "Group", - // TODO New key - Add a translation - "submission.sections.upload.form.group-label": "Group", + "submission.sections.upload.form.group-label": "Grup", // "submission.sections.upload.form.group-required": "Group is required.", - // TODO New key - Add a translation - "submission.sections.upload.form.group-required": "Group is required.", + "submission.sections.upload.form.group-required": "Grup gerekli.", // "submission.sections.upload.form.until-label": "Grant access until", - // TODO New key - Add a translation - "submission.sections.upload.form.until-label": "Grant access until", + "submission.sections.upload.form.until-label": "Şu tarihe kadar erişim izni ver:", // "submission.sections.upload.form.until-placeholder": "Until", - // TODO New key - Add a translation - "submission.sections.upload.form.until-placeholder": "Until", + "submission.sections.upload.form.until-placeholder": "Kadar", // "submission.sections.upload.header.policy.default.nolist": "Uploaded files in the {{collectionName}} collection will be accessible according to the following group(s):", - // TODO New key - Add a translation - "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}} koleksiyonuna yüklenen dosyalara aşağıdaki gruplara göre erişilebilir:", // "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):", - // TODO New key - Add a translation - "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}} koleksiyonuna yüklenen dosyalara, tek dosya için açıkça karar verilenlere ek olarak aşağıdaki gruplarla erişilebilir olacağını lütfen unutmayın:", // "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 just dragging & dropping them everywhere in the page", - // TODO New key - Add a translation - "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 just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Burada, o anda öğede bulunan tüm dosyaları bulacaksınız. Dosya meta verilerini güncelleyebilir ve koşullara erişebilir veya sayfanın her yerine sürükleyip bırakarak ek dosyalar yükleyebilirsiniz", // "submission.sections.upload.no-entry": "No", - // TODO New key - Add a translation - "submission.sections.upload.no-entry": "No", + "submission.sections.upload.no-entry": "Hayır", // "submission.sections.upload.no-file-uploaded": "No file uploaded yet.", - // TODO New key - Add a translation - "submission.sections.upload.no-file-uploaded": "No file uploaded yet.", + "submission.sections.upload.no-file-uploaded": "Henüz dosya yüklenmedi.", // "submission.sections.upload.save-metadata": "Save metadata", - // TODO New key - Add a translation - "submission.sections.upload.save-metadata": "Save metadata", + "submission.sections.upload.save-metadata": "Meta verileri kaydet", // "submission.sections.upload.undo": "Cancel", - // TODO New key - Add a translation - "submission.sections.upload.undo": "Cancel", + "submission.sections.upload.undo": "İptal", // "submission.sections.upload.upload-failed": "Upload failed", - // TODO New key - Add a translation - "submission.sections.upload.upload-failed": "Upload failed", + "submission.sections.upload.upload-failed": "Yükleme Başarısız", // "submission.sections.upload.upload-successful": "Upload successful", - // TODO New key - Add a translation - "submission.sections.upload.upload-successful": "Upload successful", + "submission.sections.upload.upload-successful": "Yükleme Başarılı", // "submission.submit.title": "Submission", - // TODO New key - Add a translation - "submission.submit.title": "Submission", + "submission.submit.title": "Gönder", // "submission.workflow.generic.delete": "Delete", - // TODO New key - Add a translation - "submission.workflow.generic.delete": "Delete", + "submission.workflow.generic.delete": "Sil", // "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", - // TODO New key - Add a translation - "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", + "submission.workflow.generic.delete-help": "Bu öğeyi atmak istiyorsanız, \"Sil\" öğesini seçin. Daha sonra onaylamanız istenecektir.", // "submission.workflow.generic.edit": "Edit", - // TODO New key - Add a translation - "submission.workflow.generic.edit": "Edit", + "submission.workflow.generic.edit": "Değiştir", // "submission.workflow.generic.edit-help": "Select this option to change the item's metadata.", - // TODO New key - Add a translation - "submission.workflow.generic.edit-help": "Select this option to change the item's metadata.", + "submission.workflow.generic.edit-help": "Öğenin meta verilerini değiştirmek için bu seçeneği belirleyin.", // "submission.workflow.generic.view": "View", - // TODO New key - Add a translation - "submission.workflow.generic.view": "View", + "submission.workflow.generic.view": "Göster", // "submission.workflow.generic.view-help": "Select this option to view the item's metadata.", - // TODO New key - Add a translation - "submission.workflow.generic.view-help": "Select this option to view the item's metadata.", + "submission.workflow.generic.view-help": "Öğenin meta verilerini görüntülemek için bu seçeneği belirleyin.", // "submission.workflow.tasks.claimed.approve": "Approve", - // TODO New key - Add a translation - "submission.workflow.tasks.claimed.approve": "Approve", + "submission.workflow.tasks.claimed.approve": "Kabul Et.", // "submission.workflow.tasks.claimed.approve_help": "If you have reviewed the item and it is suitable for inclusion in the collection, select \"Approve\".", - // TODO New key - Add a translation - "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": "Öğeyi incelediyseniz ve koleksiyona dahil edilmeye uygunsa, \"Onayla\"yı seçin.", // "submission.workflow.tasks.claimed.edit": "Edit", - // TODO New key - Add a translation - "submission.workflow.tasks.claimed.edit": "Edit", + "submission.workflow.tasks.claimed.edit": "Değiştir", // "submission.workflow.tasks.claimed.edit_help": "Select this option to change the item's metadata.", - // TODO New key - Add a translation - "submission.workflow.tasks.claimed.edit_help": "Select this option to change the item's metadata.", + "submission.workflow.tasks.claimed.edit_help": "Öğenin meta verilerini değiştirmek için bu seçeneği belirleyin.", // "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.", - // TODO New key - Add a translation - "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": "Lütfen gönderiyi reddetme nedeninizi aşağıdaki kutuya, gönderenin bir sorunu çözüp yeniden gönderip gönderemeyeceğini belirterek girin.", // "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", - // TODO New key - Add a translation - "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", + "submission.workflow.tasks.claimed.reject.reason.placeholder": "Reddetme nedenini açıklayın", // "submission.workflow.tasks.claimed.reject.reason.submit": "Reject item", - // TODO New key - Add a translation - "submission.workflow.tasks.claimed.reject.reason.submit": "Reject item", + "submission.workflow.tasks.claimed.reject.reason.submit": "Materyali Reddet", // "submission.workflow.tasks.claimed.reject.reason.title": "Reason", - // TODO New key - Add a translation - "submission.workflow.tasks.claimed.reject.reason.title": "Reason", + "submission.workflow.tasks.claimed.reject.reason.title": "Neden", // "submission.workflow.tasks.claimed.reject.submit": "Reject", - // TODO New key - Add a translation - "submission.workflow.tasks.claimed.reject.submit": "Reject", + "submission.workflow.tasks.claimed.reject.submit": "Kabul Etme", // "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.", - // TODO New key - Add a translation - "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": "Öğeyi incelediyseniz ve koleksiyona dahil edilmeye uygun olmadığını bulduysanız, \"Reddet\"i seçin. Ardından, öğenin neden uygun olmadığını ve gönderenin bir şeyi değiştirip yeniden göndermesi gerekip gerekmediğini belirten bir mesaj girmeniz istenecektir.", // "submission.workflow.tasks.claimed.return": "Return to pool", - // TODO New key - Add a translation - "submission.workflow.tasks.claimed.return": "Return to pool", + "submission.workflow.tasks.claimed.return": "Havuza Dön", // "submission.workflow.tasks.claimed.return_help": "Return the task to the pool so that another user may perform the task.", - // TODO New key - Add a translation - "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": "Başka bir kullanıcının görevi gerçekleştirebilmesi için görevi havuza geri döndürün.", // "submission.workflow.tasks.generic.error": "Error occurred during operation...", - // TODO New key - Add a translation - "submission.workflow.tasks.generic.error": "Error occurred during operation...", + "submission.workflow.tasks.generic.error": "İşlem sırasında hata oluştu...", // "submission.workflow.tasks.generic.processing": "Processing...", - // TODO New key - Add a translation - "submission.workflow.tasks.generic.processing": "Processing...", + "submission.workflow.tasks.generic.processing": "İşleniyor...", // "submission.workflow.tasks.generic.submitter": "Submitter", - // TODO New key - Add a translation - "submission.workflow.tasks.generic.submitter": "Submitter", + "submission.workflow.tasks.generic.submitter": "Gönderen", // "submission.workflow.tasks.generic.success": "Operation successful", - // TODO New key - Add a translation - "submission.workflow.tasks.generic.success": "Operation successful", + "submission.workflow.tasks.generic.success": "İşlem Başarılı", // "submission.workflow.tasks.pool.claim": "Claim", - // TODO New key - Add a translation - "submission.workflow.tasks.pool.claim": "Claim", + "submission.workflow.tasks.pool.claim": "Talep Et", // "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", - // TODO New key - Add a translation - "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", + "submission.workflow.tasks.pool.claim_help": "Bu görevi kendinize atayın.", // "submission.workflow.tasks.pool.hide-detail": "Hide detail", - // TODO New key - Add a translation - "submission.workflow.tasks.pool.hide-detail": "Hide detail", + "submission.workflow.tasks.pool.hide-detail": "Detayları gizle", // "submission.workflow.tasks.pool.show-detail": "Show detail", - // TODO New key - Add a translation - "submission.workflow.tasks.pool.show-detail": "Show detail", + "submission.workflow.tasks.pool.show-detail": "Detayaları göster", // "title": "DSpace", - // TODO New key - Add a translation "title": "DSpace", // "vocabulary-treeview.header": "Hierarchical tree view", - // TODO New key - Add a translation - "vocabulary-treeview.header": "Hierarchical tree view", + "vocabulary-treeview.header": "Hiyerarşik ağaç görünümü", // "vocabulary-treeview.load-more": "Load more", - // TODO New key - Add a translation - "vocabulary-treeview.load-more": "Load more", + "vocabulary-treeview.load-more": "Daha Fazla Yükle", // "vocabulary-treeview.search.form.reset": "Reset", - // TODO New key - Add a translation - "vocabulary-treeview.search.form.reset": "Reset", + "vocabulary-treeview.search.form.reset": "Sıfırla", // "vocabulary-treeview.search.form.search": "Search", - // TODO New key - Add a translation - "vocabulary-treeview.search.form.search": "Search", + "vocabulary-treeview.search.form.search": "Ara", // "vocabulary-treeview.search.no-result": "There were no items to show", - // TODO New key - Add a translation - "vocabulary-treeview.search.no-result": "There were no items to show", + "vocabulary-treeview.search.no-result": "Gösterilecek öğe yok", // "vocabulary-treeview.tree.description.nsi": "The Norwegian Science Index", - // TODO New key - Add a translation "vocabulary-treeview.tree.description.nsi": "The Norwegian Science Index", // "vocabulary-treeview.tree.description.srsc": "Research Subject Categories", - // TODO New key - Add a translation - "vocabulary-treeview.tree.description.srsc": "Research Subject Categories", + "vocabulary-treeview.tree.description.srsc": "Araştırma Konusu Kategorileri", // "uploader.browse": "browse", - // TODO New key - Add a translation - "uploader.browse": "browse", + "uploader.browse": "Tara", // "uploader.drag-message": "Drag & Drop your files here", - // TODO New key - Add a translation - "uploader.drag-message": "Drag & Drop your files here", + "uploader.drag-message": "Dosyalarınızı buraya sürükleyip bırakın", // "uploader.or": ", or ", - // TODO New key - Add a translation - "uploader.or": ", or ", + "uploader.or": ", veya", // "uploader.processing": "Processing", - // TODO New key - Add a translation - "uploader.processing": "Processing", + "uploader.processing": "İşleniyor", // "uploader.queue-length": "Queue length", - // TODO New key - Add a translation - "uploader.queue-length": "Queue length", + "uploader.queue-length": "Sıra Uzunluğu", // "virtual-metadata.delete-item.info": "Select the types for which you want to save the virtual metadata as real metadata", - // TODO New key - Add a translation - "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": "Sanal meta verileri gerçek meta veriler olarak kaydetmek istediğiniz türleri seçin", // "virtual-metadata.delete-item.modal-head": "The virtual metadata of this relation", - // TODO New key - Add a translation - "virtual-metadata.delete-item.modal-head": "The virtual metadata of this relation", + "virtual-metadata.delete-item.modal-head": "Bu ilişkinin sanal meta verileri", // "virtual-metadata.delete-relationship.modal-head": "Select the items for which you want to save the virtual metadata as real metadata", - // TODO New key - Add a translation - "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": "Sanal meta verilerini gerçek meta veriler olarak kaydetmek istediğiniz öğeleri seçin", // "workflowAdmin.search.results.head": "Administer Workflow", - // TODO New key - Add a translation - "workflowAdmin.search.results.head": "Administer Workflow", + "workflowAdmin.search.results.head": "İş Akışını Yönet", // "workflow-item.delete.notification.success.title": "Deleted", - // TODO New key - Add a translation - "workflow-item.delete.notification.success.title": "Deleted", + "workflow-item.delete.notification.success.title": "Silindi", // "workflow-item.delete.notification.success.content": "This workflow item was successfully deleted", - // TODO New key - Add a translation - "workflow-item.delete.notification.success.content": "This workflow item was successfully deleted", + "workflow-item.delete.notification.success.content": "Bu iş akışı öğesi başarıyla silindi", // "workflow-item.delete.notification.error.title": "Something went wrong", - // TODO New key - Add a translation - "workflow-item.delete.notification.error.title": "Something went wrong", + "workflow-item.delete.notification.error.title": "Bir şeyler yanlış gitti", // "workflow-item.delete.notification.error.content": "The workflow item could not be deleted", - // TODO New key - Add a translation - "workflow-item.delete.notification.error.content": "The workflow item could not be deleted", + "workflow-item.delete.notification.error.content": "İş akışı öğesi silinemedi", // "workflow-item.delete.title": "Delete workflow item", - // TODO New key - Add a translation - "workflow-item.delete.title": "Delete workflow item", + "workflow-item.delete.title": "İş akışı öğesini sil", // "workflow-item.delete.header": "Delete workflow item", - // TODO New key - Add a translation - "workflow-item.delete.header": "Delete workflow item", + "workflow-item.delete.header": "İş akışı öğesini sil", // "workflow-item.delete.button.cancel": "Cancel", - // TODO New key - Add a translation - "workflow-item.delete.button.cancel": "Cancel", + "workflow-item.delete.button.cancel": "İptal", // "workflow-item.delete.button.confirm": "Delete", - // TODO New key - Add a translation - "workflow-item.delete.button.confirm": "Delete", + "workflow-item.delete.button.confirm": "Sil", // "workflow-item.send-back.notification.success.title": "Sent back to submitter", - // TODO New key - Add a translation - "workflow-item.send-back.notification.success.title": "Sent back to submitter", + "workflow-item.send-back.notification.success.title": "Gönderene geri gönderildi", // "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", - // TODO New key - Add a translation - "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", + "workflow-item.send-back.notification.success.content": "Bu iş akışı öğesi, gönderene başarıyla geri gönderildi", // "workflow-item.send-back.notification.error.title": "Something went wrong", - // TODO New key - Add a translation - "workflow-item.send-back.notification.error.title": "Something went wrong", + "workflow-item.send-back.notification.error.title": "Bir şeyler yanlış gitti", // "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", - // TODO New key - Add a translation - "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": "İş akışı öğesi, gönderene geri gönderilemedi", // "workflow-item.send-back.title": "Send workflow item back to submitter", - // TODO New key - Add a translation - "workflow-item.send-back.title": "Send workflow item back to submitter", + "workflow-item.send-back.title": "İş akışı öğesini gönderene geri gönder", // "workflow-item.send-back.header": "Send workflow item back to submitter", - // TODO New key - Add a translation - "workflow-item.send-back.header": "Send workflow item back to submitter", + "workflow-item.send-back.header": "İş akışı öğesini gönderene geri gönder", // "workflow-item.send-back.button.cancel": "Cancel", - // TODO New key - Add a translation - "workflow-item.send-back.button.cancel": "Cancel", + "workflow-item.send-back.button.cancel": "İptal", // "workflow-item.send-back.button.confirm": "Send back" - // TODO New key - Add a translation - "workflow-item.send-back.button.confirm": "Send back" - + "workflow-item.send-back.button.confirm": "Geri Gönder" -} \ No newline at end of file +} From 143b7c3e0d541a85dc289a205bb33fe5d896a3c3 Mon Sep 17 00:00:00 2001 From: lotte Date: Wed, 16 Feb 2022 13:52:32 +0100 Subject: [PATCH 004/409] 87382: fixing circular dependencies --- .../admin-sidebar-section.component.ts | 4 +- .../admin-sidebar/admin-sidebar.component.ts | 3 +- ...andable-admin-sidebar-section.component.ts | 2 +- src/app/app.reducer.ts | 3 +- .../legacy-bitstream-url.resolver.spec.ts | 2 +- .../collection-item-mapper.component.spec.ts | 12 +- .../collection-page-routing.module.ts | 2 +- .../collection-page.component.ts | 2 +- .../collection-source.component.spec.ts | 2 +- .../collection-source.component.ts | 3 +- .../community-list-datasource.ts | 3 +- .../community-list-service.spec.ts | 3 +- .../community-list-service.ts | 31 +--- .../community-list.actions.ts | 2 +- .../community-list.reducer.ts | 2 +- .../community-list.component.spec.ts | 3 +- .../community-list.component.ts | 3 +- .../community-list-page/flat-node.model.ts | 22 +++ .../show-more-flat-node.model.ts | 6 + .../community-page-routing.module.ts | 2 +- .../community-page.component.ts | 3 +- src/app/core/auth/models/auth-status.model.ts | 2 +- .../auth/models/short-lived-token.model.ts | 2 +- .../core/cache/builders/build-decorators.ts | 4 +- .../remote-data-build.service.spec.ts | 3 +- .../builders/remote-data-build.service.ts | 7 +- src/app/core/cache/cacheable-object.model.ts | 22 +++ src/app/core/cache/object-cache.actions.ts | 2 +- src/app/core/cache/object-cache.reducer.ts | 36 +---- .../core/cache/object-cache.service.spec.ts | 2 +- src/app/core/cache/object-cache.service.ts | 5 +- src/app/core/cache/response.models.ts | 2 +- src/app/core/cache/typed-object.model.ts | 6 + src/app/core/config/models/config.model.ts | 2 +- .../base-response-parsing.service.spec.ts | 2 +- .../data/base-response-parsing.service.ts | 2 +- src/app/core/data/bitstream-data.service.ts | 2 +- .../data/bitstream-format-data.service.ts | 2 +- src/app/core/data/bundle-data.service.ts | 2 +- src/app/core/data/change-analyzer.ts | 2 +- src/app/core/data/collection-data.service.ts | 8 + src/app/core/data/comcol-data.service.spec.ts | 14 +- src/app/core/data/comcol-data.service.ts | 11 +- src/app/core/data/community-data.service.ts | 11 +- src/app/core/data/data.service.spec.ts | 2 +- src/app/core/data/data.service.ts | 2 +- .../data/default-change-analyzer.service.ts | 2 +- .../dspace-rest-response-parsing.service.ts | 2 +- .../endpoint-map-response-parsing.service.ts | 2 +- .../some-feature-authorization.guard.ts | 2 +- src/app/core/data/href-only-data.service.ts | 2 +- src/app/core/data/item-data.service.ts | 2 +- .../object-updates/field-change-type.model.ts | 8 + .../data/object-updates/field-update.model.ts | 10 ++ .../object-updates/field-updates.model.ts | 8 + .../data/object-updates/identifiable.model.ts | 6 + .../object-updates/object-updates.actions.ts | 18 +-- .../object-updates.reducer.spec.ts | 2 +- .../object-updates/object-updates.reducer.ts | 28 +--- .../object-updates.service.spec.ts | 2 +- .../object-updates/object-updates.service.ts | 6 +- .../metadata-patch-operation.service.spec.ts | 4 +- .../metadata-patch-operation.service.ts | 4 +- .../patch-operation.service.ts | 2 +- src/app/core/data/paginated-list.model.ts | 2 +- src/app/core/data/relationship.service.ts | 4 +- src/app/core/data/remote-data.ts | 18 +-- .../core/data/request-entry-state.model.ts | 88 +++++++++++ src/app/core/data/request-error.model.ts | 4 + src/app/core/data/request.effects.ts | 3 +- src/app/core/data/request.models.ts | 4 - src/app/core/data/request.reducer.spec.ts | 3 +- src/app/core/data/request.reducer.ts | 97 +----------- src/app/core/data/request.service.spec.ts | 3 +- src/app/core/data/request.service.ts | 3 +- src/app/core/data/root.model.ts | 2 +- .../abstract-end-user-agreement.guard.ts | 2 +- src/app/core/index/index-name.model.ts | 17 +++ src/app/core/index/index.actions.ts | 2 +- src/app/core/index/index.effects.spec.ts | 2 +- src/app/core/index/index.effects.ts | 2 +- src/app/core/index/index.reducer.spec.ts | 3 +- src/app/core/index/index.reducer.ts | 27 +--- src/app/core/index/index.selectors.ts | 3 +- .../models/resource-policy.model.ts | 2 +- src/app/core/shared/authorized.operators.ts | 91 ++++++++++++ src/app/core/shared/bitstream-format.model.ts | 2 +- .../core/shared/browse-definition.model.ts | 2 +- src/app/core/shared/browse-entry.model.ts | 2 +- .../shared/configuration-property.model.ts | 2 +- src/app/core/shared/content-source.model.ts | 2 +- src/app/core/shared/dspace-object.model.ts | 2 +- src/app/core/shared/external-source.model.ts | 2 +- .../item-relationships/item-type.model.ts | 2 +- .../relationship-type.model.ts | 2 +- .../item-relationships/relationship.model.ts | 2 +- src/app/core/shared/operators.spec.ts | 9 +- src/app/core/shared/operators.ts | 136 +---------------- src/app/core/shared/request.operators.ts | 32 ++++ .../search-configuration.service.spec.ts | 135 ++++++++++++++++- .../search/search-configuration.service.ts | 140 ++++++++++++++++-- .../search-filters/search-config.model.ts | 2 +- .../core/shared/search/search.service.spec.ts | 99 ------------- src/app/core/shared/search/search.service.ts | 94 ------------ .../models/submission-object.model.ts | 2 +- .../submission-object-data.service.ts | 2 +- .../vocabularies/models/vocabulary.model.ts | 2 +- .../core/tasks/models/task-object.model.ts | 2 +- src/app/core/tasks/tasks.service.ts | 2 +- src/app/core/utilities/equals.decorators.ts | 53 ++++++- src/app/core/utilities/equatable.spec.ts | 3 +- src/app/core/utilities/equatable.ts | 52 ------- .../header-navbar-wrapper.component.ts | 2 +- src/app/header/header.component.ts | 2 +- src/app/home-page/home-page-routing.module.ts | 2 +- .../abstract-item-update.component.ts | 6 +- .../item-bitstreams.component.spec.ts | 2 +- .../item-bitstreams.component.ts | 8 +- .../item-edit-bitstream.component.ts | 4 +- .../edit-in-place-field.component.spec.ts | 2 +- .../edit-in-place-field.component.ts | 4 +- .../item-metadata.component.spec.ts | 2 +- .../edit-relationship-list.component.spec.ts | 2 +- .../edit-relationship-list.component.ts | 6 +- .../edit-relationship.component.spec.ts | 2 +- .../edit-relationship.component.ts | 4 +- .../item-relationships.component.spec.ts | 2 +- .../item-relationships.component.ts | 6 +- src/app/item-page/item-page-routing.module.ts | 2 +- .../item-page/simple/item-page.component.ts | 3 +- .../my-dspace-configuration.service.spec.ts | 13 +- .../my-dspace-configuration.service.ts | 16 +- .../my-dspace-page.component.spec.ts | 24 ++- .../my-dspace-page.component.ts | 2 +- .../expandable-navbar-section.component.ts | 2 +- .../navbar-section.component.ts | 2 +- src/app/navbar/navbar.component.ts | 3 +- src/app/navbar/navbar.effects.spec.ts | 2 +- src/app/navbar/navbar.effects.ts | 4 +- .../detail/process-detail.component.ts | 2 +- .../process-page/processes/process.model.ts | 2 +- src/app/process-page/scripts/script.model.ts | 2 +- src/app/root/root.component.ts | 2 +- src/app/search-page/search.component.spec.ts | 10 +- src/app/search-page/search.component.ts | 2 +- .../bitstream-download-page.component.ts | 3 +- ...ynamic-form-control-container.component.ts | 2 +- ...xisting-metadata-list-element.component.ts | 2 - src/app/shared/menu/initial-menus-state.ts | 18 +-- src/app/shared/menu/menu-id.model.ts | 7 + src/app/shared/menu/menu-item-type.model.ts | 6 + src/app/shared/menu/menu-item.decorator.ts | 2 +- .../menu-item/link-menu-item.component.ts | 2 +- .../menu/menu-item/models/altmetric.model.ts | 2 +- .../menu/menu-item/models/link.model.ts | 2 +- .../menu/menu-item/models/menu-item.model.ts | 2 +- .../menu/menu-item/models/onclick.model.ts | 2 +- .../menu/menu-item/models/search.model.ts | 2 +- .../menu/menu-item/models/text.model.ts | 2 +- .../menu-item/onclick-menu-item.component.ts | 2 +- .../menu-item/text-menu-item.component.ts | 2 +- .../shared/menu/menu-section-Index.model.ts | 6 + src/app/shared/menu/menu-section.decorator.ts | 2 +- src/app/shared/menu/menu-section.model.ts | 15 ++ .../menu-section.component.spec.ts | 2 +- .../menu-section/menu-section.component.ts | 5 +- src/app/shared/menu/menu-sections.model.ts | 8 + src/app/shared/menu/menu-state.model.ts | 15 ++ src/app/shared/menu/menu.actions.ts | 4 +- src/app/shared/menu/menu.component.spec.ts | 4 +- src/app/shared/menu/menu.component.ts | 4 +- src/app/shared/menu/menu.effects.spec.ts | 5 +- src/app/shared/menu/menu.effects.ts | 4 +- src/app/shared/menu/menu.reducer.spec.ts | 6 +- src/app/shared/menu/menu.reducer.ts | 56 +------ src/app/shared/menu/menu.service.spec.ts | 5 +- src/app/shared/menu/menu.service.ts | 6 +- src/app/shared/menu/menus-state.model.ts | 9 ++ .../mocks/remote-data-build.service.mock.ts | 6 +- .../mydspace-actions-service.factory.ts | 2 +- .../shared/listable-object.model.ts | 2 +- ...nated-drag-and-drop-list.component.spec.ts | 2 +- ...-paginated-drag-and-drop-list.component.ts | 3 +- src/app/shared/remote-data.utils.ts | 2 +- .../search/facet-config-response.model.ts | 2 +- .../search/search-filter-config.model.ts | 2 +- .../search-filters.component.spec.ts | 2 - .../search-filters.component.ts | 2 +- src/app/shared/testing/menu-service.stub.ts | 4 +- .../search-configuration-service.stub.ts | 22 +++ src/app/shared/testing/utils.test.ts | 3 +- .../statistics-page.component.ts | 4 +- .../statistics/statistics-endpoint.model.ts | 2 +- .../edit/submission-edit.component.ts | 2 +- .../form/submission-form.component.ts | 3 +- .../objects/section-visibility.model.ts | 7 + .../objects/submission-error.model.ts | 8 + .../objects/submission-objects.actions.ts | 4 +- .../objects/submission-objects.effects.ts | 4 +- .../objects/submission-objects.reducer.ts | 108 +------------- .../objects/submission-section-error.model.ts | 14 ++ .../submission-section-object.model.ts | 79 ++++++++++ .../form/section-form.component.spec.ts | 2 +- .../sections/form/section-form.component.ts | 3 +- .../sections/models/section-data.model.ts | 2 +- .../submission/sections/sections.directive.ts | 2 +- .../sections/sections.service.spec.ts | 2 +- .../submission/sections/sections.service.ts | 6 +- src/app/submission/selectors.ts | 3 +- src/app/submission/submission.service.ts | 6 +- 210 files changed, 1192 insertions(+), 1033 deletions(-) create mode 100644 src/app/community-list-page/flat-node.model.ts create mode 100644 src/app/community-list-page/show-more-flat-node.model.ts create mode 100644 src/app/core/cache/cacheable-object.model.ts create mode 100644 src/app/core/cache/typed-object.model.ts create mode 100644 src/app/core/data/object-updates/field-change-type.model.ts create mode 100644 src/app/core/data/object-updates/field-update.model.ts create mode 100644 src/app/core/data/object-updates/field-updates.model.ts create mode 100644 src/app/core/data/object-updates/identifiable.model.ts create mode 100644 src/app/core/data/request-entry-state.model.ts create mode 100644 src/app/core/data/request-error.model.ts create mode 100644 src/app/core/index/index-name.model.ts create mode 100644 src/app/core/shared/authorized.operators.ts create mode 100644 src/app/core/shared/request.operators.ts delete mode 100644 src/app/core/utilities/equatable.ts create mode 100644 src/app/shared/menu/menu-id.model.ts create mode 100644 src/app/shared/menu/menu-item-type.model.ts create mode 100644 src/app/shared/menu/menu-section-Index.model.ts create mode 100644 src/app/shared/menu/menu-section.model.ts create mode 100644 src/app/shared/menu/menu-sections.model.ts create mode 100644 src/app/shared/menu/menu-state.model.ts create mode 100644 src/app/shared/menu/menus-state.model.ts create mode 100644 src/app/submission/objects/section-visibility.model.ts create mode 100644 src/app/submission/objects/submission-error.model.ts create mode 100644 src/app/submission/objects/submission-section-error.model.ts create mode 100644 src/app/submission/objects/submission-section-object.model.ts diff --git a/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts b/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts index a19a1f95e4a..ac90df07fd8 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts @@ -1,10 +1,10 @@ import { Component, Inject, Injector, OnInit } from '@angular/core'; import { MenuSectionComponent } from '../../../shared/menu/menu-section/menu-section.component'; -import { MenuID } from '../../../shared/menu/initial-menus-state'; import { MenuService } from '../../../shared/menu/menu.service'; import { rendersSectionForMenu } from '../../../shared/menu/menu-section.decorator'; import { LinkMenuItemModel } from '../../../shared/menu/menu-item/models/link.model'; -import { MenuSection } from '../../../shared/menu/menu.reducer'; +import { MenuSection } from '../../../shared/menu/menu-section.model'; +import { MenuID } from '../../../shared/menu/menu-id.model'; /** * Represents a non-expandable section in the admin sidebar diff --git a/src/app/admin/admin-sidebar/admin-sidebar.component.ts b/src/app/admin/admin-sidebar/admin-sidebar.component.ts index 53a9ecb2abe..255678e4133 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar.component.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar.component.ts @@ -12,7 +12,6 @@ import { EditCollectionSelectorComponent } from '../../shared/dso-selector/modal import { EditCommunitySelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component'; import { EditItemSelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component'; import { ExportMetadataSelectorComponent } from '../../shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component'; -import { MenuID, MenuItemType } from '../../shared/menu/initial-menus-state'; import { LinkMenuItemModel } from '../../shared/menu/menu-item/models/link.model'; import { OnClickMenuItemModel } from '../../shared/menu/menu-item/models/onclick.model'; import { TextMenuItemModel } from '../../shared/menu/menu-item/models/text.model'; @@ -21,6 +20,8 @@ import { MenuService } from '../../shared/menu/menu.service'; import { CSSVariableService } from '../../shared/sass-helper/sass-helper.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../core/data/feature-authorization/feature-id'; +import { MenuID } from '../../shared/menu/menu-id.model'; +import { MenuItemType } from '../../shared/menu/menu-item-type.model'; /** * Component representing the admin sidebar diff --git a/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.ts b/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.ts index 112560de16e..7cf39a5b6ef 100644 --- a/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.ts +++ b/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.ts @@ -4,11 +4,11 @@ import { AdminSidebarSectionComponent } from '../admin-sidebar-section/admin-sid import { slide } from '../../../shared/animations/slide'; import { CSSVariableService } from '../../../shared/sass-helper/sass-helper.service'; import { bgColor } from '../../../shared/animations/bgColor'; -import { MenuID } from '../../../shared/menu/initial-menus-state'; import { MenuService } from '../../../shared/menu/menu.service'; import { combineLatest as combineLatestObservable, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { rendersSectionForMenu } from '../../../shared/menu/menu-section.decorator'; +import { MenuID } from '../../../shared/menu/menu-id.model'; /** * Represents a expandable section in the sidebar diff --git a/src/app/app.reducer.ts b/src/app/app.reducer.ts index a02095d8343..04ef9d4c133 100644 --- a/src/app/app.reducer.ts +++ b/src/app/app.reducer.ts @@ -22,7 +22,7 @@ import { nameVariantReducer } from './shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/name-variant.reducer'; import { formReducer, FormState } from './shared/form/form.reducer'; -import { menusReducer, MenusState } from './shared/menu/menu.reducer'; +import { menusReducer} from './shared/menu/menu.reducer'; import { notificationsReducer, NotificationsState @@ -49,6 +49,7 @@ import { import { sidebarReducer, SidebarState } from './shared/sidebar/sidebar.reducer'; import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer'; import { ThemeState, themeReducer } from './shared/theme-support/theme.reducer'; +import { MenusState } from './shared/menu/menus-state.model'; export interface AppState { router: fromRouter.RouterReducerState; diff --git a/src/app/bitstream-page/legacy-bitstream-url.resolver.spec.ts b/src/app/bitstream-page/legacy-bitstream-url.resolver.spec.ts index 25e245c5b7e..045582cb26e 100644 --- a/src/app/bitstream-page/legacy-bitstream-url.resolver.spec.ts +++ b/src/app/bitstream-page/legacy-bitstream-url.resolver.spec.ts @@ -2,8 +2,8 @@ import { LegacyBitstreamUrlResolver } from './legacy-bitstream-url.resolver'; import { of as observableOf, EMPTY } from 'rxjs'; import { BitstreamDataService } from '../core/data/bitstream-data.service'; import { RemoteData } from '../core/data/remote-data'; -import { RequestEntryState } from '../core/data/request.reducer'; import { TestScheduler } from 'rxjs/testing'; +import { RequestEntryState } from '../core/data/request-entry-state.model'; describe(`LegacyBitstreamUrlResolver`, () => { let resolver: LegacyBitstreamUrlResolver; diff --git a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts index 5ae1445ceff..30ae2850598 100644 --- a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts +++ b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts @@ -16,7 +16,7 @@ import { Collection } from '../../core/shared/collection.model'; import { RemoteData } from '../../core/data/remote-data'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { EventEmitter } from '@angular/core'; +import { ChangeDetectionStrategy, EventEmitter } from '@angular/core'; import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub'; import { By } from '@angular/platform-browser'; @@ -41,6 +41,8 @@ import { } from '../../shared/remote-data.utils'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; +import { MyDSpacePageComponent, SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component'; +import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; describe('CollectionItemMapperComponent', () => { let comp: CollectionItemMapperComponent; @@ -159,6 +161,14 @@ describe('CollectionItemMapperComponent', () => { { provide: RouteService, useValue: routeServiceStub }, { provide: AuthorizationDataService, useValue: authorizationDataService } ] + }).overrideComponent(CollectionItemMapperComponent, { + set: { + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationServiceStub + } + ] } }).compileComponents(); })); diff --git a/src/app/collection-page/collection-page-routing.module.ts b/src/app/collection-page/collection-page-routing.module.ts index 5879e523af7..29e342f1408 100644 --- a/src/app/collection-page/collection-page-routing.module.ts +++ b/src/app/collection-page/collection-page-routing.module.ts @@ -18,9 +18,9 @@ import { COLLECTION_CREATE_PATH } from './collection-page-routing-paths'; import { CollectionPageAdministratorGuard } from './collection-page-administrator.guard'; -import { MenuItemType } from '../shared/menu/initial-menus-state'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedCollectionPageComponent } from './themed-collection-page.component'; +import { MenuItemType } from '../shared/menu/menu-item-type.model'; @NgModule({ imports: [ diff --git a/src/app/collection-page/collection-page.component.ts b/src/app/collection-page/collection-page.component.ts index 366e1da7b1c..5753aced0b3 100644 --- a/src/app/collection-page/collection-page.component.ts +++ b/src/app/collection-page/collection-page.component.ts @@ -21,7 +21,6 @@ import { Item } from '../core/shared/item.model'; import { getAllSucceededRemoteDataPayload, getFirstSucceededRemoteData, - redirectOn4xx, toDSpaceObjectListRD } from '../core/shared/operators'; @@ -33,6 +32,7 @@ import { PaginationService } from '../core/pagination/pagination.service'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../core/data/feature-authorization/feature-id'; import { getCollectionPageRoute } from './collection-page-routing-paths'; +import { redirectOn4xx } from '../core/shared/authorized.operators'; @Component({ selector: 'ds-collection-page', diff --git a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.spec.ts b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.spec.ts index 869238b9569..ddee57afb41 100644 --- a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.spec.ts +++ b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.spec.ts @@ -9,7 +9,6 @@ import { ContentSource, ContentSourceHarvestType } from '../../../core/shared/co import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; import { INotification, Notification } from '../../../shared/notifications/models/notification.model'; import { NotificationType } from '../../../shared/notifications/models/notification-type'; -import { FieldUpdate } from '../../../core/data/object-updates/object-updates.reducer'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { DynamicFormControlModel, DynamicFormService } from '@ng-dynamic-forms/core'; import { hasValue } from '../../../shared/empty.util'; @@ -20,6 +19,7 @@ import { Collection } from '../../../core/shared/collection.model'; import { CollectionDataService } from '../../../core/data/collection-data.service'; import { RequestService } from '../../../core/data/request.service'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; +import { FieldUpdate } from '../../../core/data/object-updates/field-update.model'; const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info'); const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning'); diff --git a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts index c4b42d028dc..0d3d48e3598 100644 --- a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts +++ b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.ts @@ -23,7 +23,6 @@ import { RemoteData } from '../../../core/data/remote-data'; import { Collection } from '../../../core/shared/collection.model'; import { first, map, switchMap, take } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; -import { FieldUpdate, FieldUpdates } from '../../../core/data/object-updates/object-updates.reducer'; import { cloneDeep } from 'lodash'; import { CollectionDataService } from '../../../core/data/collection-data.service'; import { getFirstSucceededRemoteData, getFirstCompletedRemoteData } from '../../../core/shared/operators'; @@ -31,6 +30,8 @@ import { MetadataConfig } from '../../../core/shared/metadata-config.model'; import { INotification } from '../../../shared/notifications/models/notification.model'; import { RequestService } from '../../../core/data/request.service'; import { environment } from '../../../../environments/environment'; +import { FieldUpdate } from '../../../core/data/object-updates/field-update.model'; +import { FieldUpdates } from '../../../core/data/object-updates/field-updates.model'; /** * Component for managing the content source of the collection diff --git a/src/app/community-list-page/community-list-datasource.ts b/src/app/community-list-page/community-list-datasource.ts index 80ee51cd346..f234125373b 100644 --- a/src/app/community-list-page/community-list-datasource.ts +++ b/src/app/community-list-page/community-list-datasource.ts @@ -1,10 +1,11 @@ import { Subscription } from 'rxjs/internal/Subscription'; import { FindListOptions } from '../core/data/request.models'; import { hasValue } from '../shared/empty.util'; -import { CommunityListService, FlatNode } from './community-list-service'; +import { CommunityListService} from './community-list-service'; import { CollectionViewer, DataSource } from '@angular/cdk/collections'; import { BehaviorSubject, Observable, } from 'rxjs'; import { finalize } from 'rxjs/operators'; +import { FlatNode } from './flat-node.model'; /** * DataSource object needed by a CDK Tree to render its nodes. diff --git a/src/app/community-list-page/community-list-service.spec.ts b/src/app/community-list-page/community-list-service.spec.ts index fe53a982579..f0e69128267 100644 --- a/src/app/community-list-page/community-list-service.spec.ts +++ b/src/app/community-list-page/community-list-service.spec.ts @@ -7,13 +7,14 @@ import { SortDirection, SortOptions } from '../core/cache/models/sort-options.mo import { buildPaginatedList } from '../core/data/paginated-list.model'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils'; import { StoreMock } from '../shared/testing/store.mock'; -import { CommunityListService, FlatNode, toFlatNode } from './community-list-service'; +import { CommunityListService, toFlatNode } from './community-list-service'; import { CollectionDataService } from '../core/data/collection-data.service'; import { CommunityDataService } from '../core/data/community-data.service'; import { Community } from '../core/shared/community.model'; import { Collection } from '../core/shared/collection.model'; import { FindListOptions } from '../core/data/request.models'; import { PageInfo } from '../core/shared/page-info.model'; +import { FlatNode } from './flat-node.model'; describe('CommunityListService', () => { let store: StoreMock; diff --git a/src/app/community-list-page/community-list-service.ts b/src/app/community-list-page/community-list-service.ts index 76d33585da8..b5b6ffa3f50 100644 --- a/src/app/community-list-page/community-list-service.ts +++ b/src/app/community-list-page/community-list-service.ts @@ -12,39 +12,16 @@ import { Collection } from '../core/shared/collection.model'; import { PageInfo } from '../core/shared/page-info.model'; import { hasValue, isNotEmpty } from '../shared/empty.util'; import { RemoteData } from '../core/data/remote-data'; -import { PaginatedList, buildPaginatedList } from '../core/data/paginated-list.model'; +import { buildPaginatedList, PaginatedList } from '../core/data/paginated-list.model'; import { CollectionDataService } from '../core/data/collection-data.service'; import { CommunityListSaveAction } from './community-list.actions'; import { CommunityListState } from './community-list.reducer'; import { getCommunityPageRoute } from '../community-page/community-page-routing-paths'; import { getCollectionPageRoute } from '../collection-page/collection-page-routing-paths'; -import { getFirstSucceededRemoteData, getFirstCompletedRemoteData } from '../core/shared/operators'; +import { getFirstCompletedRemoteData, getFirstSucceededRemoteData } from '../core/shared/operators'; import { followLink } from '../shared/utils/follow-link-config.model'; - -/** - * Each node in the tree is represented by a flatNode which contains info about the node itself and its position and - * state in the tree. There are nodes representing communities, collections and show more links. - */ -export interface FlatNode { - isExpandable$: Observable; - name: string; - id: string; - level: number; - isExpanded?: boolean; - parent?: FlatNode; - payload: Community | Collection | ShowMoreFlatNode; - isShowMoreNode: boolean; - route?: string; - currentCommunityPage?: number; - currentCollectionPage?: number; -} - -/** - * The show more links in the community tree are also represented by a flatNode so we know where in - * the tree it should be rendered an who its parent is (needed for the action resulting in clicking this link) - */ -export class ShowMoreFlatNode { -} +import { FlatNode } from './flat-node.model'; +import { ShowMoreFlatNode } from './show-more-flat-node.model'; // Helper method to combine an flatten an array of observables of flatNode arrays export const combineAndFlatten = (obsList: Observable[]): Observable => diff --git a/src/app/community-list-page/community-list.actions.ts b/src/app/community-list-page/community-list.actions.ts index 1d2f732ac47..8e8d6d87cf2 100644 --- a/src/app/community-list-page/community-list.actions.ts +++ b/src/app/community-list-page/community-list.actions.ts @@ -1,6 +1,6 @@ import { Action } from '@ngrx/store'; import { type } from '../shared/ngrx/type'; -import { FlatNode } from './community-list-service'; +import { FlatNode } from './flat-node.model'; /** * All the action types of the community-list diff --git a/src/app/community-list-page/community-list.reducer.ts b/src/app/community-list-page/community-list.reducer.ts index 236201b3537..99c8350cf4e 100644 --- a/src/app/community-list-page/community-list.reducer.ts +++ b/src/app/community-list-page/community-list.reducer.ts @@ -1,5 +1,5 @@ -import { FlatNode } from './community-list-service'; import { CommunityListActions, CommunityListActionTypes, CommunityListSaveAction } from './community-list.actions'; +import { FlatNode } from './flat-node.model'; /** * States we wish to put in store concerning the community list diff --git a/src/app/community-list-page/community-list/community-list.component.spec.ts b/src/app/community-list-page/community-list/community-list.component.spec.ts index 1f020b77440..575edf14e87 100644 --- a/src/app/community-list-page/community-list/community-list.component.spec.ts +++ b/src/app/community-list-page/community-list/community-list.component.spec.ts @@ -1,7 +1,7 @@ import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { CommunityListComponent } from './community-list.component'; -import { CommunityListService, FlatNode, showMoreFlatNode, toFlatNode } from '../community-list-service'; +import { CommunityListService, showMoreFlatNode, toFlatNode } from '../community-list-service'; import { CdkTreeModule } from '@angular/cdk/tree'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; @@ -15,6 +15,7 @@ import { Collection } from '../../core/shared/collection.model'; import { of as observableOf } from 'rxjs'; import { By } from '@angular/platform-browser'; import { isEmpty, isNotEmpty } from '../../shared/empty.util'; +import { FlatNode } from '../flat-node.model'; describe('CommunityListComponent', () => { let component: CommunityListComponent; diff --git a/src/app/community-list-page/community-list/community-list.component.ts b/src/app/community-list-page/community-list/community-list.component.ts index 49065c5ec5b..d92c1c38602 100644 --- a/src/app/community-list-page/community-list/community-list.component.ts +++ b/src/app/community-list-page/community-list/community-list.component.ts @@ -2,10 +2,11 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { take } from 'rxjs/operators'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { FindListOptions } from '../../core/data/request.models'; -import { CommunityListService, FlatNode } from '../community-list-service'; +import { CommunityListService} from '../community-list-service'; import { CommunityListDatasource } from '../community-list-datasource'; import { FlatTreeControl } from '@angular/cdk/tree'; import { isEmpty } from '../../shared/empty.util'; +import { FlatNode } from '../flat-node.model'; /** * A tree-structured list of nodes representing the communities, their subCommunities and collections. diff --git a/src/app/community-list-page/flat-node.model.ts b/src/app/community-list-page/flat-node.model.ts new file mode 100644 index 00000000000..0aabbeb4891 --- /dev/null +++ b/src/app/community-list-page/flat-node.model.ts @@ -0,0 +1,22 @@ +import { Observable } from 'rxjs'; +import { Community } from '../core/shared/community.model'; +import { Collection } from '../core/shared/collection.model'; +import { ShowMoreFlatNode } from './show-more-flat-node.model'; + +/** + * Each node in the tree is represented by a flatNode which contains info about the node itself and its position and + * state in the tree. There are nodes representing communities, collections and show more links. + */ +export interface FlatNode { + isExpandable$: Observable; + name: string; + id: string; + level: number; + isExpanded?: boolean; + parent?: FlatNode; + payload: Community | Collection | ShowMoreFlatNode; + isShowMoreNode: boolean; + route?: string; + currentCommunityPage?: number; + currentCollectionPage?: number; +} diff --git a/src/app/community-list-page/show-more-flat-node.model.ts b/src/app/community-list-page/show-more-flat-node.model.ts new file mode 100644 index 00000000000..801c9e7388a --- /dev/null +++ b/src/app/community-list-page/show-more-flat-node.model.ts @@ -0,0 +1,6 @@ +/** + * The show more links in the community tree are also represented by a flatNode so we know where in + * the tree it should be rendered an who its parent is (needed for the action resulting in clicking this link) + */ +export class ShowMoreFlatNode { +} diff --git a/src/app/community-page/community-page-routing.module.ts b/src/app/community-page/community-page-routing.module.ts index ad1b1fd2f20..25326448a8e 100644 --- a/src/app/community-page/community-page-routing.module.ts +++ b/src/app/community-page/community-page-routing.module.ts @@ -11,9 +11,9 @@ import { DSOBreadcrumbsService } from '../core/breadcrumbs/dso-breadcrumbs.servi import { LinkService } from '../core/cache/builders/link.service'; import { COMMUNITY_EDIT_PATH, COMMUNITY_CREATE_PATH } from './community-page-routing-paths'; import { CommunityPageAdministratorGuard } from './community-page-administrator.guard'; -import { MenuItemType } from '../shared/menu/initial-menus-state'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedCommunityPageComponent } from './themed-community-page.component'; +import { MenuItemType } from '../shared/menu/menu-item-type.model'; @NgModule({ imports: [ diff --git a/src/app/community-page/community-page.component.ts b/src/app/community-page/community-page.component.ts index 70259a599bc..b1a0cfc9466 100644 --- a/src/app/community-page/community-page.component.ts +++ b/src/app/community-page/community-page.component.ts @@ -13,11 +13,12 @@ import { MetadataService } from '../core/metadata/metadata.service'; import { fadeInOut } from '../shared/animations/fade'; import { hasValue } from '../shared/empty.util'; -import { getAllSucceededRemoteDataPayload, redirectOn4xx } from '../core/shared/operators'; +import { getAllSucceededRemoteDataPayload} from '../core/shared/operators'; import { AuthService } from '../core/auth/auth.service'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../core/data/feature-authorization/feature-id'; import { getCommunityPageRoute } from './community-page-routing-paths'; +import { redirectOn4xx } from '../core/shared/authorized.operators'; @Component({ selector: 'ds-community-page', diff --git a/src/app/core/auth/models/auth-status.model.ts b/src/app/core/auth/models/auth-status.model.ts index 197c025407a..fbe6ed6476c 100644 --- a/src/app/core/auth/models/auth-status.model.ts +++ b/src/app/core/auth/models/auth-status.model.ts @@ -2,7 +2,6 @@ import { autoserialize, deserialize, deserializeAs } from 'cerialize'; import { Observable } from 'rxjs'; import { link, typedObject } from '../../cache/builders/build-decorators'; import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer'; -import { CacheableObject } from '../../cache/object-cache.reducer'; import { RemoteData } from '../../data/remote-data'; import { EPerson } from '../../eperson/models/eperson.model'; import { EPERSON } from '../../eperson/models/eperson.resource-type'; @@ -13,6 +12,7 @@ import { AuthError } from './auth-error.model'; import { AUTH_STATUS } from './auth-status.resource-type'; import { AuthTokenInfo } from './auth-token-info.model'; import { AuthMethod } from './auth.method'; +import { CacheableObject } from '../../cache/cacheable-object.model'; /** * Object that represents the authenticated status of a user diff --git a/src/app/core/auth/models/short-lived-token.model.ts b/src/app/core/auth/models/short-lived-token.model.ts index 118c724328f..3786bd8e6a0 100644 --- a/src/app/core/auth/models/short-lived-token.model.ts +++ b/src/app/core/auth/models/short-lived-token.model.ts @@ -1,10 +1,10 @@ -import { CacheableObject } from '../../cache/object-cache.reducer'; import { typedObject } from '../../cache/builders/build-decorators'; import { excludeFromEquals } from '../../utilities/equals.decorators'; import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; import { ResourceType } from '../../shared/resource-type'; import { SHORT_LIVED_TOKEN } from './short-lived-token.resource-type'; import { HALLink } from '../../shared/hal-link.model'; +import { CacheableObject } from '../../cache/cacheable-object.model'; /** * A short-lived token that can be used to authenticate a rest request diff --git a/src/app/core/cache/builders/build-decorators.ts b/src/app/core/cache/builders/build-decorators.ts index b561ababde0..193eeb57e8a 100644 --- a/src/app/core/cache/builders/build-decorators.ts +++ b/src/app/core/cache/builders/build-decorators.ts @@ -4,11 +4,11 @@ import { GenericConstructor } from '../../shared/generic-constructor'; import { HALResource } from '../../shared/hal-resource.model'; import { ResourceType } from '../../shared/resource-type'; import { - CacheableObject, - TypedObject, getResourceTypeValueFor } from '../object-cache.reducer'; import { InjectionToken } from '@angular/core'; +import { CacheableObject } from '../cacheable-object.model'; +import { TypedObject } from '../typed-object.model'; export const DATA_SERVICE_FACTORY = new InjectionToken<(resourceType: ResourceType) => GenericConstructor>('getDataServiceFor', { providedIn: 'root', diff --git a/src/app/core/cache/builders/remote-data-build.service.spec.ts b/src/app/core/cache/builders/remote-data-build.service.spec.ts index 0cb45733a61..adda4617183 100644 --- a/src/app/core/cache/builders/remote-data-build.service.spec.ts +++ b/src/app/core/cache/builders/remote-data-build.service.spec.ts @@ -13,10 +13,11 @@ import { RequestService } from '../../data/request.service'; import { UnCacheableObject } from '../../shared/uncacheable-object.model'; import { RemoteData } from '../../data/remote-data'; import { Observable, of as observableOf } from 'rxjs'; -import { RequestEntry, RequestEntryState } from '../../data/request.reducer'; +import { RequestEntry} from '../../data/request.reducer'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { take } from 'rxjs/operators'; import { HALLink } from '../../shared/hal-link.model'; +import { RequestEntryState } from '../../data/request-entry-state.model'; describe('RemoteDataBuildService', () => { let service: RemoteDataBuildService; diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index 6b67549f2d7..1ae2ef961e3 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -13,12 +13,9 @@ import { PaginatedList } from '../../data/paginated-list.model'; import { RemoteData } from '../../data/remote-data'; import { RequestEntry, - ResponseState, - RequestEntryState, - hasSucceeded + ResponseState } from '../../data/request.reducer'; import { RequestService } from '../../data/request.service'; -import { getRequestFromRequestHref, getRequestFromRequestUUID } from '../../shared/operators'; import { ObjectCacheService } from '../object-cache.service'; import { LinkService } from './link.service'; import { HALLink } from '../../shared/hal-link.model'; @@ -28,6 +25,8 @@ import { HALResource } from '../../shared/hal-resource.model'; import { PAGINATED_LIST } from '../../data/paginated-list.resource-type'; import { getUrlWithoutEmbedParams } from '../../index/index.selectors'; import { getResourceTypeValueFor } from '../object-cache.reducer'; +import { hasSucceeded, RequestEntryState } from '../../data/request-entry-state.model'; +import { getRequestFromRequestHref, getRequestFromRequestUUID } from '../../shared/request.operators'; @Injectable() export class RemoteDataBuildService { diff --git a/src/app/core/cache/cacheable-object.model.ts b/src/app/core/cache/cacheable-object.model.ts new file mode 100644 index 00000000000..b7d1609d585 --- /dev/null +++ b/src/app/core/cache/cacheable-object.model.ts @@ -0,0 +1,22 @@ +/* tslint:disable:max-classes-per-file */ +import { HALResource } from '../shared/hal-resource.model'; +import { HALLink } from '../shared/hal-link.model'; +import { TypedObject } from './typed-object.model'; + +/** + * An interface to represent objects that can be cached + * + * A cacheable object should have a self link + */ +export class CacheableObject extends TypedObject implements HALResource { + uuid?: string; + handle?: string; + _links: { + self: HALLink; + }; + // isNew: boolean; + // dirtyType: DirtyType; + // hasDirtyAttributes: boolean; + // changedAttributes: AttributeDiffh; + // save(): void; +} diff --git a/src/app/core/cache/object-cache.actions.ts b/src/app/core/cache/object-cache.actions.ts index ed509341a70..aa7ee00ff52 100644 --- a/src/app/core/cache/object-cache.actions.ts +++ b/src/app/core/cache/object-cache.actions.ts @@ -1,8 +1,8 @@ import { Action } from '@ngrx/store'; import { type } from '../../shared/ngrx/type'; -import { CacheableObject } from './object-cache.reducer'; import { Operation } from 'fast-json-patch'; +import { CacheableObject } from './cacheable-object.model'; /** * The list of ObjectCacheAction type definitions diff --git a/src/app/core/cache/object-cache.reducer.ts b/src/app/core/cache/object-cache.reducer.ts index 8c1420704c9..36319ecf3c9 100644 --- a/src/app/core/cache/object-cache.reducer.ts +++ b/src/app/core/cache/object-cache.reducer.ts @@ -1,18 +1,16 @@ -import { HALLink } from '../shared/hal-link.model'; -import { HALResource } from '../shared/hal-resource.model'; import { + AddPatchObjectCacheAction, + AddToObjectCacheAction, + ApplyPatchObjectCacheAction, ObjectCacheAction, ObjectCacheActionTypes, - AddToObjectCacheAction, RemoveFromObjectCacheAction, - ResetObjectCacheTimestampsAction, - AddPatchObjectCacheAction, - ApplyPatchObjectCacheAction + ResetObjectCacheTimestampsAction } from './object-cache.actions'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { CacheEntry } from './cache-entry'; -import { ResourceType } from '../shared/resource-type'; import { applyPatch, Operation } from 'fast-json-patch'; +import { CacheableObject } from './cacheable-object.model'; /** * An interface to represent a JsonPatch @@ -29,11 +27,6 @@ export interface Patch { operations: Operation[]; } -export abstract class TypedObject { - static type: ResourceType; - type: ResourceType; -} - /** * Get the string value for an object that may be a string or a ResourceType * @@ -49,25 +42,6 @@ export const getResourceTypeValueFor = (type: any): string => { } }; -/* tslint:disable:max-classes-per-file */ -/** - * An interface to represent objects that can be cached - * - * A cacheable object should have a self link - */ -export class CacheableObject extends TypedObject implements HALResource { - uuid?: string; - handle?: string; - _links: { - self: HALLink; - }; - // isNew: boolean; - // dirtyType: DirtyType; - // hasDirtyAttributes: boolean; - // changedAttributes: AttributeDiffh; - // save(): void; -} - /** * An entry in the ObjectCache */ diff --git a/src/app/core/cache/object-cache.service.spec.ts b/src/app/core/cache/object-cache.service.spec.ts index 6863361c34f..e9cc7694a7a 100644 --- a/src/app/core/cache/object-cache.service.spec.ts +++ b/src/app/core/cache/object-cache.service.spec.ts @@ -20,10 +20,10 @@ import { Patch } from './object-cache.reducer'; import { ObjectCacheService } from './object-cache.service'; import { AddToSSBAction } from './server-sync-buffer.actions'; import { RemoveFromIndexBySubstringAction } from '../index/index.actions'; -import { IndexName } from '../index/index.reducer'; import { HALLink } from '../shared/hal-link.model'; import { storeModuleConfig } from '../../app.reducer'; import { TestColdObservable } from 'jasmine-marbles/src/test-observables'; +import { IndexName } from '../index/index-name.model'; describe('ObjectCacheService', () => { let service: ObjectCacheService; diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts index 5fec462670f..8b9660a668b 100644 --- a/src/app/core/cache/object-cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -22,11 +22,12 @@ import { RemoveFromObjectCacheAction } from './object-cache.actions'; -import { CacheableObject, ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer'; +import { ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer'; import { AddToSSBAction } from './server-sync-buffer.actions'; import { RemoveFromIndexBySubstringAction } from '../index/index.actions'; -import { IndexName } from '../index/index.reducer'; import { HALLink } from '../shared/hal-link.model'; +import { CacheableObject } from './cacheable-object.model'; +import { IndexName } from '../index/index-name.model'; /** * The base selector function to select the object cache in the store diff --git a/src/app/core/cache/response.models.ts b/src/app/core/cache/response.models.ts index 3c7c2728300..c8a1052f98b 100644 --- a/src/app/core/cache/response.models.ts +++ b/src/app/core/cache/response.models.ts @@ -1,9 +1,9 @@ -import { RequestError } from '../data/request.models'; import { PageInfo } from '../shared/page-info.model'; import { ConfigObject } from '../config/models/config.model'; import { DSpaceObject } from '../shared/dspace-object.model'; import { HALLink } from '../shared/hal-link.model'; import { UnCacheableObject } from '../shared/uncacheable-object.model'; +import { RequestError } from '../data/request-error.model'; /* tslint:disable:max-classes-per-file */ export class RestResponse { diff --git a/src/app/core/cache/typed-object.model.ts b/src/app/core/cache/typed-object.model.ts new file mode 100644 index 00000000000..02a530941a0 --- /dev/null +++ b/src/app/core/cache/typed-object.model.ts @@ -0,0 +1,6 @@ +import { ResourceType } from '../shared/resource-type'; + +export abstract class TypedObject { + static type: ResourceType; + type: ResourceType; +} diff --git a/src/app/core/config/models/config.model.ts b/src/app/core/config/models/config.model.ts index 53250ee045e..170aa334edb 100644 --- a/src/app/core/config/models/config.model.ts +++ b/src/app/core/config/models/config.model.ts @@ -1,8 +1,8 @@ import { autoserialize, deserialize } from 'cerialize'; -import { CacheableObject } from '../../cache/object-cache.reducer'; import { HALLink } from '../../shared/hal-link.model'; import { ResourceType } from '../../shared/resource-type'; import { excludeFromEquals } from '../../utilities/equals.decorators'; +import { CacheableObject } from '../../cache/cacheable-object.model'; export abstract class ConfigObject implements CacheableObject { diff --git a/src/app/core/data/base-response-parsing.service.spec.ts b/src/app/core/data/base-response-parsing.service.spec.ts index 94285d49d8a..c8a96838549 100644 --- a/src/app/core/data/base-response-parsing.service.spec.ts +++ b/src/app/core/data/base-response-parsing.service.spec.ts @@ -1,8 +1,8 @@ import { BaseResponseParsingService } from './base-response-parsing.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { GetRequest, RestRequest } from './request.models'; import { DSpaceObject } from '../shared/dspace-object.model'; +import { CacheableObject } from '../cache/cacheable-object.model'; /* tslint:disable:max-classes-per-file */ class TestService extends BaseResponseParsingService { diff --git a/src/app/core/data/base-response-parsing.service.ts b/src/app/core/data/base-response-parsing.service.ts index b571b29f027..61945c3161e 100644 --- a/src/app/core/data/base-response-parsing.service.ts +++ b/src/app/core/data/base-response-parsing.service.ts @@ -1,6 +1,5 @@ import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { Serializer } from '../serializer'; import { PageInfo } from '../shared/page-info.model'; import { ObjectCacheService } from '../cache/object-cache.service'; @@ -9,6 +8,7 @@ import { PaginatedList, buildPaginatedList } from './paginated-list.model'; import { getClassForType } from '../cache/builders/build-decorators'; import { RestRequest } from './request.models'; import { environment } from '../../../environments/environment'; +import { CacheableObject } from '../cache/cacheable-object.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/data/bitstream-data.service.ts b/src/app/core/data/bitstream-data.service.ts index 23aec80ff2d..ca5e2761d8f 100644 --- a/src/app/core/data/bitstream-data.service.ts +++ b/src/app/core/data/bitstream-data.service.ts @@ -25,10 +25,10 @@ import { RequestService } from './request.service'; import { BitstreamFormatDataService } from './bitstream-format-data.service'; import { BitstreamFormat } from '../shared/bitstream-format.model'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; -import { sendRequest } from '../shared/operators'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { PageInfo } from '../shared/page-info.model'; import { RequestParam } from '../cache/models/request-param.model'; +import { sendRequest } from '../shared/request.operators'; /** * A service to retrieve {@link Bitstream}s from the REST API diff --git a/src/app/core/data/bitstream-format-data.service.ts b/src/app/core/data/bitstream-format-data.service.ts index 0d0dc5eb638..1f787f4bbcf 100644 --- a/src/app/core/data/bitstream-format-data.service.ts +++ b/src/app/core/data/bitstream-format-data.service.ts @@ -19,12 +19,12 @@ import { BitstreamFormat } from '../shared/bitstream-format.model'; import { BITSTREAM_FORMAT } from '../shared/bitstream-format.resource-type'; import { Bitstream } from '../shared/bitstream.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { sendRequest } from '../shared/operators'; import { DataService } from './data.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { RemoteData } from './remote-data'; import { PostRequest, PutRequest } from './request.models'; import { RequestService } from './request.service'; +import { sendRequest } from '../shared/request.operators'; const bitstreamFormatsStateSelector = createSelector( coreSelector, diff --git a/src/app/core/data/bundle-data.service.ts b/src/app/core/data/bundle-data.service.ts index bff21d2c8d9..3aa4efda244 100644 --- a/src/app/core/data/bundle-data.service.ts +++ b/src/app/core/data/bundle-data.service.ts @@ -22,7 +22,7 @@ import { FindListOptions, GetRequest } from './request.models'; import { RequestService } from './request.service'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; import { Bitstream } from '../shared/bitstream.model'; -import { RequestEntryState } from './request.reducer'; +import { RequestEntryState } from './request-entry-state.model'; /** * A service to retrieve {@link Bundle}s from the REST API diff --git a/src/app/core/data/change-analyzer.ts b/src/app/core/data/change-analyzer.ts index 8efe26314e0..45fd9b7e84b 100644 --- a/src/app/core/data/change-analyzer.ts +++ b/src/app/core/data/change-analyzer.ts @@ -1,6 +1,6 @@ import { Operation } from 'fast-json-patch'; -import { TypedObject } from '../cache/object-cache.reducer'; +import { TypedObject } from '../cache/typed-object.model'; /** * An interface to determine what differs between two diff --git a/src/app/core/data/collection-data.service.ts b/src/app/core/data/collection-data.service.ts index f58f36450f6..e6255144b6a 100644 --- a/src/app/core/data/collection-data.service.ts +++ b/src/app/core/data/collection-data.service.ts @@ -214,4 +214,12 @@ export class CollectionDataService extends ComColDataService { findOwningCollectionFor(item: Item): Observable> { return this.findByHref(item._links.owningCollection.href); } + + protected getScopeCommunityHref(options: FindListOptions) { + return this.cds.getEndpoint().pipe( + map((endpoint: string) => this.cds.getIDHref(endpoint, options.scopeID)), + filter((href: string) => isNotEmpty(href)), + take(1) + ); + } } diff --git a/src/app/core/data/comcol-data.service.spec.ts b/src/app/core/data/comcol-data.service.spec.ts index 864c583dc2a..35704878756 100644 --- a/src/app/core/data/comcol-data.service.spec.ts +++ b/src/app/core/data/comcol-data.service.spec.ts @@ -25,6 +25,12 @@ import { BitstreamDataService } from './bitstream-data.service'; const LINK_NAME = 'test'; +const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d'; + +const communitiesEndpoint = 'https://rest.api/core/communities'; + +const communityEndpoint = `${communitiesEndpoint}/${scopeID}`; + class TestService extends ComColDataService { constructor( @@ -47,6 +53,11 @@ class TestService extends ComColDataService { // implementation in subclasses for communities/collections return undefined; } + + protected getScopeCommunityHref(options: FindListOptions): Observable { + // implementation in subclasses for communities/collections + return observableOf(communityEndpoint); + } } // tslint:disable:no-shadowed-variable @@ -66,12 +77,9 @@ describe('ComColDataService', () => { const http = {} as HttpClient; const comparator = {} as any; - const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d'; const options = Object.assign(new FindListOptions(), { scopeID: scopeID }); - const communitiesEndpoint = 'https://rest.api/core/communities'; - const communityEndpoint = `${communitiesEndpoint}/${scopeID}`; const scopedEndpoint = `${communityEndpoint}/${LINK_NAME}`; const mockHalService = { diff --git a/src/app/core/data/comcol-data.service.ts b/src/app/core/data/comcol-data.service.ts index 12aedf80093..cf59c7ac745 100644 --- a/src/app/core/data/comcol-data.service.ts +++ b/src/app/core/data/comcol-data.service.ts @@ -4,8 +4,6 @@ import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; import { ObjectCacheService } from '../cache/object-cache.service'; import { Community } from '../shared/community.model'; import { HALLink } from '../shared/hal-link.model'; -import { CommunityDataService } from './community-data.service'; - import { DataService } from './data.service'; import { FindListOptions } from './request.models'; import { PaginatedList } from './paginated-list.model'; @@ -21,7 +19,6 @@ import { URLCombiner } from '../url-combiner/url-combiner'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; export abstract class ComColDataService extends DataService { - protected abstract cds: CommunityDataService; protected abstract objectCache: ObjectCacheService; protected abstract halService: HALEndpointService; protected abstract bitstreamDataService: BitstreamDataService; @@ -40,11 +37,7 @@ export abstract class ComColDataService extend if (isEmpty(options.scopeID)) { return this.halService.getEndpoint(linkPath); } else { - const scopeCommunityHrefObs = this.cds.getEndpoint().pipe( - map((endpoint: string) => this.cds.getIDHref(endpoint, options.scopeID)), - filter((href: string) => isNotEmpty(href)), - take(1) - ); + const scopeCommunityHrefObs = this.getScopeCommunityHref(options); this.createAndSendGetRequest(scopeCommunityHrefObs, true); @@ -65,6 +58,8 @@ export abstract class ComColDataService extend } } + protected abstract getScopeCommunityHref(options: FindListOptions): Observable; + protected abstract getFindByParentHref(parentUUID: string): Observable; public findByParent(parentUUID: string, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig[]): Observable>> { diff --git a/src/app/core/data/community-data.service.ts b/src/app/core/data/community-data.service.ts index 8dee72e3916..82afe561a90 100644 --- a/src/app/core/data/community-data.service.ts +++ b/src/app/core/data/community-data.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { filter, map, switchMap, take } from 'rxjs/operators'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; @@ -20,13 +20,13 @@ import { FindListOptions } from './request.models'; import { RequestService } from './request.service'; import { BitstreamDataService } from './bitstream-data.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { isNotEmpty } from '../../shared/empty.util'; @Injectable() @dataService(COMMUNITY) export class CommunityDataService extends ComColDataService { protected linkPath = 'communities'; protected topLinkPath = 'search/top'; - protected cds = this; constructor( protected requestService: RequestService, @@ -58,4 +58,11 @@ export class CommunityDataService extends ComColDataService { ); } + protected getScopeCommunityHref(options: FindListOptions) { + return this.getEndpoint().pipe( + map((endpoint: string) => this.getIDHref(endpoint, options.scopeID)), + filter((href: string) => isNotEmpty(href)), + take(1) + ); + } } diff --git a/src/app/core/data/data.service.spec.ts b/src/app/core/data/data.service.spec.ts index 5bc7423824d..56ef753a795 100644 --- a/src/app/core/data/data.service.spec.ts +++ b/src/app/core/data/data.service.spec.ts @@ -22,7 +22,7 @@ import { RequestParam } from '../cache/models/request-param.model'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; import { TestScheduler } from 'rxjs/testing'; import { RemoteData } from './remote-data'; -import { RequestEntryState } from './request.reducer'; +import { RequestEntryState } from './request-entry-state.model'; const endpoint = 'https://rest.api/core'; diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index 6bad02e7761..12a66e50926 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -21,7 +21,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { getClassForType } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RequestParam } from '../cache/models/request-param.model'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { ObjectCacheService } from '../cache/object-cache.service'; import { CoreState } from '../core.reducers'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; @@ -45,6 +44,7 @@ import { RestRequestMethod } from './rest-request-method'; import { UpdateDataService } from './update-data.service'; import { GenericConstructor } from '../shared/generic-constructor'; import { NoContent } from '../shared/NoContent.model'; +import { CacheableObject } from '../cache/cacheable-object.model'; export abstract class DataService implements UpdateDataService { protected abstract requestService: RequestService; diff --git a/src/app/core/data/default-change-analyzer.service.ts b/src/app/core/data/default-change-analyzer.service.ts index 34a619648a2..e12a1f08d56 100644 --- a/src/app/core/data/default-change-analyzer.service.ts +++ b/src/app/core/data/default-change-analyzer.service.ts @@ -2,9 +2,9 @@ import { Injectable } from '@angular/core'; import { compare } from 'fast-json-patch'; import { Operation } from 'fast-json-patch'; import { getClassForType } from '../cache/builders/build-decorators'; -import { TypedObject } from '../cache/object-cache.reducer'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { ChangeAnalyzer } from './change-analyzer'; +import { TypedObject } from '../cache/typed-object.model'; /** * A class to determine what differs between two 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 2fda0bf40a9..27af802ce81 100644 --- a/src/app/core/data/dspace-rest-response-parsing.service.ts +++ b/src/app/core/data/dspace-rest-response-parsing.service.ts @@ -1,6 +1,5 @@ import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { Serializer } from '../serializer'; import { PageInfo } from '../shared/page-info.model'; import { ObjectCacheService } from '../cache/object-cache.service'; @@ -17,6 +16,7 @@ import { ParsedResponse } from '../cache/response.models'; import { RestRequestMethod } from './rest-request-method'; import { getUrlWithoutEmbedParams, getEmbedSizeParams } from '../index/index.selectors'; import { URLCombiner } from '../url-combiner/url-combiner'; +import { CacheableObject } from '../cache/cacheable-object.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/data/endpoint-map-response-parsing.service.ts b/src/app/core/data/endpoint-map-response-parsing.service.ts index 1a81deaea06..73396e78bbe 100644 --- a/src/app/core/data/endpoint-map-response-parsing.service.ts +++ b/src/app/core/data/endpoint-map-response-parsing.service.ts @@ -11,8 +11,8 @@ import { RestRequest } from './request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ParsedResponse } from '../cache/response.models'; import { DSpaceObject } from '../shared/dspace-object.model'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { environment } from '../../../environments/environment'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * ResponseParsingService able to deal with HAL Endpoints that are only needed as steps diff --git a/src/app/core/data/feature-authorization/feature-authorization-guard/some-feature-authorization.guard.ts b/src/app/core/data/feature-authorization/feature-authorization-guard/some-feature-authorization.guard.ts index 3a6cf745c92..18c7f8fb436 100644 --- a/src/app/core/data/feature-authorization/feature-authorization-guard/some-feature-authorization.guard.ts +++ b/src/app/core/data/feature-authorization/feature-authorization-guard/some-feature-authorization.guard.ts @@ -2,9 +2,9 @@ import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTr import { AuthorizationDataService } from '../authorization-data.service'; import { FeatureID } from '../feature-id'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; -import { returnForbiddenUrlTreeOrLoginOnAllFalse } from '../../../shared/operators'; import { switchMap } from 'rxjs/operators'; import { AuthService } from '../../../auth/auth.service'; +import { returnForbiddenUrlTreeOrLoginOnAllFalse } from '../../../shared/authorized.operators'; /** * Abstract Guard for preventing unauthorized activating and loading of routes when a user diff --git a/src/app/core/data/href-only-data.service.ts b/src/app/core/data/href-only-data.service.ts index c1298c054c9..4baffea5453 100644 --- a/src/app/core/data/href-only-data.service.ts +++ b/src/app/core/data/href-only-data.service.ts @@ -18,7 +18,7 @@ import { Observable } from 'rxjs/internal/Observable'; import { PaginatedList } from './paginated-list.model'; import { ITEM_TYPE } from '../shared/item-relationships/item-type.resource-type'; import { LICENSE } from '../shared/license.resource-type'; -import { CacheableObject } from '../cache/object-cache.reducer'; +import { CacheableObject } from '../cache/cacheable-object.model'; /* tslint:disable:max-classes-per-file */ class DataServiceImpl extends DataService { diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index 7a0116fe864..1c152701a10 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -16,7 +16,6 @@ import { ExternalSourceEntry } from '../shared/external-source-entry.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { Item } from '../shared/item.model'; import { ITEM } from '../shared/item.resource-type'; -import { sendRequest } from '../shared/operators'; import { URLCombiner } from '../url-combiner/url-combiner'; import { DataService } from './data.service'; @@ -34,6 +33,7 @@ import { NoContent } from '../shared/NoContent.model'; import { GenericConstructor } from '../shared/generic-constructor'; import { ResponseParsingService } from './parsing.service'; import { StatusCodeOnlyResponseParsingService } from './status-code-only-response-parsing.service'; +import { sendRequest } from '../shared/request.operators'; @Injectable() @dataService(ITEM) diff --git a/src/app/core/data/object-updates/field-change-type.model.ts b/src/app/core/data/object-updates/field-change-type.model.ts new file mode 100644 index 00000000000..7d8e3089451 --- /dev/null +++ b/src/app/core/data/object-updates/field-change-type.model.ts @@ -0,0 +1,8 @@ +/** + * Enum that represents the different types of updates that can be performed on a field in the ObjectUpdates store + */ +export enum FieldChangeType { + UPDATE = 0, + ADD = 1, + REMOVE = 2 +} diff --git a/src/app/core/data/object-updates/field-update.model.ts b/src/app/core/data/object-updates/field-update.model.ts new file mode 100644 index 00000000000..47b67824713 --- /dev/null +++ b/src/app/core/data/object-updates/field-update.model.ts @@ -0,0 +1,10 @@ +import { Identifiable } from './identifiable.model'; +import { FieldChangeType } from './field-change-type.model'; + +/** + * The state of a single field update + */ +export interface FieldUpdate { + field: Identifiable; + changeType: FieldChangeType; +} diff --git a/src/app/core/data/object-updates/field-updates.model.ts b/src/app/core/data/object-updates/field-updates.model.ts new file mode 100644 index 00000000000..eff804bd023 --- /dev/null +++ b/src/app/core/data/object-updates/field-updates.model.ts @@ -0,0 +1,8 @@ +import { FieldUpdate } from './field-update.model'; + +/** + * The states of all field updates available for a single page, mapped by uuid + */ +export interface FieldUpdates { + [uuid: string]: FieldUpdate; +} diff --git a/src/app/core/data/object-updates/identifiable.model.ts b/src/app/core/data/object-updates/identifiable.model.ts new file mode 100644 index 00000000000..7d32859338a --- /dev/null +++ b/src/app/core/data/object-updates/identifiable.model.ts @@ -0,0 +1,6 @@ +/** + * Represents every object that has a UUID + */ +export interface Identifiable { + uuid: string; +} diff --git a/src/app/core/data/object-updates/object-updates.actions.ts b/src/app/core/data/object-updates/object-updates.actions.ts index 13bbabb2866..6c09327a426 100644 --- a/src/app/core/data/object-updates/object-updates.actions.ts +++ b/src/app/core/data/object-updates/object-updates.actions.ts @@ -1,9 +1,10 @@ -import {type} from '../../../shared/ngrx/type'; -import {Action} from '@ngrx/store'; -import {Identifiable} from './object-updates.reducer'; -import {INotification} from '../../../shared/notifications/models/notification.model'; +import { type } from '../../../shared/ngrx/type'; +import { Action } from '@ngrx/store'; +import { INotification } from '../../../shared/notifications/models/notification.model'; import { PatchOperationService } from './patch-operation-service/patch-operation.service'; import { GenericConstructor } from '../../shared/generic-constructor'; +import { Identifiable } from './identifiable.model'; +import { FieldChangeType } from './field-change-type.model'; /** * The list of ObjectUpdatesAction type definitions @@ -23,15 +24,6 @@ export const ObjectUpdatesActionTypes = { /* tslint:disable:max-classes-per-file */ -/** - * Enum that represents the different types of updates that can be performed on a field in the ObjectUpdates store - */ -export enum FieldChangeType { - UPDATE = 0, - ADD = 1, - REMOVE = 2 -} - /** * An ngrx action to initialize a new page's fields in the ObjectUpdates state */ diff --git a/src/app/core/data/object-updates/object-updates.reducer.spec.ts b/src/app/core/data/object-updates/object-updates.reducer.spec.ts index 4d7fce24a76..a51a1431bba 100644 --- a/src/app/core/data/object-updates/object-updates.reducer.spec.ts +++ b/src/app/core/data/object-updates/object-updates.reducer.spec.ts @@ -2,7 +2,6 @@ import * as deepFreeze from 'deep-freeze'; import { AddFieldUpdateAction, DiscardObjectUpdatesAction, - FieldChangeType, InitializeFieldsAction, ReinstateObjectUpdatesAction, RemoveAllObjectUpdatesAction, @@ -14,6 +13,7 @@ import { } from './object-updates.actions'; import { OBJECT_UPDATES_TRASH_PATH, objectUpdatesReducer } from './object-updates.reducer'; import { Relationship } from '../../shared/item-relationships/relationship.model'; +import { FieldChangeType } from './field-change-type.model'; class NullAction extends RemoveFieldUpdateAction { type = null; diff --git a/src/app/core/data/object-updates/object-updates.reducer.ts b/src/app/core/data/object-updates/object-updates.reducer.ts index 6dfb4ab584d..14bacc52db4 100644 --- a/src/app/core/data/object-updates/object-updates.reducer.ts +++ b/src/app/core/data/object-updates/object-updates.reducer.ts @@ -1,16 +1,15 @@ import { AddFieldUpdateAction, DiscardObjectUpdatesAction, - FieldChangeType, InitializeFieldsAction, ObjectUpdatesAction, ObjectUpdatesActionTypes, ReinstateObjectUpdatesAction, RemoveFieldUpdateAction, RemoveObjectUpdatesAction, + SelectVirtualMetadataAction, SetEditableFieldUpdateAction, SetValidFieldUpdateAction, - SelectVirtualMetadataAction, } from './object-updates.actions'; import { hasNoValue, hasValue } from '../../../shared/empty.util'; import { Relationship } from '../../shared/item-relationships/relationship.model'; @@ -18,6 +17,9 @@ import { PatchOperationService } from './patch-operation-service/patch-operation import { Item } from '../../shared/item.model'; import { RelationshipType } from '../../shared/item-relationships/relationship-type.model'; import { GenericConstructor } from '../../shared/generic-constructor'; +import { Identifiable } from './identifiable.model'; +import { FieldUpdates } from './field-updates.model'; +import { FieldChangeType } from './field-change-type.model'; /** * Path where discarded objects are saved @@ -40,28 +42,6 @@ export interface FieldStates { [uuid: string]: FieldState; } -/** - * Represents every object that has a UUID - */ -export interface Identifiable { - uuid: string; -} - -/** - * The state of a single field update - */ -export interface FieldUpdate { - field: Identifiable; - changeType: FieldChangeType; -} - -/** - * The states of all field updates available for a single page, mapped by uuid - */ -export interface FieldUpdates { - [uuid: string]: FieldUpdate; -} - /** * The states of all virtual metadata selections available for a single page, mapped by the relationship uuid */ diff --git a/src/app/core/data/object-updates/object-updates.service.spec.ts b/src/app/core/data/object-updates/object-updates.service.spec.ts index 6c0b0f99c43..b0c63851e3b 100644 --- a/src/app/core/data/object-updates/object-updates.service.spec.ts +++ b/src/app/core/data/object-updates/object-updates.service.spec.ts @@ -3,7 +3,6 @@ import { CoreState } from '../../core.reducers'; import { ObjectUpdatesService } from './object-updates.service'; import { DiscardObjectUpdatesAction, - FieldChangeType, InitializeFieldsAction, ReinstateObjectUpdatesAction, RemoveFieldUpdateAction, @@ -16,6 +15,7 @@ import { NotificationType } from '../../../shared/notifications/models/notificat import { OBJECT_UPDATES_TRASH_PATH } from './object-updates.reducer'; import { Relationship } from '../../shared/item-relationships/relationship.model'; import { Injector } from '@angular/core'; +import { FieldChangeType } from './field-change-type.model'; describe('ObjectUpdatesService', () => { let service: ObjectUpdatesService; diff --git a/src/app/core/data/object-updates/object-updates.service.ts b/src/app/core/data/object-updates/object-updates.service.ts index 88c7c0e453f..0bdae06ce26 100644 --- a/src/app/core/data/object-updates/object-updates.service.ts +++ b/src/app/core/data/object-updates/object-updates.service.ts @@ -4,8 +4,6 @@ import { CoreState } from '../../core.reducers'; import { coreSelector } from '../../core.selectors'; import { FieldState, - FieldUpdates, - Identifiable, OBJECT_UPDATES_TRASH_PATH, ObjectUpdatesEntry, ObjectUpdatesState, @@ -15,7 +13,6 @@ import { Observable } from 'rxjs'; import { AddFieldUpdateAction, DiscardObjectUpdatesAction, - FieldChangeType, InitializeFieldsAction, ReinstateObjectUpdatesAction, RemoveFieldUpdateAction, @@ -35,6 +32,9 @@ import { INotification } from '../../../shared/notifications/models/notification import { Operation } from 'fast-json-patch'; import { PatchOperationService } from './patch-operation-service/patch-operation.service'; import { GenericConstructor } from '../../shared/generic-constructor'; +import { Identifiable } from './identifiable.model'; +import { FieldUpdates } from './field-updates.model'; +import { FieldChangeType } from './field-change-type.model'; function objectUpdatesStateSelector(): MemoizedSelector { return createSelector(coreSelector, (state: CoreState) => state['cache/object-updates']); diff --git a/src/app/core/data/object-updates/patch-operation-service/metadata-patch-operation.service.spec.ts b/src/app/core/data/object-updates/patch-operation-service/metadata-patch-operation.service.spec.ts index 9708266cd7d..db46426b79f 100644 --- a/src/app/core/data/object-updates/patch-operation-service/metadata-patch-operation.service.spec.ts +++ b/src/app/core/data/object-updates/patch-operation-service/metadata-patch-operation.service.spec.ts @@ -1,8 +1,8 @@ import { MetadataPatchOperationService } from './metadata-patch-operation.service'; -import { FieldUpdates } from '../object-updates.reducer'; import { Operation } from 'fast-json-patch'; -import { FieldChangeType } from '../object-updates.actions'; import { MetadatumViewModel } from '../../../shared/metadata.models'; +import { FieldUpdates } from '../field-updates.model'; +import { FieldChangeType } from '../field-change-type.model'; describe('MetadataPatchOperationService', () => { let service: MetadataPatchOperationService; diff --git a/src/app/core/data/object-updates/patch-operation-service/metadata-patch-operation.service.ts b/src/app/core/data/object-updates/patch-operation-service/metadata-patch-operation.service.ts index 59c981872a1..33e9129a9d1 100644 --- a/src/app/core/data/object-updates/patch-operation-service/metadata-patch-operation.service.ts +++ b/src/app/core/data/object-updates/patch-operation-service/metadata-patch-operation.service.ts @@ -1,14 +1,14 @@ import { PatchOperationService } from './patch-operation.service'; import { MetadatumViewModel } from '../../../shared/metadata.models'; -import { FieldUpdates } from '../object-updates.reducer'; import { Operation } from 'fast-json-patch'; -import { FieldChangeType } from '../object-updates.actions'; import { Injectable } from '@angular/core'; import { MetadataPatchOperation } from './operations/metadata/metadata-patch-operation.model'; import { hasValue } from '../../../../shared/empty.util'; import { MetadataPatchAddOperation } from './operations/metadata/metadata-patch-add-operation.model'; import { MetadataPatchRemoveOperation } from './operations/metadata/metadata-patch-remove-operation.model'; import { MetadataPatchReplaceOperation } from './operations/metadata/metadata-patch-replace-operation.model'; +import { FieldUpdates } from '../field-updates.model'; +import { FieldChangeType } from '../field-change-type.model'; /** * Service transforming {@link FieldUpdates} into {@link Operation}s for metadata values diff --git a/src/app/core/data/object-updates/patch-operation-service/patch-operation.service.ts b/src/app/core/data/object-updates/patch-operation-service/patch-operation.service.ts index 7c67f9a2e55..171c1d2a54e 100644 --- a/src/app/core/data/object-updates/patch-operation-service/patch-operation.service.ts +++ b/src/app/core/data/object-updates/patch-operation-service/patch-operation.service.ts @@ -1,5 +1,5 @@ -import { FieldUpdates } from '../object-updates.reducer'; import { Operation } from 'fast-json-patch'; +import { FieldUpdates } from '../field-updates.model'; /** * Interface for a service dealing with the transformations of patch operations from the object-updates store diff --git a/src/app/core/data/paginated-list.model.ts b/src/app/core/data/paginated-list.model.ts index e85a91f7914..415bfe234ea 100644 --- a/src/app/core/data/paginated-list.model.ts +++ b/src/app/core/data/paginated-list.model.ts @@ -3,11 +3,11 @@ import { hasValue, isEmpty, hasNoValue, isUndefined } from '../../shared/empty.u import { HALResource } from '../shared/hal-resource.model'; import { HALLink } from '../shared/hal-link.model'; import { typedObject } from '../cache/builders/build-decorators'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { PAGINATED_LIST } from './paginated-list.resource-type'; import { ResourceType } from '../shared/resource-type'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { autoserialize, deserialize } from 'cerialize'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * Factory function for a paginated list diff --git a/src/app/core/data/relationship.service.ts b/src/app/core/data/relationship.service.ts index 727cd105e6c..7bd36d0cece 100644 --- a/src/app/core/data/relationship.service.ts +++ b/src/app/core/data/relationship.service.ts @@ -29,7 +29,6 @@ import { Relationship } from '../shared/item-relationships/relationship.model'; import { RELATIONSHIP } from '../shared/item-relationships/relationship.resource-type'; import { Item } from '../shared/item.model'; import { - sendRequest, getFirstCompletedRemoteData, getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload, @@ -42,8 +41,9 @@ import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { DeleteRequest, FindListOptions, PostRequest, RestRequest } from './request.models'; import { RequestService } from './request.service'; -import { RequestEntryState } from './request.reducer'; import { NoContent } from '../shared/NoContent.model'; +import { RequestEntryState } from './request-entry-state.model'; +import { sendRequest } from '../shared/request.operators'; const relationshipListsStateSelector = (state: AppState) => state.relationshipLists; diff --git a/src/app/core/data/remote-data.ts b/src/app/core/data/remote-data.ts index 4fa11607dff..40c8d7f4000 100644 --- a/src/app/core/data/remote-data.ts +++ b/src/app/core/data/remote-data.ts @@ -1,17 +1,17 @@ import { - RequestEntryState, - isStale, hasCompleted, - hasSucceeded, hasFailed, - isLoading, - isSuccessStale, - isErrorStale, - isSuccess, + hasSucceeded, isError, + isErrorStale, + isLoading, + isRequestPending, isResponsePending, - isRequestPending -} from './request.reducer'; + isStale, + isSuccess, + isSuccessStale, + RequestEntryState +} from './request-entry-state.model'; /** * A class to represent the state of a remote resource diff --git a/src/app/core/data/request-entry-state.model.ts b/src/app/core/data/request-entry-state.model.ts new file mode 100644 index 00000000000..a813b6e7436 --- /dev/null +++ b/src/app/core/data/request-entry-state.model.ts @@ -0,0 +1,88 @@ +export enum RequestEntryState { + RequestPending = 'RequestPending', + ResponsePending = 'ResponsePending', + Error = 'Error', + Success = 'Success', + ErrorStale = 'ErrorStale', + SuccessStale = 'SuccessStale' +} + +/** + * Returns true if the given state is RequestPending, false otherwise + */ +export const isRequestPending = (state: RequestEntryState) => + state === RequestEntryState.RequestPending; + +/** + * Returns true if the given state is Error, false otherwise + */ +export const isError = (state: RequestEntryState) => + state === RequestEntryState.Error; + +/** + * Returns true if the given state is Success, false otherwise + */ +export const isSuccess = (state: RequestEntryState) => + state === RequestEntryState.Success; + +/** + * Returns true if the given state is ErrorStale, false otherwise + */ +export const isErrorStale = (state: RequestEntryState) => + state === RequestEntryState.ErrorStale; + +/** + * Returns true if the given state is SuccessStale, false otherwise + */ +export const isSuccessStale = (state: RequestEntryState) => + state === RequestEntryState.SuccessStale; + +/** + * Returns true if the given state is ResponsePending, false otherwise + */ +export const isResponsePending = (state: RequestEntryState) => + state === RequestEntryState.ResponsePending; +/** + * Returns true if the given state is RequestPending or ResponsePending, + * false otherwise + */ +export const isLoading = (state: RequestEntryState) => + isRequestPending(state) || isResponsePending(state); + +/** + * If isLoading is true for the given state, this method returns undefined, we can't know yet. + * If it isn't this method will return true if the the given state is Error or ErrorStale, + * false otherwise + */ +export const hasFailed = (state: RequestEntryState) => { + if (isLoading(state)) { + return undefined; + } else { + return isError(state) || isErrorStale(state); + } +}; + +/** + * If isLoading is true for the given state, this method returns undefined, we can't know yet. + * If it isn't this method will return true if the the given state is Success or SuccessStale, + * false otherwise + */ +export const hasSucceeded = (state: RequestEntryState) => { + if (isLoading(state)) { + return undefined; + } else { + return isSuccess(state) || isSuccessStale(state); + } +}; + +/** + * Returns true if the given state is not loading, false otherwise + */ +export const hasCompleted = (state: RequestEntryState) => + !isLoading(state); + +/** + * Returns true if the given state is SuccessStale or ErrorStale, false otherwise + */ +export const isStale = (state: RequestEntryState) => + isSuccessStale(state) || isErrorStale(state); diff --git a/src/app/core/data/request-error.model.ts b/src/app/core/data/request-error.model.ts new file mode 100644 index 00000000000..bde0e1ea235 --- /dev/null +++ b/src/app/core/data/request-error.model.ts @@ -0,0 +1,4 @@ +export class RequestError extends Error { + statusCode: number; + statusText: string; +} diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index acac82afa5f..e5a4fc7df2a 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -16,10 +16,11 @@ import { RequestSuccessAction, ResetResponseTimestampsAction } from './request.actions'; -import { RequestError, RestRequest } from './request.models'; +import { RestRequest } from './request.models'; import { RequestEntry } from './request.reducer'; import { RequestService } from './request.service'; import { ParsedResponse } from '../cache/response.models'; +import { RequestError } from './request-error.model'; @Injectable() export class RequestEffects { diff --git a/src/app/core/data/request.models.ts b/src/app/core/data/request.models.ts index 667e4a04349..990c37d192b 100644 --- a/src/app/core/data/request.models.ts +++ b/src/app/core/data/request.models.ts @@ -275,8 +275,4 @@ export class MyDSpaceRequest extends GetRequest { public responseMsToLive = 10 * 1000; } -export class RequestError extends Error { - statusCode: number; - statusText: string; -} /* tslint:enable:max-classes-per-file */ diff --git a/src/app/core/data/request.reducer.spec.ts b/src/app/core/data/request.reducer.spec.ts index 3e210220fe4..2073b4faa1a 100644 --- a/src/app/core/data/request.reducer.spec.ts +++ b/src/app/core/data/request.reducer.spec.ts @@ -9,7 +9,8 @@ import { ResetResponseTimestampsAction } from './request.actions'; import { GetRequest } from './request.models'; -import { RequestEntryState, requestReducer, RequestState } from './request.reducer'; +import { requestReducer, RequestState } from './request.reducer'; +import { RequestEntryState } from './request-entry-state.model'; class NullAction extends RequestSuccessAction { type = null; diff --git a/src/app/core/data/request.reducer.ts b/src/app/core/data/request.reducer.ts index 5dcee2dbb18..8b6f50dda8e 100644 --- a/src/app/core/data/request.reducer.ts +++ b/src/app/core/data/request.reducer.ts @@ -2,107 +2,18 @@ import { RequestAction, RequestActionTypes, RequestConfigureAction, + RequestErrorAction, RequestExecuteAction, RequestRemoveAction, - ResetResponseTimestampsAction, + RequestStaleAction, RequestSuccessAction, - RequestErrorAction, - RequestStaleAction + ResetResponseTimestampsAction } from './request.actions'; import { RestRequest } from './request.models'; import { HALLink } from '../shared/hal-link.model'; import { UnCacheableObject } from '../shared/uncacheable-object.model'; import { isNull } from '../../shared/empty.util'; - -export enum RequestEntryState { - RequestPending = 'RequestPending', - ResponsePending = 'ResponsePending', - Error = 'Error', - Success = 'Success', - ErrorStale = 'ErrorStale', - SuccessStale = 'SuccessStale' -} - -/** - * Returns true if the given state is RequestPending, false otherwise - */ -export const isRequestPending = (state: RequestEntryState) => - state === RequestEntryState.RequestPending; - -/** - * Returns true if the given state is ResponsePending, false otherwise - */ -export const isResponsePending = (state: RequestEntryState) => - state === RequestEntryState.ResponsePending; - -/** - * Returns true if the given state is Error, false otherwise - */ -export const isError = (state: RequestEntryState) => - state === RequestEntryState.Error; - -/** - * Returns true if the given state is Success, false otherwise - */ -export const isSuccess = (state: RequestEntryState) => - state === RequestEntryState.Success; - -/** - * Returns true if the given state is ErrorStale, false otherwise - */ -export const isErrorStale = (state: RequestEntryState) => - state === RequestEntryState.ErrorStale; - -/** - * Returns true if the given state is SuccessStale, false otherwise - */ -export const isSuccessStale = (state: RequestEntryState) => - state === RequestEntryState.SuccessStale; - -/** - * Returns true if the given state is RequestPending or ResponsePending, - * false otherwise - */ -export const isLoading = (state: RequestEntryState) => - isRequestPending(state) || isResponsePending(state); - -/** - * If isLoading is true for the given state, this method returns undefined, we can't know yet. - * If it isn't this method will return true if the the given state is Error or ErrorStale, - * false otherwise - */ -export const hasFailed = (state: RequestEntryState) => { - if (isLoading(state)) { - return undefined; - } else { - return isError(state) || isErrorStale(state); - } -}; - -/** - * If isLoading is true for the given state, this method returns undefined, we can't know yet. - * If it isn't this method will return true if the the given state is Success or SuccessStale, - * false otherwise - */ -export const hasSucceeded = (state: RequestEntryState) => { - if (isLoading(state)) { - return undefined; - } else { - return isSuccess(state) || isSuccessStale(state); - } -}; - -/** - * Returns true if the given state is not loading, false otherwise - */ -export const hasCompleted = (state: RequestEntryState) => - !isLoading(state); - -/** - * Returns true if the given state is SuccessStale or ErrorStale, false otherwise - */ -export const isStale = (state: RequestEntryState) => - isSuccessStale(state) || isErrorStale(state); +import { hasSucceeded, isStale, RequestEntryState } from './request-entry-state.model'; export class ResponseState { timeCompleted: number; diff --git a/src/app/core/data/request.service.spec.ts b/src/app/core/data/request.service.spec.ts index 7a07f6fe103..50d753ab456 100644 --- a/src/app/core/data/request.service.spec.ts +++ b/src/app/core/data/request.service.spec.ts @@ -19,11 +19,12 @@ import { PutRequest, RestRequest } from './request.models'; -import { RequestEntry, RequestEntryState } from './request.reducer'; +import { RequestEntry} from './request.reducer'; import { RequestService } from './request.service'; import { TestBed, waitForAsync } from '@angular/core/testing'; import { storeModuleConfig } from '../../app.reducer'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; +import { RequestEntryState } from './request-entry-state.model'; describe('RequestService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index 14499b82149..b381fdd1fd1 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -18,10 +18,11 @@ import { RequestStaleAction } from './request.actions'; import { GetRequest, RestRequest } from './request.models'; -import { RequestEntry, RequestState, isStale, isLoading } from './request.reducer'; +import { RequestEntry, RequestState} from './request.reducer'; import { CommitSSBAction } from '../cache/server-sync-buffer.actions'; import { RestRequestMethod } from './rest-request-method'; import { coreSelector } from '../core.selectors'; +import { isLoading, isStale } from './request-entry-state.model'; /** * The base selector function to select the request state in the store diff --git a/src/app/core/data/root.model.ts b/src/app/core/data/root.model.ts index 4840051df54..a2d2518ddea 100644 --- a/src/app/core/data/root.model.ts +++ b/src/app/core/data/root.model.ts @@ -1,10 +1,10 @@ import { typedObject } from '../cache/builders/build-decorators'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { ROOT } from './root.resource-type'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { autoserialize, deserialize } from 'cerialize'; import { ResourceType } from '../shared/resource-type'; import { HALLink } from '../shared/hal-link.model'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * The root rest api resource diff --git a/src/app/core/end-user-agreement/abstract-end-user-agreement.guard.ts b/src/app/core/end-user-agreement/abstract-end-user-agreement.guard.ts index 5d44a8447a2..b9f134f9464 100644 --- a/src/app/core/end-user-agreement/abstract-end-user-agreement.guard.ts +++ b/src/app/core/end-user-agreement/abstract-end-user-agreement.guard.ts @@ -1,6 +1,6 @@ import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router'; import { Observable } from 'rxjs'; -import { returnEndUserAgreementUrlTreeOnFalse } from '../shared/operators'; +import { returnEndUserAgreementUrlTreeOnFalse } from '../shared/authorized.operators'; /** * An abstract guard for redirecting users to the user agreement page if a certain condition is met diff --git a/src/app/core/index/index-name.model.ts b/src/app/core/index/index-name.model.ts new file mode 100644 index 00000000000..fa4c20a0060 --- /dev/null +++ b/src/app/core/index/index-name.model.ts @@ -0,0 +1,17 @@ +/** + * An enum containing all index names + */ +export enum IndexName { + // Contains all objects in the object cache indexed by UUID + OBJECT = 'object/uuid-to-self-link', + + // contains all requests in the request cache indexed by UUID + REQUEST = 'get-request/href-to-uuid', + + /** + * Contains the alternative link for an objects + * Maps these link on to their matching self link in the object cache + * Eg. /workspaceitems/12/item --> /items/12345 + */ + ALTERNATIVE_OBJECT_LINK = 'object/alt-link-to-self-link' +} diff --git a/src/app/core/index/index.actions.ts b/src/app/core/index/index.actions.ts index feff7a44868..091f7886267 100644 --- a/src/app/core/index/index.actions.ts +++ b/src/app/core/index/index.actions.ts @@ -1,7 +1,7 @@ import { Action } from '@ngrx/store'; import { type } from '../../shared/ngrx/type'; -import { IndexName } from './index.reducer'; +import { IndexName } from './index-name.model'; /** * The list of HrefIndexAction type definitions diff --git a/src/app/core/index/index.effects.spec.ts b/src/app/core/index/index.effects.spec.ts index efca0ae3647..c86860d01c0 100644 --- a/src/app/core/index/index.effects.spec.ts +++ b/src/app/core/index/index.effects.spec.ts @@ -6,9 +6,9 @@ import { cold, hot } from 'jasmine-marbles'; import { AddToObjectCacheAction } from '../cache/object-cache.actions'; import { Item } from '../shared/item.model'; import { AddToIndexAction } from './index.actions'; -import { IndexName } from './index.reducer'; import { provideMockStore } from '@ngrx/store/testing'; import { NoOpAction } from '../../shared/ngrx/no-op.action'; +import { IndexName } from './index-name.model'; describe('ObjectUpdatesEffects', () => { let indexEffects: UUIDIndexEffects; diff --git a/src/app/core/index/index.effects.ts b/src/app/core/index/index.effects.ts index a1ab0b20a8d..58acc08acc6 100644 --- a/src/app/core/index/index.effects.ts +++ b/src/app/core/index/index.effects.ts @@ -14,12 +14,12 @@ import { } from '../data/request.actions'; import { AddToIndexAction, RemoveFromIndexByValueAction } from './index.actions'; import { hasValue } from '../../shared/empty.util'; -import { IndexName } from './index.reducer'; import { RestRequestMethod } from '../data/rest-request-method'; import { getUrlWithoutEmbedParams, uuidFromHrefSelector } from './index.selectors'; import { Store, select } from '@ngrx/store'; import { CoreState } from '../core.reducers'; import { NoOpAction } from '../../shared/ngrx/no-op.action'; +import { IndexName } from './index-name.model'; @Injectable() export class UUIDIndexEffects { diff --git a/src/app/core/index/index.reducer.spec.ts b/src/app/core/index/index.reducer.spec.ts index 4daacc03a69..867e4dbad88 100644 --- a/src/app/core/index/index.reducer.spec.ts +++ b/src/app/core/index/index.reducer.spec.ts @@ -1,11 +1,12 @@ import * as deepFreeze from 'deep-freeze'; -import { IndexName, indexReducer, MetaIndexState } from './index.reducer'; +import { indexReducer, MetaIndexState } from './index.reducer'; import { AddToIndexAction, RemoveFromIndexBySubstringAction, RemoveFromIndexByValueAction } from './index.actions'; +import { IndexName } from './index-name.model'; class NullAction extends AddToIndexAction { type = null; diff --git a/src/app/core/index/index.reducer.ts b/src/app/core/index/index.reducer.ts index 80cb322c75d..21819d67baf 100644 --- a/src/app/core/index/index.reducer.ts +++ b/src/app/core/index/index.reducer.ts @@ -1,28 +1,5 @@ -import { - AddToIndexAction, - IndexAction, - IndexActionTypes, - RemoveFromIndexBySubstringAction, - RemoveFromIndexByValueAction -} from './index.actions'; - -/** - * An enum containing all index names - */ -export enum IndexName { - // Contains all objects in the object cache indexed by UUID - OBJECT = 'object/uuid-to-self-link', - - // contains all requests in the request cache indexed by UUID - REQUEST = 'get-request/href-to-uuid', - - /** - * Contains the alternative link for an objects - * Maps these link on to their matching self link in the object cache - * Eg. /workspaceitems/12/item --> /items/12345 - */ - ALTERNATIVE_OBJECT_LINK = 'object/alt-link-to-self-link' -} +import { AddToIndexAction, IndexAction, IndexActionTypes, RemoveFromIndexBySubstringAction, RemoveFromIndexByValueAction } from './index.actions'; +import { IndexName } from './index-name.model'; /** * The state of a single index diff --git a/src/app/core/index/index.selectors.ts b/src/app/core/index/index.selectors.ts index 9b570643889..435398d0a42 100644 --- a/src/app/core/index/index.selectors.ts +++ b/src/app/core/index/index.selectors.ts @@ -3,8 +3,9 @@ import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { URLCombiner } from '../url-combiner/url-combiner'; -import { IndexName, IndexState, MetaIndexState } from './index.reducer'; +import { IndexState, MetaIndexState } from './index.reducer'; import * as parse from 'url-parse'; +import { IndexName } from './index-name.model'; /** * Return the given url without `embed` params. diff --git a/src/app/core/resource-policy/models/resource-policy.model.ts b/src/app/core/resource-policy/models/resource-policy.model.ts index 94ae2c41a34..b0608dfbcaf 100644 --- a/src/app/core/resource-policy/models/resource-policy.model.ts +++ b/src/app/core/resource-policy/models/resource-policy.model.ts @@ -2,7 +2,6 @@ import { autoserialize, deserialize, deserializeAs } from 'cerialize'; import { link, typedObject } from '../../cache/builders/build-decorators'; import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer'; import { ActionType } from './action-type.model'; -import { CacheableObject } from '../../cache/object-cache.reducer'; import { HALLink } from '../../shared/hal-link.model'; import { RESOURCE_POLICY } from './resource-policy.resource-type'; import { excludeFromEquals } from '../../utilities/equals.decorators'; @@ -14,6 +13,7 @@ import { GROUP } from '../../eperson/models/group.resource-type'; import { Group } from '../../eperson/models/group.model'; import { EPERSON } from '../../eperson/models/eperson.resource-type'; import { EPerson } from '../../eperson/models/eperson.model'; +import { CacheableObject } from '../../cache/cacheable-object.model'; /** * Model class for a Resource Policy diff --git a/src/app/core/shared/authorized.operators.ts b/src/app/core/shared/authorized.operators.ts new file mode 100644 index 00000000000..c36f0f41d23 --- /dev/null +++ b/src/app/core/shared/authorized.operators.ts @@ -0,0 +1,91 @@ +import { Router, UrlTree } from '@angular/router'; +import { AuthService } from '../auth/auth.service'; +import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; +import { filter, map, withLatestFrom } from 'rxjs/operators'; +import { InjectionToken } from '@angular/core'; +import { RemoteData } from '../data/remote-data'; +import { getEndUserAgreementPath } from '../../info/info-routing-paths'; +import { getForbiddenRoute, getPageNotFoundRoute } from '../../app-routing-paths'; + +export const REDIRECT_ON_4XX = new InjectionToken<(router: Router, authService: AuthService) => (source: Observable>) => Observable>>('redirectOn4xx', { + providedIn: 'root', + factory: () => redirectOn4xx +}); +/** + * Operator that checks if a remote data object returned a 4xx error + * When it does contain such an error, it will redirect the user to the related error page, without + * altering the current URL + * + * @param router The router used to navigate to a new page + * @param authService Service to check if the user is authenticated + */ +export const redirectOn4xx = (router: Router, authService: AuthService) => + (source: Observable>): Observable> => + source.pipe( + withLatestFrom(authService.isAuthenticated()), + filter(([rd, isAuthenticated]: [RemoteData, boolean]) => { + if (rd.hasFailed) { + if (rd.statusCode === 404 || rd.statusCode === 422) { + router.navigateByUrl(getPageNotFoundRoute(), { skipLocationChange: true }); + return false; + } else if (rd.statusCode === 403 || rd.statusCode === 401) { + if (isAuthenticated) { + router.navigateByUrl(getForbiddenRoute(), { skipLocationChange: true }); + return false; + } else { + authService.setRedirectUrl(router.url); + router.navigateByUrl('login'); + return false; + } + } + } + return true; + }), + map(([rd,]: [RemoteData, boolean]) => rd) + ); +/** + * Operator that returns a UrlTree to a forbidden page or the login page when the boolean received is false + * @param router The router used to navigate to a forbidden page + * @param authService The AuthService used to determine whether or not the user is logged in + * @param redirectUrl The URL to redirect back to after logging in + */ +export const returnForbiddenUrlTreeOrLoginOnFalse = (router: Router, authService: AuthService, redirectUrl: string) => + (source: Observable): Observable => + source.pipe( + map((authorized) => [authorized]), + returnForbiddenUrlTreeOrLoginOnAllFalse(router, authService, redirectUrl), + ); +/** + * Operator that returns a UrlTree to a forbidden page or the login page when the booleans received are all false + * @param router The router used to navigate to a forbidden page + * @param authService The AuthService used to determine whether or not the user is logged in + * @param redirectUrl The URL to redirect back to after logging in + */ +export const returnForbiddenUrlTreeOrLoginOnAllFalse = (router: Router, authService: AuthService, redirectUrl: string) => + (source: Observable): Observable => + observableCombineLatest(source, authService.isAuthenticated()).pipe( + map(([authorizedList, authenticated]: [boolean[], boolean]) => { + if (authorizedList.some((b: boolean) => b === true)) { + return true; + } else { + if (authenticated) { + return router.parseUrl(getForbiddenRoute()); + } else { + authService.setRedirectUrl(redirectUrl); + return router.parseUrl('login'); + } + } + })); +/** + * Operator that returns a UrlTree to the unauthorized page when the boolean received is false + * @param router Router + * @param redirect Redirect URL to add to the UrlTree. This is used to redirect back to the original route after the + * user accepts the agreement. + */ +export const returnEndUserAgreementUrlTreeOnFalse = (router: Router, redirect: string) => + (source: Observable): Observable => + source.pipe( + map((hasAgreed: boolean) => { + const queryParams = { redirect: encodeURIComponent(redirect) }; + return hasAgreed ? hasAgreed : router.createUrlTree([getEndUserAgreementPath()], { queryParams }); + })); diff --git a/src/app/core/shared/bitstream-format.model.ts b/src/app/core/shared/bitstream-format.model.ts index 24a06463160..9e8dc5e1fe8 100644 --- a/src/app/core/shared/bitstream-format.model.ts +++ b/src/app/core/shared/bitstream-format.model.ts @@ -1,12 +1,12 @@ import { autoserialize, deserialize, deserializeAs } from 'cerialize'; import { typedObject } from '../cache/builders/build-decorators'; import { IDToUUIDSerializer } from '../cache/id-to-uuid-serializer'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { BitstreamFormatSupportLevel } from './bitstream-format-support-level'; import { BITSTREAM_FORMAT } from './bitstream-format.resource-type'; import { HALLink } from './hal-link.model'; import { ResourceType } from './resource-type'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * Model class for a Bitstream Format diff --git a/src/app/core/shared/browse-definition.model.ts b/src/app/core/shared/browse-definition.model.ts index 2c08417b6d7..8a13beae210 100644 --- a/src/app/core/shared/browse-definition.model.ts +++ b/src/app/core/shared/browse-definition.model.ts @@ -1,11 +1,11 @@ import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; import { typedObject } from '../cache/builders/build-decorators'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { BROWSE_DEFINITION } from './browse-definition.resource-type'; import { HALLink } from './hal-link.model'; import { ResourceType } from './resource-type'; import { SortOption } from './sort-option.model'; +import { CacheableObject } from '../cache/cacheable-object.model'; @typedObject export class BrowseDefinition extends CacheableObject { diff --git a/src/app/core/shared/browse-entry.model.ts b/src/app/core/shared/browse-entry.model.ts index 9ae28ac2f09..df748ac61c8 100644 --- a/src/app/core/shared/browse-entry.model.ts +++ b/src/app/core/shared/browse-entry.model.ts @@ -1,12 +1,12 @@ import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; import { typedObject } from '../cache/builders/build-decorators'; -import { TypedObject } from '../cache/object-cache.reducer'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { BROWSE_ENTRY } from './browse-entry.resource-type'; import { GenericConstructor } from './generic-constructor'; import { HALLink } from './hal-link.model'; import { ResourceType } from './resource-type'; +import { TypedObject } from '../cache/typed-object.model'; /** * Class object representing a browse entry diff --git a/src/app/core/shared/configuration-property.model.ts b/src/app/core/shared/configuration-property.model.ts index 465523c29f2..874e80f08db 100644 --- a/src/app/core/shared/configuration-property.model.ts +++ b/src/app/core/shared/configuration-property.model.ts @@ -1,10 +1,10 @@ import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; import { typedObject } from '../cache/builders/build-decorators'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { HALLink } from './hal-link.model'; import { ResourceType } from './resource-type'; import { CONFIG_PROPERTY } from './config-property.resource-type'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * Model class for a Configuration Property diff --git a/src/app/core/shared/content-source.model.ts b/src/app/core/shared/content-source.model.ts index 326407822f5..10806cf5b4c 100644 --- a/src/app/core/shared/content-source.model.ts +++ b/src/app/core/shared/content-source.model.ts @@ -1,11 +1,11 @@ import { autoserializeAs, deserializeAs, deserialize } from 'cerialize'; import { HALLink } from './hal-link.model'; import { MetadataConfig } from './metadata-config.model'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { typedObject } from '../cache/builders/build-decorators'; import { CONTENT_SOURCE } from './content-source.resource-type'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { ResourceType } from './resource-type'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * The type of content harvesting used diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index 5ea2bced3d3..6f5d45544df 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -2,7 +2,6 @@ import { autoserialize, autoserializeAs, deserialize, deserializeAs } from 'ceri import { hasNoValue, hasValue, isUndefined } from '../../shared/empty.util'; import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; import { typedObject } from '../cache/builders/build-decorators'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { DSPACE_OBJECT } from './dspace-object.resource-type'; import { GenericConstructor } from './generic-constructor'; @@ -16,6 +15,7 @@ import { } from './metadata.models'; import { Metadata } from './metadata.utils'; import { ResourceType } from './resource-type'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * An abstract model class for a DSpaceObject. diff --git a/src/app/core/shared/external-source.model.ts b/src/app/core/shared/external-source.model.ts index e28c8953e90..f6011a08bc3 100644 --- a/src/app/core/shared/external-source.model.ts +++ b/src/app/core/shared/external-source.model.ts @@ -1,10 +1,10 @@ import { autoserialize, deserialize } from 'cerialize'; import { typedObject } from '../cache/builders/build-decorators'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { EXTERNAL_SOURCE } from './external-source.resource-type'; import { HALLink } from './hal-link.model'; import { ResourceType } from './resource-type'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * Model class for an external source diff --git a/src/app/core/shared/item-relationships/item-type.model.ts b/src/app/core/shared/item-relationships/item-type.model.ts index d41024cdaa0..c51c3b9035b 100644 --- a/src/app/core/shared/item-relationships/item-type.model.ts +++ b/src/app/core/shared/item-relationships/item-type.model.ts @@ -1,11 +1,11 @@ import { autoserialize, deserialize, deserializeAs } from 'cerialize'; import { typedObject } from '../../cache/builders/build-decorators'; import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer'; -import { CacheableObject } from '../../cache/object-cache.reducer'; import { excludeFromEquals } from '../../utilities/equals.decorators'; import { HALLink } from '../hal-link.model'; import { ResourceType } from '../resource-type'; import { ITEM_TYPE } from './item-type.resource-type'; +import { CacheableObject } from '../../cache/cacheable-object.model'; /** * Describes a type of Item diff --git a/src/app/core/shared/item-relationships/relationship-type.model.ts b/src/app/core/shared/item-relationships/relationship-type.model.ts index fb62f685dd1..73e3a7b47c6 100644 --- a/src/app/core/shared/item-relationships/relationship-type.model.ts +++ b/src/app/core/shared/item-relationships/relationship-type.model.ts @@ -2,7 +2,6 @@ import { autoserialize, deserialize, deserializeAs } from 'cerialize'; import { Observable } from 'rxjs'; import { link, typedObject } from '../../cache/builders/build-decorators'; import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer'; -import { CacheableObject } from '../../cache/object-cache.reducer'; import { RemoteData } from '../../data/remote-data'; import { excludeFromEquals } from '../../utilities/equals.decorators'; import { HALLink } from '../hal-link.model'; @@ -10,6 +9,7 @@ import { ResourceType } from '../resource-type'; import { ItemType } from './item-type.model'; import { ITEM_TYPE } from './item-type.resource-type'; import { RELATIONSHIP_TYPE } from './relationship-type.resource-type'; +import { CacheableObject } from '../../cache/cacheable-object.model'; /** * Describes a type of Relationship between multiple possible Items diff --git a/src/app/core/shared/item-relationships/relationship.model.ts b/src/app/core/shared/item-relationships/relationship.model.ts index b85d6e1b8ef..db12e1d8621 100644 --- a/src/app/core/shared/item-relationships/relationship.model.ts +++ b/src/app/core/shared/item-relationships/relationship.model.ts @@ -2,7 +2,6 @@ import { autoserialize, deserialize, deserializeAs } from 'cerialize'; import { Observable } from 'rxjs'; import { link, typedObject } from '../../cache/builders/build-decorators'; import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer'; -import { CacheableObject } from '../../cache/object-cache.reducer'; import { RemoteData } from '../../data/remote-data'; import { excludeFromEquals } from '../../utilities/equals.decorators'; import { HALLink } from '../hal-link.model'; @@ -12,6 +11,7 @@ import { ResourceType } from '../resource-type'; import { RelationshipType } from './relationship-type.model'; import { RELATIONSHIP_TYPE } from './relationship-type.resource-type'; import { RELATIONSHIP } from './relationship.resource-type'; +import { CacheableObject } from '../../cache/cacheable-object.model'; /** * Describes a Relationship between two Items diff --git a/src/app/core/shared/operators.spec.ts b/src/app/core/shared/operators.spec.ts index 6fd15ceacc3..eb102065cd7 100644 --- a/src/app/core/shared/operators.spec.ts +++ b/src/app/core/shared/operators.spec.ts @@ -5,20 +5,17 @@ import { GetRequest } from '../data/request.models'; import { RequestEntry } from '../data/request.reducer'; import { RequestService } from '../data/request.service'; import { - sendRequest, getAllSucceededRemoteData, getFirstSucceededRemoteData, - getRemoteDataPayload, - getRequestFromRequestHref, - getRequestFromRequestUUID, - getResponseFromEntry, - redirectOn4xx + getRemoteDataPayload } from './operators'; import { of as observableOf } from 'rxjs'; import { createFailedRemoteDataObject, createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; +import { getRequestFromRequestHref, getRequestFromRequestUUID, getResponseFromEntry, sendRequest } from './request.operators'; +import { redirectOn4xx } from './authorized.operators'; // tslint:disable:no-shadowed-variable diff --git a/src/app/core/shared/operators.ts b/src/app/core/shared/operators.ts index 3be04447ab8..3be8afb597e 100644 --- a/src/app/core/shared/operators.ts +++ b/src/app/core/shared/operators.ts @@ -1,31 +1,13 @@ -import { Router, UrlTree } from '@angular/router'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; -import { - debounceTime, - filter, - find, - map, - mergeMap, - switchMap, - take, - takeWhile, - tap, - withLatestFrom -} from 'rxjs/operators'; +import { debounceTime, filter, find, map, switchMap, take, takeWhile } from 'rxjs/operators'; import { hasNoValue, hasValue, hasValueOperator, isNotEmpty } from '../../shared/empty.util'; import { SearchResult } from '../../shared/search/search-result.model'; import { PaginatedList } from '../data/paginated-list.model'; import { RemoteData } from '../data/remote-data'; -import { RestRequest } from '../data/request.models'; -import { RequestEntry, ResponseState } from '../data/request.reducer'; -import { RequestService } from '../data/request.service'; import { MetadataField } from '../metadata/metadata-field.model'; import { MetadataSchema } from '../metadata/metadata-schema.model'; import { BrowseDefinition } from './browse-definition.model'; import { DSpaceObject } from './dspace-object.model'; -import { getForbiddenRoute, getPageNotFoundRoute } from '../../app-routing-paths'; -import { getEndUserAgreementPath } from '../../info/info-routing-paths'; -import { AuthService } from '../auth/auth.service'; import { InjectionToken } from '@angular/core'; export const DEBOUNCE_TIME_OPERATOR = new InjectionToken<(dueTime: number) => (source: Observable) => Observable>('debounceTime', { @@ -33,40 +15,6 @@ export const DEBOUNCE_TIME_OPERATOR = new InjectionToken<(dueTime: number) => factory: () => debounceTime }); -export const REDIRECT_ON_4XX = new InjectionToken<(router: Router, authService: AuthService) => (source: Observable>) => Observable>>('redirectOn4xx', { - providedIn: 'root', - factory: () => redirectOn4xx -}); - -/** - * This file contains custom RxJS operators that can be used in multiple places - */ - -export const getRequestFromRequestHref = (requestService: RequestService) => - (source: Observable): Observable => - source.pipe( - mergeMap((href: string) => requestService.getByHref(href)), - hasValueOperator() - ); - -export const getRequestFromRequestUUID = (requestService: RequestService) => - (source: Observable): Observable => - source.pipe( - mergeMap((uuid: string) => requestService.getByUUID(uuid)), - hasValueOperator() - ); - -export const getResponseFromEntry = () => - (source: Observable): Observable => - source.pipe( - filter((entry: RequestEntry) => hasValue(entry) && hasValue(entry.response)), - map((entry: RequestEntry) => entry.response) - ); - -export const sendRequest = (requestService: RequestService) => - (source: Observable): Observable => - source.pipe(tap((request: RestRequest) => requestService.send(request))); - export const getRemoteDataPayload = () => (source: Observable>): Observable => source.pipe(map((remoteData: RemoteData) => remoteData.payload)); @@ -190,88 +138,6 @@ export const getAllSucceededRemoteListPayload = () => getPaginatedListPayload() ); -/** - * Operator that checks if a remote data object returned a 4xx error - * When it does contain such an error, it will redirect the user to the related error page, without - * altering the current URL - * - * @param router The router used to navigate to a new page - * @param authService Service to check if the user is authenticated - */ -export const redirectOn4xx = (router: Router, authService: AuthService) => - (source: Observable>): Observable> => - source.pipe( - withLatestFrom(authService.isAuthenticated()), - filter(([rd, isAuthenticated]: [RemoteData, boolean]) => { - if (rd.hasFailed) { - if (rd.statusCode === 404 || rd.statusCode === 422) { - router.navigateByUrl(getPageNotFoundRoute(), { skipLocationChange: true }); - return false; - } else if (rd.statusCode === 403 || rd.statusCode === 401) { - if (isAuthenticated) { - router.navigateByUrl(getForbiddenRoute(), { skipLocationChange: true }); - return false; - } else { - authService.setRedirectUrl(router.url); - router.navigateByUrl('login'); - return false; - } - } - } - return true; - }), - map(([rd,]: [RemoteData, boolean]) => rd) - ); - -/** - * Operator that returns a UrlTree to a forbidden page or the login page when the boolean received is false - * @param router The router used to navigate to a forbidden page - * @param authService The AuthService used to determine whether or not the user is logged in - * @param redirectUrl The URL to redirect back to after logging in - */ -export const returnForbiddenUrlTreeOrLoginOnFalse = (router: Router, authService: AuthService, redirectUrl: string) => - (source: Observable): Observable => - source.pipe( - map((authorized) => [authorized]), - returnForbiddenUrlTreeOrLoginOnAllFalse(router, authService, redirectUrl), - ); - -/** - * Operator that returns a UrlTree to a forbidden page or the login page when the booleans received are all false - * @param router The router used to navigate to a forbidden page - * @param authService The AuthService used to determine whether or not the user is logged in - * @param redirectUrl The URL to redirect back to after logging in - */ -export const returnForbiddenUrlTreeOrLoginOnAllFalse = (router: Router, authService: AuthService, redirectUrl: string) => - (source: Observable): Observable => - observableCombineLatest(source, authService.isAuthenticated()).pipe( - map(([authorizedList, authenticated]: [boolean[], boolean]) => { - if (authorizedList.some((b: boolean) => b === true)) { - return true; - } else { - if (authenticated) { - return router.parseUrl(getForbiddenRoute()); - } else { - authService.setRedirectUrl(redirectUrl); - return router.parseUrl('login'); - } - } - })); - -/** - * Operator that returns a UrlTree to the unauthorized page when the boolean received is false - * @param router Router - * @param redirect Redirect URL to add to the UrlTree. This is used to redirect back to the original route after the - * user accepts the agreement. - */ -export const returnEndUserAgreementUrlTreeOnFalse = (router: Router, redirect: string) => - (source: Observable): Observable => - source.pipe( - map((hasAgreed: boolean) => { - const queryParams = { redirect: encodeURIComponent(redirect) }; - return hasAgreed ? hasAgreed : router.createUrlTree([getEndUserAgreementPath()], { queryParams }); - })); - export const getFinishedRemoteData = () => (source: Observable>): Observable> => source.pipe(find((rd: RemoteData) => !rd.isLoading)); diff --git a/src/app/core/shared/request.operators.ts b/src/app/core/shared/request.operators.ts new file mode 100644 index 00000000000..3caba824b94 --- /dev/null +++ b/src/app/core/shared/request.operators.ts @@ -0,0 +1,32 @@ +import { RequestService } from '../data/request.service'; +import { Observable } from 'rxjs'; +import { RestRequest } from '../data/request.models'; +import { filter, map, mergeMap, tap } from 'rxjs/operators'; +import { RequestEntry, ResponseState } from '../data/request.reducer'; +import { hasValue, hasValueOperator } from '../../shared/empty.util'; + +/** + * This file contains custom RxJS operators that can be used in multiple places + */ + +export const getRequestFromRequestHref = (requestService: RequestService) => + (source: Observable): Observable => + source.pipe( + mergeMap((href: string) => requestService.getByHref(href)), + hasValueOperator() + ); +export const getRequestFromRequestUUID = (requestService: RequestService) => + (source: Observable): Observable => + source.pipe( + mergeMap((uuid: string) => requestService.getByUUID(uuid)), + hasValueOperator() + ); +export const getResponseFromEntry = () => + (source: Observable): Observable => + source.pipe( + filter((entry: RequestEntry) => hasValue(entry) && hasValue(entry.response)), + map((entry: RequestEntry) => entry.response) + ); +export const sendRequest = (requestService: RequestService) => + (source: Observable): Observable => + source.pipe(tap((request: RestRequest) => requestService.send(request))); diff --git a/src/app/core/shared/search/search-configuration.service.spec.ts b/src/app/core/shared/search/search-configuration.service.spec.ts index 805ecd0486b..30be28f65fd 100644 --- a/src/app/core/shared/search/search-configuration.service.spec.ts +++ b/src/app/core/shared/search/search-configuration.service.spec.ts @@ -4,8 +4,16 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio import { SortDirection, SortOptions } from '../../cache/models/sort-options.model'; import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model'; import { SearchFilter } from '../../../shared/search/search-filter.model'; -import { of as observableOf } from 'rxjs'; +import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { HALEndpointServiceStub } from '../../../shared/testing/hal-endpoint-service.stub'; +import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock'; +import { RequestEntry } from '../../data/request.reducer'; +import { map } from 'rxjs/operators'; +import { RemoteData } from '../../data/remote-data'; +import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; +import { SearchObjects } from '../../../shared/search/search-objects.model'; +import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; describe('SearchConfigurationService', () => { let service: SearchConfigurationService; @@ -38,10 +46,37 @@ describe('SearchConfigurationService', () => { const activatedRoute: any = new ActivatedRouteStub(); + const linkService: any = {}; + const requestService: any = getMockRequestService(); + const halService: any = { + /* tslint:disable:no-empty */ + getEndpoint: () => { + } + /* tslint:enable:no-empty */ + }; + + const rdb: any = { + toRemoteDataObservable: (requestEntryObs: Observable, payloadObs: Observable) => { + return observableCombineLatest([requestEntryObs, payloadObs]).pipe( + map(([req, pay]) => { + return { req, pay }; + }) + ); + }, + aggregate: (input: Observable>[]): Observable> => { + return createSuccessfulRemoteDataObject$([]); + }, + buildFromHref: (href: string): Observable> => { + return createSuccessfulRemoteDataObject$(Object.assign(new SearchObjects(), { + page: [] + })); + } + }; beforeEach(() => { - service = new SearchConfigurationService(routeService, paginationService as any, activatedRoute); + service = new SearchConfigurationService(routeService, paginationService as any, activatedRoute, linkService, halService, requestService, rdb); }); + describe('when the scope is called', () => { beforeEach(() => { service.getCurrentScope(''); @@ -160,4 +195,100 @@ describe('SearchConfigurationService', () => { }); }); + describe('when getSearchConfigurationFor is called with a scope', () => { + const endPoint = 'http://endpoint.com/test/config'; + const scope = 'test'; + const requestUrl = endPoint + '?scope=' + scope; + beforeEach(() => { + spyOn((service as any).halService, 'getEndpoint').and.returnValue(observableOf(endPoint)); + /* tslint:disable:no-empty */ + service.getSearchConfigurationFor(scope).subscribe((t) => { + }); // subscribe to make sure all methods are called + /* tslint:enable:no-empty */ + }); + + it('should call getEndpoint on the halService', () => { + expect((service as any).halService.getEndpoint).toHaveBeenCalled(); + }); + + it('should send out the request on the request service', () => { + expect((service as any).requestService.send).toHaveBeenCalled(); + }); + + it('should call send containing a request with the correct request url', () => { + expect((service as any).requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({ href: requestUrl }), true); + }); + }); + + describe('when getSearchConfigurationFor is called without a scope', () => { + const endPoint = 'http://endpoint.com/test/config'; + beforeEach(() => { + spyOn((service as any).halService, 'getEndpoint').and.returnValue(observableOf(endPoint)); + spyOn((service as any).rdb, 'buildFromHref').and.callThrough(); + /* tslint:disable:no-empty */ + service.getSearchConfigurationFor(null).subscribe((t) => { + }); // subscribe to make sure all methods are called + /* tslint:enable:no-empty */ + }); + + it('should call getEndpoint on the halService', () => { + expect((service as any).halService.getEndpoint).toHaveBeenCalled(); + }); + + it('should send out the request on the request service', () => { + expect((service as any).requestService.send).toHaveBeenCalled(); + }); + + it('should call send containing a request with the correct request url', () => { + expect((service as any).requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({ href: endPoint }), true); + }); + }); + describe('when getConfig is called without a scope', () => { + const endPoint = 'http://endpoint.com/test/config'; + beforeEach(() => { + spyOn((service as any).halService, 'getEndpoint').and.returnValue(observableOf(endPoint)); + spyOn((service as any).rdb, 'buildFromHref').and.callThrough(); + /* tslint:disable:no-empty */ + service.getConfig(null).subscribe((t) => { + }); // subscribe to make sure all methods are called + /* tslint:enable:no-empty */ + }); + + it('should call getEndpoint on the halService', () => { + expect((service as any).halService.getEndpoint).toHaveBeenCalled(); + }); + + it('should send out the request on the request service', () => { + expect((service as any).requestService.send).toHaveBeenCalled(); + }); + + it('should call send containing a request with the correct request url', () => { + expect((service as any).requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({ href: endPoint }), true); + }); + }); + + describe('when getConfig is called with a scope', () => { + const endPoint = 'http://endpoint.com/test/config'; + const scope = 'test'; + const requestUrl = endPoint + '?scope=' + scope; + beforeEach(() => { + spyOn((service as any).halService, 'getEndpoint').and.returnValue(observableOf(endPoint)); + /* tslint:disable:no-empty */ + service.getConfig(scope).subscribe((t) => { + }); // subscribe to make sure all methods are called + /* tslint:enable:no-empty */ + }); + + it('should call getEndpoint on the halService', () => { + expect((service as any).halService.getEndpoint).toHaveBeenCalled(); + }); + + it('should send out the request on the request service', () => { + expect((service as any).requestService.send).toHaveBeenCalled(); + }); + + it('should call send containing a request with the correct request url', () => { + expect((service as any).requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({ href: requestUrl }), true); + }); + }); }); diff --git a/src/app/core/shared/search/search-configuration.service.ts b/src/app/core/shared/search/search-configuration.service.ts index 74af230810e..d62e5ea01bb 100644 --- a/src/app/core/shared/search/search-configuration.service.ts +++ b/src/app/core/shared/search/search-configuration.service.ts @@ -1,14 +1,7 @@ import { Injectable, OnDestroy } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; -import { - BehaviorSubject, - combineLatest, - combineLatest as observableCombineLatest, - merge as observableMerge, - Observable, - Subscription -} from 'rxjs'; +import { BehaviorSubject, combineLatest, combineLatest as observableCombineLatest, merge as observableMerge, Observable, Subscription } from 'rxjs'; import { distinctUntilChanged, filter, map, startWith, switchMap, take } from 'rxjs/operators'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SearchOptions } from '../../../shared/search/search-options.model'; @@ -18,16 +11,23 @@ import { RemoteData } from '../../data/remote-data'; import { DSpaceObjectType } from '../dspace-object-type.model'; import { SortDirection, SortOptions } from '../../cache/models/sort-options.model'; import { RouteService } from '../../services/route.service'; -import { - getAllSucceededRemoteDataPayload, - getFirstSucceededRemoteData -} from '../operators'; +import { getAllSucceededRemoteDataPayload, getFirstSucceededRemoteData } from '../operators'; import { hasNoValue, hasValue, isNotEmpty, isNotEmptyOperator } from '../../../shared/empty.util'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { SearchConfig } from './search-filters/search-config.model'; -import { SearchService } from './search.service'; import { of } from 'rxjs/internal/observable/of'; import { PaginationService } from '../../pagination/pagination.service'; +import { LinkService } from '../../cache/builders/link.service'; +import { HALEndpointService } from '../hal-endpoint.service'; +import { RequestService } from '../../data/request.service'; +import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; +import { GetRequest } from '../../data/request.models'; +import { URLCombiner } from '../../url-combiner/url-combiner'; +import { SearchFilterConfig } from '../../../shared/search/search-filter-config.model'; +import { GenericConstructor } from '../generic-constructor'; +import { ResponseParsingService } from '../../data/parsing.service'; +import { FacetConfigResponseParsingService } from '../../data/facet-config-response-parsing.service'; +import { FacetConfigResponse } from '../../../shared/search/facet-config-response.model'; /** * Service that performs all actions that have to do with the current search configuration @@ -35,6 +35,16 @@ import { PaginationService } from '../../pagination/pagination.service'; @Injectable() export class SearchConfigurationService implements OnDestroy { + /** + * Endpoint link path for retrieving search configurations + */ + private configurationLinkPath = 'discover/search'; + + /** + * Endpoint link path for retrieving facet config incl values + */ + private facetLinkPathPrefix = 'discover/facets/'; + public paginationID = 'spc'; /** * Default pagination settings @@ -88,11 +98,20 @@ export class SearchConfigurationService implements OnDestroy { /** * Initialize the search options * @param {RouteService} routeService + * @param paginationService * @param {ActivatedRoute} route + * @param linkService + * @param halService + * @param requestService + * @param rdb */ constructor(protected routeService: RouteService, protected paginationService: PaginationService, - protected route: ActivatedRoute) { + protected route: ActivatedRoute, + protected linkService: LinkService, + protected halService: HALEndpointService, + protected requestService: RequestService, + protected rdb: RemoteDataBuildService,) { this.initDefaults(); } @@ -212,10 +231,10 @@ export class SearchConfigurationService implements OnDestroy { * @param configuration$ * @param service */ - getConfigurationSearchConfigObservable(configuration$: Observable, service: SearchService): Observable { + getConfigurationSearchConfigObservable(configuration$: Observable): Observable { return configuration$.pipe( distinctUntilChanged(), - switchMap((configuration) => service.getSearchConfigurationFor(null, configuration)), + switchMap((configuration) => this.getSearchConfigurationFor(null, configuration)), getAllSucceededRemoteDataPayload()); } @@ -404,4 +423,93 @@ export class SearchConfigurationService implements OnDestroy { }), ); } + + + /** + * Request the search configuration for a given scope or the whole repository + * @param {string} scope UUID of the object for which config the filter config is requested, when no scope is provided the configuration for the whole repository is loaded + * @param {string} configurationName the name of the configuration + * @returns {Observable>} The found configuration + */ + getSearchConfigurationFor(scope?: string, configurationName?: string): Observable> { + const href$ = this.halService.getEndpoint(this.configurationLinkPath).pipe( + map((url: string) => this.getConfigUrl(url, scope, configurationName)), + ); + + href$.pipe(take(1)).subscribe((url: string) => { + const request = new GetRequest(this.requestService.generateRequestId(), url); + this.requestService.send(request, true); + }); + + return this.rdb.buildFromHref(href$); + } + + private getConfigUrl(url: string, scope?: string, configurationName?: string) { + const args: string[] = []; + + if (isNotEmpty(scope)) { + args.push(`scope=${scope}`); + } + + if (isNotEmpty(configurationName)) { + args.push(`configuration=${configurationName}`); + } + + if (isNotEmpty(args)) { + url = new URLCombiner(url, `?${args.join('&')}`).toString(); + } + + return url; + } + + + + /** + * Request the filter configuration for a given scope or the whole repository + * @param {string} scope UUID of the object for which config the filter config is requested, when no scope is provided the configuration for the whole repository is loaded + * @param {string} configurationName the name of the configuration + * @returns {Observable>} The found filter configuration + */ + getConfig(scope?: string, configurationName?: string): Observable> { + const href$ = this.halService.getEndpoint(this.facetLinkPathPrefix).pipe( + map((url: string) => this.getConfigUrl(url, scope, configurationName)), + ); + + href$.pipe(take(1)).subscribe((url: string) => { + let request = new GetRequest(this.requestService.generateRequestId(), url); + request = Object.assign(request, { + getResponseParser(): GenericConstructor { + return FacetConfigResponseParsingService; + } + }); + this.requestService.send(request, true); + }); + + return this.rdb.buildFromHref(href$).pipe( + map((rd: RemoteData) => { + if (rd.hasSucceeded) { + let filters: SearchFilterConfig[]; + if (isNotEmpty(rd.payload.filters)) { + filters = rd.payload.filters + .map((filter: any) => Object.assign(new SearchFilterConfig(), filter)); + } else { + filters = []; + } + + return new RemoteData( + rd.timeCompleted, + rd.msToLive, + rd.lastUpdated, + rd.state, + rd.errorMessage, + filters, + rd.statusCode, + ); + } else { + return rd as any as RemoteData; + } + }) + ); + } + } diff --git a/src/app/core/shared/search/search-filters/search-config.model.ts b/src/app/core/shared/search/search-filters/search-config.model.ts index 725761fe7be..abcec6dd1eb 100644 --- a/src/app/core/shared/search/search-filters/search-config.model.ts +++ b/src/app/core/shared/search/search-filters/search-config.model.ts @@ -2,9 +2,9 @@ import { autoserialize, deserialize } from 'cerialize'; import { SEARCH_CONFIG } from './search-config.resource-type'; import { typedObject } from '../../../cache/builders/build-decorators'; -import { CacheableObject } from '../../../cache/object-cache.reducer'; import { HALLink } from '../../hal-link.model'; import { ResourceType } from '../../resource-type'; +import { CacheableObject } from '../../../cache/cacheable-object.model'; /** * The configuration for a search diff --git a/src/app/core/shared/search/search.service.spec.ts b/src/app/core/shared/search/search.service.spec.ts index 00f10230c3c..d41f6d8d721 100644 --- a/src/app/core/shared/search/search.service.spec.ts +++ b/src/app/core/shared/search/search.service.spec.ts @@ -191,104 +191,5 @@ describe('SearchService', () => { expect((searchService as any).rdb.buildFromHref).toHaveBeenCalledWith(endPoint); }); }); - - describe('when getConfig is called without a scope', () => { - const endPoint = 'http://endpoint.com/test/config'; - beforeEach(() => { - spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(observableOf(endPoint)); - spyOn((searchService as any).rdb, 'buildFromHref').and.callThrough(); - /* tslint:disable:no-empty */ - searchService.getConfig(null).subscribe((t) => { - }); // subscribe to make sure all methods are called - /* tslint:enable:no-empty */ - }); - - it('should call getEndpoint on the halService', () => { - expect((searchService as any).halService.getEndpoint).toHaveBeenCalled(); - }); - - it('should send out the request on the request service', () => { - expect((searchService as any).requestService.send).toHaveBeenCalled(); - }); - - it('should call send containing a request with the correct request url', () => { - expect((searchService as any).requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({ href: endPoint }), true); - }); - }); - - describe('when getConfig is called with a scope', () => { - const endPoint = 'http://endpoint.com/test/config'; - const scope = 'test'; - const requestUrl = endPoint + '?scope=' + scope; - beforeEach(() => { - spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(observableOf(endPoint)); - /* tslint:disable:no-empty */ - searchService.getConfig(scope).subscribe((t) => { - }); // subscribe to make sure all methods are called - /* tslint:enable:no-empty */ - }); - - it('should call getEndpoint on the halService', () => { - expect((searchService as any).halService.getEndpoint).toHaveBeenCalled(); - }); - - it('should send out the request on the request service', () => { - expect((searchService as any).requestService.send).toHaveBeenCalled(); - }); - - it('should call send containing a request with the correct request url', () => { - expect((searchService as any).requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({ href: requestUrl }), true); - }); - }); - - describe('when getSearchConfigurationFor is called without a scope', () => { - const endPoint = 'http://endpoint.com/test/config'; - beforeEach(() => { - spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(observableOf(endPoint)); - spyOn((searchService as any).rdb, 'buildFromHref').and.callThrough(); - /* tslint:disable:no-empty */ - searchService.getSearchConfigurationFor(null).subscribe((t) => { - }); // subscribe to make sure all methods are called - /* tslint:enable:no-empty */ - }); - - it('should call getEndpoint on the halService', () => { - expect((searchService as any).halService.getEndpoint).toHaveBeenCalled(); - }); - - it('should send out the request on the request service', () => { - expect((searchService as any).requestService.send).toHaveBeenCalled(); - }); - - it('should call send containing a request with the correct request url', () => { - expect((searchService as any).requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({ href: endPoint }), true); - }); - }); - - describe('when getSearchConfigurationFor is called with a scope', () => { - const endPoint = 'http://endpoint.com/test/config'; - const scope = 'test'; - const requestUrl = endPoint + '?scope=' + scope; - beforeEach(() => { - spyOn((searchService as any).halService, 'getEndpoint').and.returnValue(observableOf(endPoint)); - /* tslint:disable:no-empty */ - searchService.getSearchConfigurationFor(scope).subscribe((t) => { - }); // subscribe to make sure all methods are called - /* tslint:enable:no-empty */ - }); - - it('should call getEndpoint on the halService', () => { - expect((searchService as any).halService.getEndpoint).toHaveBeenCalled(); - }); - - it('should send out the request on the request service', () => { - expect((searchService as any).requestService.send).toHaveBeenCalled(); - }); - - it('should call send containing a request with the correct request url', () => { - expect((searchService as any).requestService.send).toHaveBeenCalledWith(jasmine.objectContaining({ href: requestUrl }), true); - }); - }); - }); }); diff --git a/src/app/core/shared/search/search.service.ts b/src/app/core/shared/search/search.service.ts index 75723366bc2..13340874e72 100644 --- a/src/app/core/shared/search/search.service.ts +++ b/src/app/core/shared/search/search.service.ts @@ -85,21 +85,11 @@ class DataServiceImpl extends DataService { @Injectable() export class SearchService implements OnDestroy { - /** - * Endpoint link path for retrieving search configurations - */ - private configurationLinkPath = 'discover/search'; - /** * Endpoint link path for retrieving general search results */ private searchLinkPath = 'discover/search/objects'; - /** - * Endpoint link path for retrieving facet config incl values - */ - private facetLinkPathPrefix = 'discover/facets/'; - /** * The ResponseParsingService constructor name */ @@ -298,71 +288,6 @@ export class SearchService implements OnDestroy { ); } - private getConfigUrl(url: string, scope?: string, configurationName?: string) { - const args: string[] = []; - - if (isNotEmpty(scope)) { - args.push(`scope=${scope}`); - } - - if (isNotEmpty(configurationName)) { - args.push(`configuration=${configurationName}`); - } - - if (isNotEmpty(args)) { - url = new URLCombiner(url, `?${args.join('&')}`).toString(); - } - - return url; - } - - /** - * Request the filter configuration for a given scope or the whole repository - * @param {string} scope UUID of the object for which config the filter config is requested, when no scope is provided the configuration for the whole repository is loaded - * @param {string} configurationName the name of the configuration - * @returns {Observable>} The found filter configuration - */ - getConfig(scope?: string, configurationName?: string): Observable> { - const href$ = this.halService.getEndpoint(this.facetLinkPathPrefix).pipe( - map((url: string) => this.getConfigUrl(url, scope, configurationName)), - ); - - href$.pipe(take(1)).subscribe((url: string) => { - let request = new this.request(this.requestService.generateRequestId(), url); - request = Object.assign(request, { - getResponseParser(): GenericConstructor { - return FacetConfigResponseParsingService; - } - }); - this.requestService.send(request, true); - }); - - return this.rdb.buildFromHref(href$).pipe( - map((rd: RemoteData) => { - if (rd.hasSucceeded) { - let filters: SearchFilterConfig[]; - if (isNotEmpty(rd.payload.filters)) { - filters = rd.payload.filters - .map((filter: any) => Object.assign(new SearchFilterConfig(), filter)); - } else { - filters = []; - } - - return new RemoteData( - rd.timeCompleted, - rd.msToLive, - rd.lastUpdated, - rd.state, - rd.errorMessage, - filters, - rd.statusCode, - ); - } else { - return rd as any as RemoteData; - } - }) - ); - } /** * Method to request a single page of filter values for a given value @@ -469,25 +394,6 @@ export class SearchService implements OnDestroy { }); } - /** - * Request the search configuration for a given scope or the whole repository - * @param {string} scope UUID of the object for which config the filter config is requested, when no scope is provided the configuration for the whole repository is loaded - * @param {string} configurationName the name of the configuration - * @returns {Observable>} The found configuration - */ - getSearchConfigurationFor(scope?: string, configurationName?: string): Observable> { - const href$ = this.halService.getEndpoint(this.configurationLinkPath).pipe( - map((url: string) => this.getConfigUrl(url, scope, configurationName)), - ); - - href$.pipe(take(1)).subscribe((url: string) => { - const request = new this.request(this.requestService.generateRequestId(), url); - this.requestService.send(request, true); - }); - - return this.rdb.buildFromHref(href$); - } - /** * @returns {string} The base path to the search page */ diff --git a/src/app/core/submission/models/submission-object.model.ts b/src/app/core/submission/models/submission-object.model.ts index 4c9ea6dfb08..3d7c0a3678a 100644 --- a/src/app/core/submission/models/submission-object.model.ts +++ b/src/app/core/submission/models/submission-object.model.ts @@ -2,7 +2,6 @@ import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; import { Observable } from 'rxjs'; import { link } from '../../cache/builders/build-decorators'; -import { CacheableObject } from '../../cache/object-cache.reducer'; import { SubmissionDefinitionsModel } from '../../config/models/config-submission-definitions.model'; import { RemoteData } from '../../data/remote-data'; import { EPerson } from '../../eperson/models/eperson.model'; @@ -14,6 +13,7 @@ import { HALLink } from '../../shared/hal-link.model'; import { ITEM } from '../../shared/item.resource-type'; import { excludeFromEquals } from '../../utilities/equals.decorators'; import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model'; +import { CacheableObject } from '../../cache/cacheable-object.model'; export interface SubmissionObjectError { message: string; diff --git a/src/app/core/submission/submission-object-data.service.ts b/src/app/core/submission/submission-object-data.service.ts index 174229fdc78..97256ea8dac 100644 --- a/src/app/core/submission/submission-object-data.service.ts +++ b/src/app/core/submission/submission-object-data.service.ts @@ -11,7 +11,7 @@ import { DataService } from '../data/data.service'; import { map } from 'rxjs/operators'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { environment } from '../../../environments/environment'; -import { RequestEntryState } from '../data/request.reducer'; +import { RequestEntryState } from '../data/request-entry-state.model'; /** * A service to retrieve submission objects (WorkspaceItem/WorkflowItem) diff --git a/src/app/core/submission/vocabularies/models/vocabulary.model.ts b/src/app/core/submission/vocabularies/models/vocabulary.model.ts index 83b578eb899..9cfc779115a 100644 --- a/src/app/core/submission/vocabularies/models/vocabulary.model.ts +++ b/src/app/core/submission/vocabularies/models/vocabulary.model.ts @@ -2,13 +2,13 @@ import { autoserialize, deserialize } from 'cerialize'; import { HALLink } from '../../../shared/hal-link.model'; import { VOCABULARY, VOCABULARY_ENTRY } from './vocabularies.resource-type'; -import { CacheableObject } from '../../../cache/object-cache.reducer'; import { typedObject, link } from '../../../cache/builders/build-decorators'; import { excludeFromEquals } from '../../../utilities/equals.decorators'; import { Observable } from 'rxjs'; import { RemoteData } from '../../../data/remote-data'; import { PaginatedList } from '../../../data/paginated-list.model'; import { VocabularyEntry } from './vocabulary-entry.model'; +import { CacheableObject } from '../../../cache/cacheable-object.model'; /** * Model class for a Vocabulary diff --git a/src/app/core/tasks/models/task-object.model.ts b/src/app/core/tasks/models/task-object.model.ts index 1f23a84ca75..dc4aa8b5ae6 100644 --- a/src/app/core/tasks/models/task-object.model.ts +++ b/src/app/core/tasks/models/task-object.model.ts @@ -2,7 +2,6 @@ import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; import { Observable } from 'rxjs'; import { link, typedObject } from '../../cache/builders/build-decorators'; -import { CacheableObject } from '../../cache/object-cache.reducer'; import { RemoteData } from '../../data/remote-data'; import { EPerson } from '../../eperson/models/eperson.model'; import { EPERSON } from '../../eperson/models/eperson.resource-type'; @@ -14,6 +13,7 @@ import { TASK_OBJECT } from './task-object.resource-type'; import { WORKFLOWITEM } from '../../eperson/models/workflowitem.resource-type'; import { WORKFLOW_ACTION } from './workflow-action-object.resource-type'; import { WorkflowAction } from './workflow-action-object.model'; +import { CacheableObject } from '../../cache/cacheable-object.model'; /** * An abstract model class for a TaskObject. diff --git a/src/app/core/tasks/tasks.service.ts b/src/app/core/tasks/tasks.service.ts index 7aeb5221702..d96e3320f2f 100644 --- a/src/app/core/tasks/tasks.service.ts +++ b/src/app/core/tasks/tasks.service.ts @@ -15,9 +15,9 @@ import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { ProcessTaskResponse } from './models/process-task-response'; import { getAllCompletedRemoteData, getFirstCompletedRemoteData } from '../shared/operators'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { RemoteData } from '../data/remote-data'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * An abstract class that provides methods to handle task requests. diff --git a/src/app/core/utilities/equals.decorators.ts b/src/app/core/utilities/equals.decorators.ts index 82422e29b6e..2e07084ea77 100644 --- a/src/app/core/utilities/equals.decorators.ts +++ b/src/app/core/utilities/equals.decorators.ts @@ -1,10 +1,59 @@ -import { isEmpty } from '../../shared/empty.util'; +import { hasNoValue, hasValue, isEmpty } from '../../shared/empty.util'; import { GenericConstructor } from '../shared/generic-constructor'; -import { EquatableObject } from './equatable'; const excludedFromEquals = new Map(); const fieldsForEqualsMap = new Map(); +/** + * Method to compare fields of two objects against each other + * @param object1 The first object for the comparison + * @param object2 The second object for the comparison + * @param fieldList The list of property/field names to compare + */ +function equalsByFields(object1, object2, fieldList): boolean { + const unequalProperty = fieldList.find((key) => { + if (object1[key] === object2[key]) { + return false; + } + if (hasNoValue(object1[key]) && hasNoValue(object2[key])) { + return false; + } + if (hasNoValue(object1[key]) || hasNoValue(object2[key])) { + return true; + } + const mapping = getFieldsForEquals(object1.constructor, key); + if (hasValue(mapping)) { + return !equalsByFields(object1[key], object2[key], mapping); + } + if (object1[key] instanceof EquatableObject) { + return !object1[key].equals(object2[key]); + } + if (typeof object1[key] === 'object') { + return !equalsByFields(object1[key], object2[key], Object.keys(object1)); + } + return object1[key] !== object2[key]; + }); + return hasNoValue(unequalProperty); +} + +/** + * Abstract class to represent objects that can be compared to each other + * It provides a default way of comparing + */ +export abstract class EquatableObject { + equals(other: T): boolean { + if (hasNoValue(other)) { + return false; + } + if (this as any === other) { + return true; + } + const excludedKeys = getExcludedFromEqualsFor(this.constructor); + const keys = Object.keys(this).filter((key) => !excludedKeys.includes(key)); + return equalsByFields(this, other, keys); + } +} + /** * Decorator function that adds the equatable settings from the given (parent) object * @param parentCo The constructor of the parent object diff --git a/src/app/core/utilities/equatable.spec.ts b/src/app/core/utilities/equatable.spec.ts index 79136cd2215..02d5e5a9f97 100644 --- a/src/app/core/utilities/equatable.spec.ts +++ b/src/app/core/utilities/equatable.spec.ts @@ -1,5 +1,4 @@ -import { excludeFromEquals, fieldsForEquals } from './equals.decorators'; -import { EquatableObject } from './equatable'; +import { EquatableObject, excludeFromEquals, fieldsForEquals } from './equals.decorators'; import { cloneDeep } from 'lodash'; class Dog extends EquatableObject { diff --git a/src/app/core/utilities/equatable.ts b/src/app/core/utilities/equatable.ts deleted file mode 100644 index 783a43f3391..00000000000 --- a/src/app/core/utilities/equatable.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { getExcludedFromEqualsFor, getFieldsForEquals } from './equals.decorators'; -import { hasNoValue, hasValue } from '../../shared/empty.util'; - -/** - * Method to compare fields of two objects against each other - * @param object1 The first object for the comparison - * @param object2 The second object for the comparison - * @param fieldList The list of property/field names to compare - */ -function equalsByFields(object1, object2, fieldList): boolean { - const unequalProperty = fieldList.find((key) => { - if (object1[key] === object2[key]) { - return false; - } - if (hasNoValue(object1[key]) && hasNoValue(object2[key])) { - return false; - } - if (hasNoValue(object1[key]) || hasNoValue(object2[key])) { - return true; - } - const mapping = getFieldsForEquals(object1.constructor, key); - if (hasValue(mapping)) { - return !equalsByFields(object1[key], object2[key], mapping); - } - if (object1[key] instanceof EquatableObject) { - return !object1[key].equals(object2[key]); - } - if (typeof object1[key] === 'object') { - return !equalsByFields(object1[key], object2[key], Object.keys(object1)); - } - return object1[key] !== object2[key]; - }); - return hasNoValue(unequalProperty); -} - -/** - * Abstract class to represent objects that can be compared to each other - * It provides a default way of comparing - */ -export abstract class EquatableObject { - equals(other: T): boolean { - if (hasNoValue(other)) { - return false; - } - if (this as any === other) { - return true; - } - const excludedKeys = getExcludedFromEqualsFor(this.constructor); - const keys = Object.keys(this).filter((key) => !excludedKeys.includes(key)); - return equalsByFields(this, other, keys); - } -} diff --git a/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts b/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts index 128ce41b10f..a610b2cb026 100644 --- a/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts +++ b/src/app/header-nav-wrapper/header-navbar-wrapper.component.ts @@ -4,7 +4,7 @@ import { AppState } from '../app.reducer'; import { hasValue } from '../shared/empty.util'; import { Observable, Subscription } from 'rxjs'; import { MenuService } from '../shared/menu/menu.service'; -import { MenuID } from '../shared/menu/initial-menus-state'; +import { MenuID } from '../shared/menu/menu-id.model'; /** * This component represents a wrapper for the horizontal navbar and the header diff --git a/src/app/header/header.component.ts b/src/app/header/header.component.ts index 78298b1e061..366b4f5e7a1 100644 --- a/src/app/header/header.component.ts +++ b/src/app/header/header.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { Observable } from 'rxjs'; import { MenuService } from '../shared/menu/menu.service'; -import { MenuID } from '../shared/menu/initial-menus-state'; +import { MenuID } from '../shared/menu/menu-id.model'; /** * Represents the header with the logo and simple navigation diff --git a/src/app/home-page/home-page-routing.module.ts b/src/app/home-page/home-page-routing.module.ts index 2a41c079da1..196a290552a 100644 --- a/src/app/home-page/home-page-routing.module.ts +++ b/src/app/home-page/home-page-routing.module.ts @@ -2,9 +2,9 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { HomePageResolver } from './home-page.resolver'; -import { MenuItemType } from '../shared/menu/initial-menus-state'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedHomePageComponent } from './themed-home-page.component'; +import { MenuItemType } from '../shared/menu/menu-item-type.model'; @NgModule({ imports: [ 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 01d6cc74395..80002f614b6 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 @@ -1,8 +1,4 @@ import { Component, OnInit, OnDestroy, Input } from '@angular/core'; -import { - FieldUpdate, - FieldUpdates -} from '../../../core/data/object-updates/object-updates.reducer'; import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; import { Item } from '../../../core/shared/item.model'; import { ItemDataService } from '../../../core/data/item-data.service'; @@ -18,6 +14,8 @@ 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 { FieldUpdate } from '../../../core/data/object-updates/field-update.model'; +import { FieldUpdates } from '../../../core/data/object-updates/field-updates.model'; @Component({ selector: 'ds-abstract-item-update', 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 a2299be5ba1..dbbd3bc72e1 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 @@ -9,7 +9,6 @@ import { ObjectUpdatesService } from '../../../core/data/object-updates/object-u import { ActivatedRoute, Router } from '@angular/router'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { ChangeDetectorRef, NO_ERRORS_SCHEMA } from '@angular/core'; -import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions'; import { INotification, Notification } from '../../../shared/notifications/models/notification.model'; import { NotificationType } from '../../../shared/notifications/models/notification-type'; import { BitstreamDataService } from '../../../core/data/bitstream-data.service'; @@ -25,6 +24,7 @@ import { RouterStub } from '../../../shared/testing/router.stub'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createPaginatedList } from '../../../shared/testing/utils.test'; +import { FieldChangeType } from '../../../core/data/object-updates/field-change-type.model'; let comp: ItemBitstreamsComponent; let fixture: ComponentFixture; 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 d66c5d060d2..88c594c74b1 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 @@ -15,18 +15,16 @@ import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../../../core import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; import { Bundle } from '../../../core/shared/bundle.model'; -import { - FieldUpdate, - FieldUpdates -} from '../../../core/data/object-updates/object-updates.reducer'; import { Bitstream } from '../../../core/shared/bitstream.model'; -import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions'; import { BundleDataService } from '../../../core/data/bundle-data.service'; import { PaginatedSearchOptions } from '../../../shared/search/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'; @Component({ selector: 'ds-item-bitstreams', 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 index a4d30f6853d..8f31bd4c2b4 100644 --- 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 @@ -1,14 +1,14 @@ import { Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core'; -import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer'; import { Bitstream } from '../../../../core/shared/bitstream.model'; import { cloneDeep } from 'lodash'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; -import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; 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'; @Component({ selector: 'ds-item-edit-bitstream', diff --git a/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts b/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts index 0a4df1bda59..29bfaf4f568 100644 --- a/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts @@ -7,7 +7,6 @@ import { getTestScheduler } from 'jasmine-marbles'; import { of as observableOf } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; import { MetadataFieldDataService } from '../../../../core/data/metadata-field-data.service'; -import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { buildPaginatedList } from '../../../../core/data/paginated-list.model'; import { MetadataField } from '../../../../core/metadata/metadata-field.model'; @@ -21,6 +20,7 @@ import { EditInPlaceFieldComponent } from './edit-in-place-field.component'; import { MockComponent, MockDirective } from 'ng-mocks'; import { DebounceDirective } from '../../../../shared/utils/debounce.directive'; import { ValidationSuggestionsComponent } from '../../../../shared/input-suggestions/validation-suggestions/validation-suggestions.component'; +import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; let comp: EditInPlaceFieldComponent; let fixture: ComponentFixture; diff --git a/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts b/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts index 27827479164..849a54cc48a 100644 --- a/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts +++ b/src/app/item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts @@ -8,13 +8,13 @@ import { RegistryService } from '../../../../core/registry/registry.service'; import { cloneDeep } from 'lodash'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { map } from 'rxjs/operators'; -import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; -import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { NgModel } from '@angular/forms'; import { MetadatumViewModel } from '../../../../core/shared/metadata.models'; import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; import { followLink } from '../../../../shared/utils/follow-link-config.model'; +import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; +import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; @Component({ // tslint:disable-next-line:component-selector diff --git a/src/app/item-page/edit-item-page/item-metadata/item-metadata.component.spec.ts b/src/app/item-page/edit-item-page/item-metadata/item-metadata.component.spec.ts index 0f01efcc552..44ed6c783f7 100644 --- a/src/app/item-page/edit-item-page/item-metadata/item-metadata.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-metadata/item-metadata.component.spec.ts @@ -15,7 +15,6 @@ import { INotification, Notification } from '../../../shared/notifications/model import { NotificationType } from '../../../shared/notifications/models/notification-type'; import { RouterStub } from '../../../shared/testing/router.stub'; import { Item } from '../../../core/shared/item.model'; -import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions'; import { MetadatumViewModel } from '../../../core/shared/metadata.models'; import { RegistryService } from '../../../core/registry/registry.service'; import { MetadataSchema } from '../../../core/metadata/metadata-schema.model'; @@ -24,6 +23,7 @@ import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } f import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { DSOSuccessResponse } from '../../../core/cache/response.models'; import { createPaginatedList } from '../../../shared/testing/utils.test'; +import { FieldChangeType } from '../../../core/data/object-updates/field-change-type.model'; let comp: any; let fixture: ComponentFixture; 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 67422340583..91bff2a8b55 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 @@ -4,7 +4,6 @@ import { By } from '@angular/platform-browser'; import { TranslateModule } from '@ngx-translate/core'; import { of as observableOf } from 'rxjs'; import { LinkService } from '../../../../core/cache/builders/link.service'; -import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { RelationshipService } from '../../../../core/data/relationship.service'; import { ItemType } from '../../../../core/shared/item-relationships/item-type.model'; @@ -22,6 +21,7 @@ import { HostWindowService } from '../../../../shared/host-window.service'; import { HostWindowServiceStub } from '../../../../shared/testing/host-window-service.stub'; import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; +import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; let comp: EditRelationshipListComponent; let fixture: ComponentFixture; 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 9f417ab7995..620f749ab9f 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 @@ -1,7 +1,6 @@ import { Component, Input, OnInit, OnDestroy } from '@angular/core'; import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { LinkService } from '../../../../core/cache/builders/link.service'; -import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { combineLatest as observableCombineLatest, @@ -10,8 +9,6 @@ import { from as observableFrom } from 'rxjs'; import { - FieldUpdate, - FieldUpdates, RelationshipIdentifiable } from '../../../../core/data/object-updates/object-updates.reducer'; import { RelationshipService } from '../../../../core/data/relationship.service'; @@ -49,6 +46,9 @@ import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { Subscription } from 'rxjs/internal/Subscription'; import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; 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'; +import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; @Component({ selector: 'ds-edit-relationship-list', diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.spec.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.spec.ts index 3ab17ad6233..a3062abf7ed 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.spec.ts @@ -2,7 +2,6 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { TranslateModule } from '@ngx-translate/core'; import { of as observableOf } from 'rxjs'; -import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model'; import { Relationship } from '../../../../core/shared/item-relationships/relationship.model'; @@ -11,6 +10,7 @@ import { EditRelationshipComponent } from './edit-relationship.component'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils'; import { createPaginatedList } from '../../../../shared/testing/utils.test'; +import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; let objectUpdatesService; const url = 'http://test-url.com/test-url'; diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts index 3a3a8f96757..112531cce55 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts @@ -1,10 +1,8 @@ import { Component, Input, OnChanges } from '@angular/core'; import { combineLatest as observableCombineLatest, Observable, of } from 'rxjs'; import { filter, map, switchMap, take } from 'rxjs/operators'; -import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { DeleteRelationship, - FieldUpdate, RelationshipIdentifiable } from '../../../../core/data/object-updates/object-updates.reducer'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; @@ -13,6 +11,8 @@ import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../../../../c import { ViewMode } from '../../../../core/shared/view-mode.model'; import { hasValue, isNotEmpty } from '../../../../shared/empty.util'; import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { FieldUpdate } from '../../../../core/data/object-updates/field-update.model'; +import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; @Component({ // tslint:disable-next-line:component-selector diff --git a/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.spec.ts b/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.spec.ts index 65fd49f7950..9fe8545a7d9 100644 --- a/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.spec.ts @@ -9,7 +9,6 @@ import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { RestResponse } from '../../../core/cache/response.models'; import { EntityTypeService } from '../../../core/data/entity-type.service'; import { ItemDataService } from '../../../core/data/item-data.service'; -import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions'; import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; import { RelationshipService } from '../../../core/data/relationship.service'; import { RequestService } from '../../../core/data/request.service'; @@ -25,6 +24,7 @@ import { RouterStub } from '../../../shared/testing/router.stub'; import { ItemRelationshipsComponent } from './item-relationships.component'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createPaginatedList } from '../../../shared/testing/utils.test'; +import { FieldChangeType } from '../../../core/data/object-updates/field-change-type.model'; let comp: any; let fixture: ComponentFixture; diff --git a/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.ts b/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.ts index e22ad8ddcb3..07a35e03b4e 100644 --- a/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.ts +++ b/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.ts @@ -2,8 +2,6 @@ import { ChangeDetectorRef, Component } from '@angular/core'; import { Item } from '../../../core/shared/item.model'; import { DeleteRelationship, - FieldUpdate, - FieldUpdates, RelationshipIdentifiable, } from '../../../core/data/object-updates/object-updates.reducer'; import { Observable } from 'rxjs/internal/Observable'; @@ -28,10 +26,12 @@ import { RequestService } from '../../../core/data/request.service'; import { RelationshipType } from '../../../core/shared/item-relationships/relationship-type.model'; import { ItemType } from '../../../core/shared/item-relationships/item-type.model'; import { EntityTypeService } from '../../../core/data/entity-type.service'; -import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions'; import { Relationship } from '../../../core/shared/item-relationships/relationship.model'; import { NoContent } from '../../../core/shared/NoContent.model'; import { hasValue } from '../../../shared/empty.util'; +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'; @Component({ selector: 'ds-item-relationships', diff --git a/src/app/item-page/item-page-routing.module.ts b/src/app/item-page/item-page-routing.module.ts index f2d0a23935c..de749915ac4 100644 --- a/src/app/item-page/item-page-routing.module.ts +++ b/src/app/item-page/item-page-routing.module.ts @@ -8,10 +8,10 @@ import { LinkService } from '../core/cache/builders/link.service'; import { UploadBitstreamComponent } from './bitstreams/upload/upload-bitstream.component'; import { ITEM_EDIT_PATH, UPLOAD_BITSTREAM_PATH } from './item-page-routing-paths'; import { ItemPageAdministratorGuard } from './item-page-administrator.guard'; -import { MenuItemType } from '../shared/menu/initial-menus-state'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedItemPageComponent } from './simple/themed-item-page.component'; import { ThemedFullItemPageComponent } from './full/themed-full-item-page.component'; +import { MenuItemType } from '../shared/menu/menu-item-type.model'; @NgModule({ imports: [ diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index cc23ba86d5e..f410707731c 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -9,10 +9,11 @@ import { RemoteData } from '../../core/data/remote-data'; import { Item } from '../../core/shared/item.model'; import { fadeInOut } from '../../shared/animations/fade'; -import { getAllSucceededRemoteDataPayload, redirectOn4xx } from '../../core/shared/operators'; +import { getAllSucceededRemoteDataPayload} from '../../core/shared/operators'; import { ViewMode } from '../../core/shared/view-mode.model'; import { AuthService } from '../../core/auth/auth.service'; import { getItemPageRoute } from '../item-page-routing-paths'; +import { redirectOn4xx } from '../../core/shared/authorized.operators'; /** * This component renders a simple item page. diff --git a/src/app/my-dspace-page/my-dspace-configuration.service.spec.ts b/src/app/my-dspace-page/my-dspace-configuration.service.spec.ts index fa278da967e..611a3177ca8 100644 --- a/src/app/my-dspace-page/my-dspace-configuration.service.spec.ts +++ b/src/app/my-dspace-page/my-dspace-configuration.service.spec.ts @@ -11,6 +11,12 @@ import { cold, hot } from 'jasmine-marbles'; import { MyDSpaceConfigurationValueType } from './my-dspace-configuration-value-type'; import { PaginationServiceStub } from '../shared/testing/pagination-service.stub'; import { PaginationService } from '../core/pagination/pagination.service'; +import { LinkService } from '../core/cache/builders/link.service'; +import { HALEndpointService } from '../core/shared/hal-endpoint.service'; +import { RequestService } from '../core/data/request.service'; +import { RemoteDataBuildService } from '../core/cache/builders/remote-data-build.service'; +import { HALEndpointServiceStub } from '../shared/testing/hal-endpoint-service.stub'; +import { getMockRemoteDataBuildService } from '../shared/mocks/remote-data-build.service.mock'; describe('MyDSpaceConfigurationService', () => { let service: MyDSpaceConfigurationService; @@ -44,8 +50,13 @@ describe('MyDSpaceConfigurationService', () => { const roleService: any = new RoleServiceMock(); + const linkService: any = {}; + const halService: any = new HALEndpointServiceStub(''); + const requestService: any = {}; + const rdb: any = getMockRemoteDataBuildService(); + beforeEach(() => { - service = new MyDSpaceConfigurationService(roleService, spy, paginationService as any, activatedRoute); + service = new MyDSpaceConfigurationService(roleService, spy, paginationService as any, activatedRoute, linkService, halService, requestService, rdb); }); describe('when the scope is called', () => { diff --git a/src/app/my-dspace-page/my-dspace-configuration.service.ts b/src/app/my-dspace-page/my-dspace-configuration.service.ts index 82f76eb776b..7f741506c3e 100644 --- a/src/app/my-dspace-page/my-dspace-configuration.service.ts +++ b/src/app/my-dspace-page/my-dspace-configuration.service.ts @@ -12,6 +12,10 @@ import { PaginationComponentOptions } from '../shared/pagination/pagination-comp import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model'; import { RouteService } from '../core/services/route.service'; import { PaginationService } from '../core/pagination/pagination.service'; +import { LinkService } from '../core/cache/builders/link.service'; +import { HALEndpointService } from '../core/shared/hal-endpoint.service'; +import { RequestService } from '../core/data/request.service'; +import { RemoteDataBuildService } from '../core/cache/builders/remote-data-build.service'; /** * Service that performs all actions that have to do with the current mydspace configuration @@ -58,13 +62,21 @@ export class MyDSpaceConfigurationService extends SearchConfigurationService { * @param {RouteService} routeService * @param {PaginationService} paginationService * @param {ActivatedRoute} route + * @param linkService + * @param halService + * @param requestService + * @param rdb */ constructor(protected roleService: RoleService, protected routeService: RouteService, protected paginationService: PaginationService, - protected route: ActivatedRoute) { + protected route: ActivatedRoute, + protected linkService: LinkService, + protected halService: HALEndpointService, + protected requestService: RequestService, + protected rdb: RemoteDataBuildService) { - super(routeService, paginationService, route); + super(routeService, paginationService, route, linkService, halService, requestService, rdb); // override parent class initialization this._defaults = null; diff --git a/src/app/my-dspace-page/my-dspace-page.component.spec.ts b/src/app/my-dspace-page/my-dspace-page.component.spec.ts index b4b75b42a02..a7f16d41844 100644 --- a/src/app/my-dspace-page/my-dspace-page.component.spec.ts +++ b/src/app/my-dspace-page/my-dspace-page.component.spec.ts @@ -16,8 +16,6 @@ import { CommunityDataService } from '../core/data/community-data.service'; import { HostWindowService } from '../shared/host-window.service'; import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; import { MyDSpacePageComponent, SEARCH_CONFIG_SERVICE } from './my-dspace-page.component'; -import { RouteService } from '../core/services/route.service'; -import { routeServiceStub } from '../shared/testing/route-service.stub'; import { SearchConfigurationServiceStub } from '../shared/testing/search-configuration-service.stub'; import { SearchService } from '../core/shared/search/search.service'; import { SearchConfigurationService } from '../core/shared/search/search-configuration.service'; @@ -90,7 +88,6 @@ describe('MyDSpacePageComponent', () => { useValue: jasmine.createSpyObj('communityService', ['findById', 'findAll']) }, { provide: ActivatedRoute, useValue: activatedRouteStub }, - { provide: RouteService, useValue: routeServiceStub }, { provide: Store, useValue: store }, @@ -109,9 +106,14 @@ describe('MyDSpacePageComponent', () => { { provide: SearchFilterService, useValue: {} - }, { + }, + { provide: SEARCH_CONFIG_SERVICE, - useValue: new SearchConfigurationServiceStub() + useFactory: () => new SearchConfigurationServiceStub() + }, + { + provide: SearchConfigurationService, + useFactory: new SearchConfigurationServiceStub() }, { provide: RoleService, @@ -120,7 +122,14 @@ describe('MyDSpacePageComponent', () => { ], schemas: [NO_ERRORS_SCHEMA] }).overrideComponent(MyDSpacePageComponent, { - set: { changeDetection: ChangeDetectionStrategy.Default } + set: { + changeDetection: ChangeDetectionStrategy.Default, + providers: [ + { + provide: SEARCH_CONFIG_SERVICE, + useClass: SearchConfigurationServiceStub + } + ] } }).compileComponents(); })); @@ -130,6 +139,7 @@ describe('MyDSpacePageComponent', () => { fixture.detectChanges(); searchServiceObject = (comp as any).service; searchConfigurationServiceObject = (comp as any).searchConfigService; + console.log(searchConfigurationServiceObject) }); afterEach(() => { @@ -198,9 +208,7 @@ describe('MyDSpacePageComponent', () => { }); it('should have initialized the sortOptions$ observable', (done) => { - comp.sortOptions$.subscribe((sortOptions) => { - expect(sortOptions.length).toEqual(2); expect(sortOptions[0]).toEqual(new SortOptions('score', SortDirection.ASC)); expect(sortOptions[1]).toEqual(new SortOptions('score', SortDirection.DESC)); diff --git a/src/app/my-dspace-page/my-dspace-page.component.ts b/src/app/my-dspace-page/my-dspace-page.component.ts index 3ded17191ee..8745f458b3d 100644 --- a/src/app/my-dspace-page/my-dspace-page.component.ts +++ b/src/app/my-dspace-page/my-dspace-page.component.ts @@ -160,7 +160,7 @@ export class MyDSpacePageComponent implements OnInit { ); const configuration$ = this.searchConfigService.getCurrentConfiguration('workspace'); - const searchConfig$ = this.searchConfigService.getConfigurationSearchConfigObservable(configuration$, this.service); + const searchConfig$ = this.searchConfigService.getConfigurationSearchConfigObservable(configuration$); this.sortOptions$ = this.searchConfigService.getConfigurationSortOptionsObservable(searchConfig$); this.searchConfigService.initializeSortOptionsFromConfiguration(searchConfig$); diff --git a/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts b/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts index 068854d6f85..5bc69bcbb4e 100644 --- a/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts +++ b/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts @@ -1,11 +1,11 @@ import { Component, Inject, Injector, OnInit } from '@angular/core'; import { NavbarSectionComponent } from '../navbar-section/navbar-section.component'; import { MenuService } from '../../shared/menu/menu.service'; -import { MenuID } from '../../shared/menu/initial-menus-state'; import { slide } from '../../shared/animations/slide'; import { first } from 'rxjs/operators'; import { HostWindowService } from '../../shared/host-window.service'; import { rendersSectionForMenu } from '../../shared/menu/menu-section.decorator'; +import { MenuID } from '../../shared/menu/menu-id.model'; /** * Represents an expandable section in the navbar diff --git a/src/app/navbar/navbar-section/navbar-section.component.ts b/src/app/navbar/navbar-section/navbar-section.component.ts index e1488de3d38..9b86aa10f2b 100644 --- a/src/app/navbar/navbar-section/navbar-section.component.ts +++ b/src/app/navbar/navbar-section/navbar-section.component.ts @@ -1,8 +1,8 @@ import { Component, Inject, Injector, OnInit } from '@angular/core'; import { MenuSectionComponent } from '../../shared/menu/menu-section/menu-section.component'; import { MenuService } from '../../shared/menu/menu.service'; -import { MenuID } from '../../shared/menu/initial-menus-state'; import { rendersSectionForMenu } from '../../shared/menu/menu-section.decorator'; +import { MenuID } from '../../shared/menu/menu-id.model'; /** * Represents a non-expandable section in the navbar diff --git a/src/app/navbar/navbar.component.ts b/src/app/navbar/navbar.component.ts index e741cea2851..98b1eb5056c 100644 --- a/src/app/navbar/navbar.component.ts +++ b/src/app/navbar/navbar.component.ts @@ -2,11 +2,12 @@ import { Component, Injector } from '@angular/core'; import { slideMobileNav } from '../shared/animations/slide'; import { MenuComponent } from '../shared/menu/menu.component'; import { MenuService } from '../shared/menu/menu.service'; -import { MenuID, MenuItemType } from '../shared/menu/initial-menus-state'; import { TextMenuItemModel } from '../shared/menu/menu-item/models/text.model'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { HostWindowService } from '../shared/host-window.service'; import { environment } from '../../environments/environment'; +import { MenuID } from '../shared/menu/menu-id.model'; +import { MenuItemType } from '../shared/menu/menu-item-type.model'; /** * Component representing the public navbar diff --git a/src/app/navbar/navbar.effects.spec.ts b/src/app/navbar/navbar.effects.spec.ts index 0bd3fa8e6e9..bcb105d5b2b 100644 --- a/src/app/navbar/navbar.effects.spec.ts +++ b/src/app/navbar/navbar.effects.spec.ts @@ -6,9 +6,9 @@ import { provideMockActions } from '@ngrx/effects/testing'; import { cold, hot } from 'jasmine-marbles'; import * as fromRouter from '@ngrx/router-store'; import { CollapseMenuAction } from '../shared/menu/menu.actions'; -import { MenuID } from '../shared/menu/initial-menus-state'; import { MenuService } from '../shared/menu/menu.service'; import { MenuServiceStub } from '../shared/testing/menu-service.stub'; +import { MenuID } from '../shared/menu/menu-id.model'; describe('NavbarEffects', () => { let navbarEffects: NavbarEffects; diff --git a/src/app/navbar/navbar.effects.ts b/src/app/navbar/navbar.effects.ts index 6cb11f21c0b..bdf6fe5be18 100644 --- a/src/app/navbar/navbar.effects.ts +++ b/src/app/navbar/navbar.effects.ts @@ -9,10 +9,10 @@ import { ExpandMenuPreviewAction, MenuActionTypes } from '../shared/menu/menu.actions'; -import { MenuID } from '../shared/menu/initial-menus-state'; import { MenuService } from '../shared/menu/menu.service'; -import { MenuState } from '../shared/menu/menu.reducer'; import { NoOpAction } from '../shared/ngrx/no-op.action'; +import { MenuState } from '../shared/menu/menu-state.model'; +import { MenuID } from '../shared/menu/menu-id.model'; @Injectable() export class NavbarEffects { diff --git a/src/app/process-page/detail/process-detail.component.ts b/src/app/process-page/detail/process-detail.component.ts index 481189cf053..775b9da7ca4 100644 --- a/src/app/process-page/detail/process-detail.component.ts +++ b/src/app/process-page/detail/process-detail.component.ts @@ -13,7 +13,6 @@ import { Bitstream } from '../../core/shared/bitstream.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { getFirstSucceededRemoteDataPayload, - redirectOn4xx, getFirstSucceededRemoteData } from '../../core/shared/operators'; import { URLCombiner } from '../../core/url-combiner/url-combiner'; @@ -21,6 +20,7 @@ import { AlertType } from '../../shared/alert/aletr-type'; import { hasValue } from '../../shared/empty.util'; import { ProcessStatus } from '../processes/process-status.model'; import { Process } from '../processes/process.model'; +import { redirectOn4xx } from '../../core/shared/authorized.operators'; @Component({ selector: 'ds-process-detail', diff --git a/src/app/process-page/processes/process.model.ts b/src/app/process-page/processes/process.model.ts index 9f9a3ee2621..d5f6e77d32a 100644 --- a/src/app/process-page/processes/process.model.ts +++ b/src/app/process-page/processes/process.model.ts @@ -2,7 +2,6 @@ import { Bitstream } from '../../core/shared/bitstream.model'; import { PROCESS_OUTPUT_TYPE } from '../../core/shared/process-output.resource-type'; import { ProcessStatus } from './process-status.model'; import { ProcessParameter } from './process-parameter.model'; -import { CacheableObject } from '../../core/cache/object-cache.reducer'; import { HALLink } from '../../core/shared/hal-link.model'; import { autoserialize, deserialize } from 'cerialize'; import { PROCESS } from './process.resource-type'; @@ -13,6 +12,7 @@ import { Observable } from 'rxjs'; import { RemoteData } from '../../core/data/remote-data'; import { SCRIPT } from '../scripts/script.resource-type'; import { Script } from '../scripts/script.model'; +import { CacheableObject } from '../../core/cache/cacheable-object.model'; /** * Object representing a process diff --git a/src/app/process-page/scripts/script.model.ts b/src/app/process-page/scripts/script.model.ts index e94d233fc2c..afb1d41524e 100644 --- a/src/app/process-page/scripts/script.model.ts +++ b/src/app/process-page/scripts/script.model.ts @@ -1,4 +1,3 @@ -import { CacheableObject } from '../../core/cache/object-cache.reducer'; import { HALLink } from '../../core/shared/hal-link.model'; import { autoserialize, deserialize } from 'cerialize'; import { SCRIPT } from './script.resource-type'; @@ -6,6 +5,7 @@ import { ScriptParameter } from './script-parameter.model'; import { typedObject } from '../../core/cache/builders/build-decorators'; import { excludeFromEquals } from '../../core/utilities/equals.decorators'; import { ResourceType } from '../../core/shared/resource-type'; +import { CacheableObject } from '../../core/cache/cacheable-object.model'; /** * Object representing a script diff --git a/src/app/root/root.component.ts b/src/app/root/root.component.ts index 209f17b520d..ed6687033fa 100644 --- a/src/app/root/root.component.ts +++ b/src/app/root/root.component.ts @@ -13,12 +13,12 @@ import { NativeWindowRef, NativeWindowService } from '../core/services/window.se import { AuthService } from '../core/auth/auth.service'; import { CSSVariableService } from '../shared/sass-helper/sass-helper.service'; import { MenuService } from '../shared/menu/menu.service'; -import { MenuID } from '../shared/menu/initial-menus-state'; import { HostWindowService } from '../shared/host-window.service'; import { ThemeConfig } from '../../config/theme.model'; import { Angulartics2DSpace } from '../statistics/angulartics/dspace-provider'; import { environment } from '../../environments/environment'; import { slideSidebarPadding } from '../shared/animations/slide'; +import { MenuID } from '../shared/menu/menu-id.model'; @Component({ selector: 'ds-root', diff --git a/src/app/search-page/search.component.spec.ts b/src/app/search-page/search.component.spec.ts index 445f4614d3d..dae3b1479ad 100644 --- a/src/app/search-page/search.component.spec.ts +++ b/src/app/search-page/search.component.spec.ts @@ -47,7 +47,7 @@ const searchServiceStub = jasmine.createSpyObj('SearchService', { search: mockResults, getSearchLink: '/search', getScopes: observableOf(['test-scope']), - getSearchConfigurationFor: createSuccessfulRemoteDataObject$({ sortOptions: [sortOption]}) + getSearchConfigurationFor: createSuccessfulRemoteDataObject$({ sortOptions: [sortOption] }) }); const configurationParam = 'default'; const queryParam = 'test query'; @@ -137,7 +137,13 @@ export function configureSearchComponentTestingModule(compType, additionalDeclar ], schemas: [NO_ERRORS_SCHEMA] }).overrideComponent(compType, { - set: { changeDetection: ChangeDetectionStrategy.Default } + set: { + changeDetection: ChangeDetectionStrategy.Default, + providers: [{ + provide: SEARCH_CONFIG_SERVICE, + useValue: new SearchConfigurationServiceStub() + }] + } }).compileComponents(); } diff --git a/src/app/search-page/search.component.ts b/src/app/search-page/search.component.ts index d4d65b87fe7..1a9fb69c468 100644 --- a/src/app/search-page/search.component.ts +++ b/src/app/search-page/search.component.ts @@ -144,7 +144,7 @@ export class SearchComponent implements OnInit { this.configuration$ = this.searchConfigService.getCurrentConfiguration('default'); } - const searchConfig$ = this.searchConfigService.getConfigurationSearchConfigObservable(this.configuration$, this.service); + const searchConfig$ = this.searchConfigService.getConfigurationSearchConfigObservable(this.configuration$); this.sortOptions$ = this.searchConfigService.getConfigurationSortOptionsObservable(searchConfig$); this.searchConfigService.initializeSortOptionsFromConfiguration(searchConfig$); diff --git a/src/app/shared/bitstream-download-page/bitstream-download-page.component.ts b/src/app/shared/bitstream-download-page/bitstream-download-page.component.ts index a09d7e8b3ea..0bd44ce4969 100644 --- a/src/app/shared/bitstream-download-page/bitstream-download-page.component.ts +++ b/src/app/shared/bitstream-download-page/bitstream-download-page.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { filter, map, switchMap, take } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; import { hasValue, isNotEmpty } from '../empty.util'; -import { getRemoteDataPayload, redirectOn4xx } from '../../core/shared/operators'; +import { getRemoteDataPayload} from '../../core/shared/operators'; import { Bitstream } from '../../core/shared/bitstream.model'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../core/data/feature-authorization/feature-id'; @@ -12,6 +12,7 @@ import { FileService } from '../../core/shared/file.service'; import { HardRedirectService } from '../../core/services/hard-redirect.service'; import { getForbiddenRoute } from '../../app-routing-paths'; import { RemoteData } from '../../core/data/remote-data'; +import { redirectOn4xx } from '../../core/shared/authorized.operators'; @Component({ selector: 'ds-bitstream-download-page', 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 7adb9a837b3..8ff16de5b5c 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 @@ -323,7 +323,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo getAllSucceededRemoteData(), getRemoteDataPayload(), map((leftItem: Item) => { - return new ReorderableRelationship(relationship, leftItem.uuid !== item.uuid, this.relationshipService, this.store, this.model.submissionId); + return new ReorderableRelationship(relationship, leftItem.uuid !== item.uuid, this.store, this.model.submissionId); }), ) ), diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.ts index 899400eba04..326a8f71b75 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.ts @@ -5,7 +5,6 @@ import { Store } from '@ngrx/store'; import { BehaviorSubject, Subscription } from 'rxjs'; import { filter, take } from 'rxjs/operators'; import { AppState } from '../../../../../app.reducer'; -import { RelationshipService } from '../../../../../core/data/relationship.service'; import { Relationship } from '../../../../../core/shared/item-relationships/relationship.model'; import { Item } from '../../../../../core/shared/item.model'; import { ItemMetadataRepresentation } from '../../../../../core/shared/metadata-representation/item/item-metadata-representation.model'; @@ -103,7 +102,6 @@ export class ReorderableRelationship extends Reorderable { constructor( public relationship: Relationship, public useLeftItem: boolean, - protected relationshipService: RelationshipService, protected store: Store, protected submissionID: string, oldIndex?: number, diff --git a/src/app/shared/menu/initial-menus-state.ts b/src/app/shared/menu/initial-menus-state.ts index 7b900540b6f..d684afc3e77 100644 --- a/src/app/shared/menu/initial-menus-state.ts +++ b/src/app/shared/menu/initial-menus-state.ts @@ -1,19 +1,5 @@ -import { MenusState } from './menu.reducer'; - -/** - * Availavle Menu IDs - */ -export enum MenuID { - ADMIN = 'admin-sidebar', - PUBLIC = 'public' -} - -/** - * List of possible MenuItemTypes - */ -export enum MenuItemType { - TEXT, LINK, ALTMETRIC, SEARCH, ONCLICK -} +import { MenusState } from './menus-state.model'; +import { MenuID } from './menu-id.model'; /** * The initial state of the menus diff --git a/src/app/shared/menu/menu-id.model.ts b/src/app/shared/menu/menu-id.model.ts new file mode 100644 index 00000000000..50ce924a1b1 --- /dev/null +++ b/src/app/shared/menu/menu-id.model.ts @@ -0,0 +1,7 @@ +/** + * Availavle Menu IDs + */ +export enum MenuID { + ADMIN = 'admin-sidebar', + PUBLIC = 'public' +} diff --git a/src/app/shared/menu/menu-item-type.model.ts b/src/app/shared/menu/menu-item-type.model.ts new file mode 100644 index 00000000000..713dc6ab88e --- /dev/null +++ b/src/app/shared/menu/menu-item-type.model.ts @@ -0,0 +1,6 @@ +/** + * List of possible MenuItemTypes + */ +export enum MenuItemType { + TEXT, LINK, ALTMETRIC, SEARCH, ONCLICK +} diff --git a/src/app/shared/menu/menu-item.decorator.ts b/src/app/shared/menu/menu-item.decorator.ts index 3740a4eba46..ef3910e6a84 100644 --- a/src/app/shared/menu/menu-item.decorator.ts +++ b/src/app/shared/menu/menu-item.decorator.ts @@ -1,4 +1,4 @@ -import { MenuItemType } from './initial-menus-state'; +import { MenuItemType } from './menu-item-type.model'; const menuMenuItemComponentMap = new Map(); diff --git a/src/app/shared/menu/menu-item/link-menu-item.component.ts b/src/app/shared/menu/menu-item/link-menu-item.component.ts index e5b66c5aab9..8e0767cdda9 100644 --- a/src/app/shared/menu/menu-item/link-menu-item.component.ts +++ b/src/app/shared/menu/menu-item/link-menu-item.component.ts @@ -1,9 +1,9 @@ import { Component, Inject, Input, OnInit } from '@angular/core'; import { LinkMenuItemModel } from './models/link.model'; -import { MenuItemType } from '../initial-menus-state'; import { rendersMenuItemForType } from '../menu-item.decorator'; import { isNotEmpty } from '../../empty.util'; import { environment } from '../../../../environments/environment'; +import { MenuItemType } from '../menu-item-type.model'; /** * Component that renders a menu section of type LINK diff --git a/src/app/shared/menu/menu-item/models/altmetric.model.ts b/src/app/shared/menu/menu-item/models/altmetric.model.ts index 8dc3f013636..9dabb43a92b 100644 --- a/src/app/shared/menu/menu-item/models/altmetric.model.ts +++ b/src/app/shared/menu/menu-item/models/altmetric.model.ts @@ -1,5 +1,5 @@ -import { MenuItemType } from '../../initial-menus-state'; import { MenuItemModel } from './menu-item.model'; +import { MenuItemType } from '../../menu-item-type.model'; /** * Model representing an Altmetric Menu Section diff --git a/src/app/shared/menu/menu-item/models/link.model.ts b/src/app/shared/menu/menu-item/models/link.model.ts index a5b3671f621..e4f43a0c80c 100644 --- a/src/app/shared/menu/menu-item/models/link.model.ts +++ b/src/app/shared/menu/menu-item/models/link.model.ts @@ -1,5 +1,5 @@ import { MenuItemModel } from './menu-item.model'; -import { MenuItemType } from '../../initial-menus-state'; +import { MenuItemType } from '../../menu-item-type.model'; /** * Model representing an Link Menu Section diff --git a/src/app/shared/menu/menu-item/models/menu-item.model.ts b/src/app/shared/menu/menu-item/models/menu-item.model.ts index 7bf5fca0665..b60b55719ee 100644 --- a/src/app/shared/menu/menu-item/models/menu-item.model.ts +++ b/src/app/shared/menu/menu-item/models/menu-item.model.ts @@ -1,4 +1,4 @@ -import { MenuItemType } from '../../initial-menus-state'; +import { MenuItemType } from '../../menu-item-type.model'; /** * Interface for models representing a Menu Section diff --git a/src/app/shared/menu/menu-item/models/onclick.model.ts b/src/app/shared/menu/menu-item/models/onclick.model.ts index 4cef3084f90..2501163bfc1 100644 --- a/src/app/shared/menu/menu-item/models/onclick.model.ts +++ b/src/app/shared/menu/menu-item/models/onclick.model.ts @@ -1,5 +1,5 @@ import { MenuItemModel } from './menu-item.model'; -import { MenuItemType } from '../../initial-menus-state'; +import { MenuItemType } from '../../menu-item-type.model'; /** * Model representing an OnClick Menu Section diff --git a/src/app/shared/menu/menu-item/models/search.model.ts b/src/app/shared/menu/menu-item/models/search.model.ts index e8eeda5501e..eac281da515 100644 --- a/src/app/shared/menu/menu-item/models/search.model.ts +++ b/src/app/shared/menu/menu-item/models/search.model.ts @@ -1,5 +1,5 @@ -import { MenuItemType } from '../../initial-menus-state'; import { MenuItemModel } from './menu-item.model'; +import { MenuItemType } from '../../menu-item-type.model'; /** * Model representing an Search Bar Menu Section diff --git a/src/app/shared/menu/menu-item/models/text.model.ts b/src/app/shared/menu/menu-item/models/text.model.ts index bbaf7804d99..70dc7c12033 100644 --- a/src/app/shared/menu/menu-item/models/text.model.ts +++ b/src/app/shared/menu/menu-item/models/text.model.ts @@ -1,5 +1,5 @@ -import { MenuItemType } from '../../initial-menus-state'; import { MenuItemModel } from './menu-item.model'; +import { MenuItemType } from '../../menu-item-type.model'; /** * Model representing an Text Menu Section diff --git a/src/app/shared/menu/menu-item/onclick-menu-item.component.ts b/src/app/shared/menu/menu-item/onclick-menu-item.component.ts index 95b896ed644..e41dfea1876 100644 --- a/src/app/shared/menu/menu-item/onclick-menu-item.component.ts +++ b/src/app/shared/menu/menu-item/onclick-menu-item.component.ts @@ -1,7 +1,7 @@ import { Component, Inject } from '@angular/core'; -import { MenuItemType } from '../initial-menus-state'; import { rendersMenuItemForType } from '../menu-item.decorator'; import { OnClickMenuItemModel } from './models/onclick.model'; +import { MenuItemType } from '../menu-item-type.model'; /** * Component that renders a menu section of type ONCLICK diff --git a/src/app/shared/menu/menu-item/text-menu-item.component.ts b/src/app/shared/menu/menu-item/text-menu-item.component.ts index f7d3402be04..af690d198c4 100644 --- a/src/app/shared/menu/menu-item/text-menu-item.component.ts +++ b/src/app/shared/menu/menu-item/text-menu-item.component.ts @@ -1,7 +1,7 @@ import { Component, Inject, Input } from '@angular/core'; import { TextMenuItemModel } from './models/text.model'; -import { MenuItemType } from '../initial-menus-state'; import { rendersMenuItemForType } from '../menu-item.decorator'; +import { MenuItemType } from '../menu-item-type.model'; /** * Component that renders a menu section of type TEXT diff --git a/src/app/shared/menu/menu-section-Index.model.ts b/src/app/shared/menu/menu-section-Index.model.ts new file mode 100644 index 00000000000..f9b12f82362 --- /dev/null +++ b/src/app/shared/menu/menu-section-Index.model.ts @@ -0,0 +1,6 @@ +/** + * Represents the a mapping of all sections to their subsections for a menu in the store + */ +export interface MenuSectionIndex { + [id: string]: string[]; +} diff --git a/src/app/shared/menu/menu-section.decorator.ts b/src/app/shared/menu/menu-section.decorator.ts index c27e870e13e..2aa695aabd7 100644 --- a/src/app/shared/menu/menu-section.decorator.ts +++ b/src/app/shared/menu/menu-section.decorator.ts @@ -1,4 +1,4 @@ -import { MenuID } from './initial-menus-state'; +import { MenuID } from './menu-id.model'; const menuComponentMap = new Map(); diff --git a/src/app/shared/menu/menu-section.model.ts b/src/app/shared/menu/menu-section.model.ts new file mode 100644 index 00000000000..f14b029d776 --- /dev/null +++ b/src/app/shared/menu/menu-section.model.ts @@ -0,0 +1,15 @@ +import { MenuItemModel } from './menu-item/models/menu-item.model'; + +/** + * Represents the state of a single menu section in the store + */ +export class MenuSection { + id: string; + parentID?: string; + visible: boolean; + active: boolean; + model: MenuItemModel; + index?: number; + icon?: string; + shouldPersistOnRouteChange? = false; +} diff --git a/src/app/shared/menu/menu-section/menu-section.component.spec.ts b/src/app/shared/menu/menu-section/menu-section.component.spec.ts index 27d9821d52d..f40f45f9b4a 100644 --- a/src/app/shared/menu/menu-section/menu-section.component.spec.ts +++ b/src/app/shared/menu/menu-section/menu-section.component.spec.ts @@ -5,9 +5,9 @@ import { ChangeDetectionStrategy, Injector, NO_ERRORS_SCHEMA } from '@angular/co import { MenuSectionComponent } from './menu-section.component'; import { MenuService } from '../menu.service'; import { MenuServiceStub } from '../../testing/menu-service.stub'; -import { MenuSection } from '../menu.reducer'; import { of as observableOf } from 'rxjs'; import { LinkMenuItemComponent } from '../menu-item/link-menu-item.component'; +import { MenuSection } from '../menu-section.model'; describe('MenuSectionComponent', () => { let comp: MenuSectionComponent; diff --git a/src/app/shared/menu/menu-section/menu-section.component.ts b/src/app/shared/menu/menu-section/menu-section.component.ts index fcd96c65f1d..bef90b21c3c 100644 --- a/src/app/shared/menu/menu-section/menu-section.component.ts +++ b/src/app/shared/menu/menu-section/menu-section.component.ts @@ -1,13 +1,14 @@ import { Component, Injector, OnDestroy, OnInit } from '@angular/core'; import { MenuService } from '../menu.service'; -import { MenuSection } from '../menu.reducer'; import { getComponentForMenuItemType } from '../menu-item.decorator'; -import { MenuID, MenuItemType } from '../initial-menus-state'; import { hasNoValue, hasValue } from '../../empty.util'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { MenuItemModel } from '../menu-item/models/menu-item.model'; import { distinctUntilChanged, switchMap } from 'rxjs/operators'; import { GenericConstructor } from '../../../core/shared/generic-constructor'; +import { MenuSection } from '../menu-section.model'; +import { MenuID } from '../menu-id.model'; +import { MenuItemType } from '../menu-item-type.model'; /** * A basic implementation of a menu section's component diff --git a/src/app/shared/menu/menu-sections.model.ts b/src/app/shared/menu/menu-sections.model.ts new file mode 100644 index 00000000000..fc9dd818324 --- /dev/null +++ b/src/app/shared/menu/menu-sections.model.ts @@ -0,0 +1,8 @@ +import { MenuSection } from './menu-section.model'; + +/** + * Represents the state of all menu sections in the store + */ +export interface MenuSections { + [id: string]: MenuSection; +} diff --git a/src/app/shared/menu/menu-state.model.ts b/src/app/shared/menu/menu-state.model.ts new file mode 100644 index 00000000000..0bedac21293 --- /dev/null +++ b/src/app/shared/menu/menu-state.model.ts @@ -0,0 +1,15 @@ +import { MenuSectionIndex } from './menu-section-Index.model'; +import { MenuSections } from './menu-sections.model'; +import { MenuID } from './menu-id.model'; + +/** + * Represents the state of a single menu in the store + */ +export interface MenuState { + id: MenuID; + collapsed: boolean; + previewCollapsed: boolean; + visible: boolean; + sections: MenuSections; + sectionToSubsectionIndex: MenuSectionIndex; +} diff --git a/src/app/shared/menu/menu.actions.ts b/src/app/shared/menu/menu.actions.ts index 3f5bc995b1d..56607977e30 100644 --- a/src/app/shared/menu/menu.actions.ts +++ b/src/app/shared/menu/menu.actions.ts @@ -1,7 +1,7 @@ import { Action } from '@ngrx/store'; -import { MenuID } from './initial-menus-state'; import { type } from '../ngrx/type'; -import { MenuSection } from './menu.reducer'; +import { MenuSection } from './menu-section.model'; +import { MenuID } from './menu-id.model'; /** * For each action type in an action group, make a simple diff --git a/src/app/shared/menu/menu.component.spec.ts b/src/app/shared/menu/menu.component.spec.ts index 883969137b8..8c171094a03 100644 --- a/src/app/shared/menu/menu.component.spec.ts +++ b/src/app/shared/menu/menu.component.spec.ts @@ -6,10 +6,10 @@ import { MenuService } from './menu.service'; import { MenuComponent } from './menu.component'; import { MenuServiceStub } from '../testing/menu-service.stub'; import { of as observableOf } from 'rxjs'; -import { MenuSection } from './menu.reducer'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; -import { MenuID } from './initial-menus-state'; +import { MenuSection } from './menu-section.model'; +import { MenuID } from './menu-id.model'; describe('MenuComponent', () => { let comp: MenuComponent; diff --git a/src/app/shared/menu/menu.component.ts b/src/app/shared/menu/menu.component.ts index 32fd938f4e1..8c93e478c5f 100644 --- a/src/app/shared/menu/menu.component.ts +++ b/src/app/shared/menu/menu.component.ts @@ -1,14 +1,14 @@ import { ChangeDetectionStrategy, Component, Injector, OnDestroy, OnInit } from '@angular/core'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { MenuService } from './menu.service'; -import { MenuID } from './initial-menus-state'; -import { MenuSection } from './menu.reducer'; import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; import { GenericConstructor } from '../../core/shared/generic-constructor'; import { hasValue } from '../empty.util'; import { MenuSectionComponent } from './menu-section/menu-section.component'; import { getComponentForMenu } from './menu-section.decorator'; import { compareArraysUsingIds } from '../../item-page/simple/item-types/shared/item-relationships-utils'; +import { MenuSection } from './menu-section.model'; +import { MenuID } from './menu-id.model'; /** * A basic implementation of a MenuComponent diff --git a/src/app/shared/menu/menu.effects.spec.ts b/src/app/shared/menu/menu.effects.spec.ts index e8a4c6a7ceb..72319e06b80 100644 --- a/src/app/shared/menu/menu.effects.spec.ts +++ b/src/app/shared/menu/menu.effects.spec.ts @@ -1,5 +1,3 @@ -import { MenuID, MenuItemType } from './initial-menus-state'; -import { MenuSection } from './menu.reducer'; import { LinkMenuItemModel } from './menu-item/models/link.model'; import { TestBed } from '@angular/core/testing'; import { MenuService } from './menu.service'; @@ -9,6 +7,9 @@ import { provideMockActions } from '@ngrx/effects/testing'; import { cold, hot } from 'jasmine-marbles'; import { ROUTER_NAVIGATED } from '@ngrx/router-store'; import { MenuEffects } from './menu.effects'; +import { MenuSection } from './menu-section.model'; +import { MenuID } from './menu-id.model'; +import { MenuItemType } from './menu-item-type.model'; describe('MenuEffects', () => { let menuEffects: MenuEffects; diff --git a/src/app/shared/menu/menu.effects.ts b/src/app/shared/menu/menu.effects.ts index 47cff902093..2a9e536ae85 100644 --- a/src/app/shared/menu/menu.effects.ts +++ b/src/app/shared/menu/menu.effects.ts @@ -1,5 +1,4 @@ import { ActivatedRoute } from '@angular/router'; -import { MenuSection } from './menu.reducer'; import { hasNoValue, hasValue } from '../empty.util'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { MenuService } from './menu.service'; @@ -8,7 +7,8 @@ import { Action } from '@ngrx/store'; import { ROUTER_NAVIGATED } from '@ngrx/router-store'; import { Injectable } from '@angular/core'; import { map, take, tap } from 'rxjs/operators'; -import { MenuID } from './initial-menus-state'; +import { MenuSection } from './menu-section.model'; +import { MenuID } from './menu-id.model'; /** * Effects modifying the state of menus diff --git a/src/app/shared/menu/menu.reducer.spec.ts b/src/app/shared/menu/menu.reducer.spec.ts index f6db3e67d15..7ae05536af6 100644 --- a/src/app/shared/menu/menu.reducer.spec.ts +++ b/src/app/shared/menu/menu.reducer.spec.ts @@ -15,8 +15,10 @@ import { ToggleActiveMenuSectionAction, ToggleMenuAction } from './menu.actions'; -import { MenuSectionIndex, menusReducer } from './menu.reducer'; -import { initialMenusState, MenuID } from './initial-menus-state'; +import { menusReducer } from './menu.reducer'; +import { initialMenusState} from './initial-menus-state'; +import { MenuSectionIndex } from './menu-section-Index.model'; +import { MenuID } from './menu-id.model'; let visibleSection1; let dummyState; diff --git a/src/app/shared/menu/menu.reducer.ts b/src/app/shared/menu/menu.reducer.ts index b8a21d3507a..c7ea017cc24 100644 --- a/src/app/shared/menu/menu.reducer.ts +++ b/src/app/shared/menu/menu.reducer.ts @@ -10,56 +10,14 @@ import { ShowMenuSectionAction, ToggleActiveMenuSectionAction } from './menu.actions'; -import { initialMenusState, MenuID } from './initial-menus-state'; +import { initialMenusState} from './initial-menus-state'; import { hasValue } from '../empty.util'; -import { MenuItemModel } from './menu-item/models/menu-item.model'; - -/** - * Represents the state of all menus in the store - */ -export type MenusState = { - [id in MenuID]: MenuState; -}; - -/** - * Represents the state of a single menu in the store - */ -export interface MenuState { - id: MenuID; - collapsed: boolean; - previewCollapsed: boolean; - visible: boolean; - sections: MenuSections; - sectionToSubsectionIndex: MenuSectionIndex; -} - -/** - * Represents the a mapping of all sections to their subsections for a menu in the store - */ -export interface MenuSectionIndex { - [id: string]: string[]; -} - -/** - * Represents the state of all menu sections in the store - */ -export interface MenuSections { - [id: string]: MenuSection; -} - -/** - * Represents the state of a single menu section in the store - */ -export class MenuSection { - id: string; - parentID?: string; - visible: boolean; - active: boolean; - model: MenuItemModel; - index?: number; - icon?: string; - shouldPersistOnRouteChange? = false; -} +import { MenusState } from './menus-state.model'; +import { MenuState } from './menu-state.model'; +import { MenuSectionIndex } from './menu-section-Index.model'; +import { MenuSections } from './menu-sections.model'; +import { MenuSection } from './menu-section.model'; +import { MenuID } from './menu-id.model'; /** * Reducer that handles MenuActions to update the MenusState diff --git a/src/app/shared/menu/menu.service.spec.ts b/src/app/shared/menu/menu.service.spec.ts index c38cabaa53d..7a6b304ec13 100644 --- a/src/app/shared/menu/menu.service.spec.ts +++ b/src/app/shared/menu/menu.service.spec.ts @@ -6,7 +6,6 @@ import { provideMockStore } from '@ngrx/store/testing'; import { cold } from 'jasmine-marbles'; import { MenuService } from './menu.service'; -import { MenuID } from './initial-menus-state'; import { ActivateMenuSectionAction, AddMenuSectionAction, @@ -21,8 +20,10 @@ import { ToggleActiveMenuSectionAction, ToggleMenuAction } from './menu.actions'; -import { MenuSection, menusReducer } from './menu.reducer'; +import { menusReducer } from './menu.reducer'; import { storeModuleConfig } from '../../app.reducer'; +import { MenuSection } from './menu-section.model'; +import { MenuID } from './menu-id.model'; describe('MenuService', () => { let service: MenuService; diff --git a/src/app/shared/menu/menu.service.ts b/src/app/shared/menu/menu.service.ts index ac713f41940..ef8c0b1fadc 100644 --- a/src/app/shared/menu/menu.service.ts +++ b/src/app/shared/menu/menu.service.ts @@ -1,8 +1,6 @@ import { Injectable } from '@angular/core'; import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; -import { MenuSection, MenuSections, MenuState } from './menu.reducer'; import { AppState, keySelector } from '../../app.reducer'; -import { MenuID } from './initial-menus-state'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { @@ -20,6 +18,10 @@ import { ToggleMenuAction, } from './menu.actions'; import { hasNoValue, hasValue, hasValueOperator, isNotEmpty } from '../empty.util'; +import { MenuState } from './menu-state.model'; +import { MenuSections } from './menu-sections.model'; +import { MenuSection } from './menu-section.model'; +import { MenuID } from './menu-id.model'; export function menuKeySelector(key: string, selector): MemoizedSelector { return createSelector(selector, (state) => { diff --git a/src/app/shared/menu/menus-state.model.ts b/src/app/shared/menu/menus-state.model.ts new file mode 100644 index 00000000000..9590fa1760b --- /dev/null +++ b/src/app/shared/menu/menus-state.model.ts @@ -0,0 +1,9 @@ +import { MenuState } from './menu-state.model'; +import { MenuID } from './menu-id.model'; + +/** + * Represents the state of all menus in the store + */ +export type MenusState = { + [id in MenuID]: MenuState; +}; diff --git a/src/app/shared/mocks/remote-data-build.service.mock.ts b/src/app/shared/mocks/remote-data-build.service.mock.ts index a33326758fa..90071f8dc66 100644 --- a/src/app/shared/mocks/remote-data-build.service.mock.ts +++ b/src/app/shared/mocks/remote-data-build.service.mock.ts @@ -28,7 +28,8 @@ export function getMockRemoteDataBuildService(toRemoteDataObservable$?: Observab return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])); } }, - buildFromRequestUUID: (id: string) => createSuccessfulRemoteDataObject$({}) + buildFromRequestUUID: (id: string) => createSuccessfulRemoteDataObject$({}), + buildFromHref: (href: string) => createSuccessfulRemoteDataObject$({}) } as RemoteDataBuildService; } @@ -64,7 +65,8 @@ export function getMockRemoteDataBuildServiceHrefMap(toRemoteDataObservable$?: O }) ); }, - buildFromRequestUUID: (id: string) => createSuccessfulRemoteDataObject$({}) + buildFromRequestUUID: (id: string) => createSuccessfulRemoteDataObject$({}), + buildFromHref: (href: string) => createSuccessfulRemoteDataObject$({}) } as RemoteDataBuildService; } diff --git a/src/app/shared/mydspace-actions/mydspace-actions-service.factory.ts b/src/app/shared/mydspace-actions/mydspace-actions-service.factory.ts index 48a0630778b..4a0c5f1fb25 100644 --- a/src/app/shared/mydspace-actions/mydspace-actions-service.factory.ts +++ b/src/app/shared/mydspace-actions/mydspace-actions-service.factory.ts @@ -4,13 +4,13 @@ import { WorkspaceitemDataService } from '../../core/submission/workspaceitem-da import { ClaimedTaskDataService } from '../../core/tasks/claimed-task-data.service'; import { PoolTaskDataService } from '../../core/tasks/pool-task-data.service'; import { WorkflowItemDataService } from '../../core/submission/workflowitem-data.service'; -import { CacheableObject } from '../../core/cache/object-cache.reducer'; import { ItemDataService } from '../../core/data/item-data.service'; import { Item } from '../../core/shared/item.model'; import { PoolTask } from '../../core/tasks/models/pool-task-object.model'; import { ClaimedTask } from '../../core/tasks/models/claimed-task-object.model'; import { WorkspaceItem } from '../../core/submission/models/workspaceitem.model'; import { WorkflowItem } from '../../core/submission/models/workflowitem.model'; +import { CacheableObject } from '../../core/cache/cacheable-object.model'; /** * Class to return DataService for given ResourceType diff --git a/src/app/shared/object-collection/shared/listable-object.model.ts b/src/app/shared/object-collection/shared/listable-object.model.ts index 7ff6a8dc578..cb44cefb569 100644 --- a/src/app/shared/object-collection/shared/listable-object.model.ts +++ b/src/app/shared/object-collection/shared/listable-object.model.ts @@ -1,5 +1,5 @@ -import { EquatableObject } from '../../../core/utilities/equatable'; import { GenericConstructor } from '../../../core/shared/generic-constructor'; +import { EquatableObject } from '../../../core/utilities/equals.decorators'; export abstract class ListableObject extends EquatableObject { /** 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 index 0c6cd80a62e..7db53425d5b 100644 --- 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 @@ -5,7 +5,6 @@ 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 { FieldUpdates } from '../../core/data/object-updates/object-updates.reducer'; import { take } from 'rxjs/operators'; import { PaginationComponent } from '../pagination/pagination.component'; import { createSuccessfulRemoteDataObject } from '../remote-data.utils'; @@ -15,6 +14,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; 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', 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 index 64a3bc53614..8dba47566fa 100644 --- 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 @@ -1,4 +1,3 @@ -import { FieldUpdate, FieldUpdates } from '../../core/data/object-updates/object-updates.reducer'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list.model'; @@ -18,6 +17,8 @@ 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 diff --git a/src/app/shared/remote-data.utils.ts b/src/app/shared/remote-data.utils.ts index 14e3c04ecea..2a7dee6383c 100644 --- a/src/app/shared/remote-data.utils.ts +++ b/src/app/shared/remote-data.utils.ts @@ -1,7 +1,7 @@ import { RemoteData } from '../core/data/remote-data'; import { Observable, of as observableOf } from 'rxjs'; import { environment } from '../../environments/environment'; -import { RequestEntryState } from '../core/data/request.reducer'; +import { RequestEntryState } from '../core/data/request-entry-state.model'; /** * A fixed timestamp to use in tests diff --git a/src/app/shared/search/facet-config-response.model.ts b/src/app/shared/search/facet-config-response.model.ts index 74190d35ba6..0d8cb21a8a1 100644 --- a/src/app/shared/search/facet-config-response.model.ts +++ b/src/app/shared/search/facet-config-response.model.ts @@ -1,10 +1,10 @@ -import { CacheableObject } from '../../core/cache/object-cache.reducer'; import { typedObject } from '../../core/cache/builders/build-decorators'; import { FACET_CONFIG_RESPONSE } from './facet-config-response.resouce-type'; import { excludeFromEquals } from '../../core/utilities/equals.decorators'; import { SearchFilterConfig } from './search-filter-config.model'; import { deserialize } from 'cerialize'; import { HALLink } from '../../core/shared/hal-link.model'; +import { CacheableObject } from '../../core/cache/cacheable-object.model'; /** * The response from the discover/facets endpoint diff --git a/src/app/shared/search/search-filter-config.model.ts b/src/app/shared/search/search-filter-config.model.ts index 1a0be94d2be..3523042e1bb 100644 --- a/src/app/shared/search/search-filter-config.model.ts +++ b/src/app/shared/search/search-filter-config.model.ts @@ -2,9 +2,9 @@ import { FilterType } from './filter-type.model'; import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; import { HALLink } from '../../core/shared/hal-link.model'; import { typedObject } from '../../core/cache/builders/build-decorators'; -import { CacheableObject } from '../../core/cache/object-cache.reducer'; import { excludeFromEquals } from '../../core/utilities/equals.decorators'; import { SEARCH_FILTER_CONFIG } from './search-filter-config.resource-type'; +import { CacheableObject } from '../../core/cache/cacheable-object.model'; /** * The configuration for a search filter diff --git a/src/app/shared/search/search-filters/search-filters.component.spec.ts b/src/app/shared/search/search-filters/search-filters.component.spec.ts index 031c2e132bb..3864aeffd7a 100644 --- a/src/app/shared/search/search-filters/search-filters.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filters.component.spec.ts @@ -18,8 +18,6 @@ describe('SearchFiltersComponent', () => { const searchServiceStub = { /* tslint:disable:no-empty */ - getConfig: () => - observableOf({ hasSucceeded: true, payload: [] }), getClearFiltersQueryParams: () => { }, getSearchLink: () => { diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index 0556da44268..d602f28f0c3 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -83,7 +83,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { initFilters() { this.filters = this.searchConfigService.searchOptions.pipe( - switchMap((options) => this.searchService.getConfig(options.scope, options.configuration).pipe(getFirstSucceededRemoteData())), + switchMap((options) => this.searchConfigService.getConfig(options.scope, options.configuration).pipe(getFirstSucceededRemoteData())), ); } diff --git a/src/app/shared/testing/menu-service.stub.ts b/src/app/shared/testing/menu-service.stub.ts index 4f2828a7e16..14eccfda67d 100644 --- a/src/app/shared/testing/menu-service.stub.ts +++ b/src/app/shared/testing/menu-service.stub.ts @@ -1,6 +1,6 @@ -import { MenuID } from '../menu/initial-menus-state'; import { Observable, of as observableOf } from 'rxjs'; -import { MenuSection } from '../menu/menu.reducer'; +import { MenuSection } from '../menu/menu-section.model'; +import { MenuID } from '../menu/menu-id.model'; export class MenuServiceStub { visibleSection1 = { diff --git a/src/app/shared/testing/search-configuration-service.stub.ts b/src/app/shared/testing/search-configuration-service.stub.ts index 4b8f1d6f125..80744ba59a6 100644 --- a/src/app/shared/testing/search-configuration-service.stub.ts +++ b/src/app/shared/testing/search-configuration-service.stub.ts @@ -1,4 +1,6 @@ import { BehaviorSubject, of as observableOf } from 'rxjs'; +import { SearchConfig } from '../../core/shared/search/search-filters/search-config.model'; +import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; export class SearchConfigurationServiceStub { @@ -18,4 +20,24 @@ export class SearchConfigurationServiceStub { getCurrentConfiguration(a) { return observableOf(a); } + + getConfig () { + return observableOf({ hasSucceeded: true, payload: [] }); + } + + getAvailableConfigurationOptions() { + return observableOf([{value: 'test', label: 'test'}]); + } + + getConfigurationSearchConfigObservable() { + return observableOf(new SearchConfig()); + } + + getConfigurationSortOptionsObservable() { + return observableOf([new SortOptions('score', SortDirection.ASC), new SortOptions('score', SortDirection.DESC)]); + } + + initializeSortOptionsFromConfiguration() { + /* empty */ + } } diff --git a/src/app/shared/testing/utils.test.ts b/src/app/shared/testing/utils.test.ts index 342c987bc2b..1e62ee8f004 100644 --- a/src/app/shared/testing/utils.test.ts +++ b/src/app/shared/testing/utils.test.ts @@ -2,9 +2,10 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { Observable } from 'rxjs/internal/Observable'; -import { RequestEntry, RequestEntryState } from '../../core/data/request.reducer'; +import { RequestEntry} from '../../core/data/request.reducer'; import { of as observableOf } from 'rxjs/internal/observable/of'; import { UnCacheableObject } from '../../core/shared/uncacheable-object.model'; +import { RequestEntryState } from '../../core/data/request-entry-state.model'; /** * Returns true if a Native Element has a specified css class. diff --git a/src/app/statistics-page/statistics-page/statistics-page.component.ts b/src/app/statistics-page/statistics-page/statistics-page.component.ts index 099d2990151..7aceb5c9b7e 100644 --- a/src/app/statistics-page/statistics-page/statistics-page.component.ts +++ b/src/app/statistics-page/statistics-page/statistics-page.component.ts @@ -6,13 +6,13 @@ import { UsageReport } from '../../core/statistics/models/usage-report.model'; import { RemoteData } from '../../core/data/remote-data'; import { getRemoteDataPayload, - getFirstSucceededRemoteData, - redirectOn4xx + getFirstSucceededRemoteData } from '../../core/shared/operators'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { ActivatedRoute, Router } from '@angular/router'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { AuthService } from '../../core/auth/auth.service'; +import { redirectOn4xx } from '../../core/shared/authorized.operators'; /** * Class representing an abstract statistics page component. diff --git a/src/app/statistics/statistics-endpoint.model.ts b/src/app/statistics/statistics-endpoint.model.ts index 1dafa215b86..0a3671432e4 100644 --- a/src/app/statistics/statistics-endpoint.model.ts +++ b/src/app/statistics/statistics-endpoint.model.ts @@ -1,10 +1,10 @@ import { HALLink } from '../core/shared/hal-link.model'; import { typedObject } from '../core/cache/builders/build-decorators'; -import { CacheableObject } from '../core/cache/object-cache.reducer'; import { excludeFromEquals } from '../core/utilities/equals.decorators'; import { autoserialize, deserialize } from 'cerialize'; import { ResourceType } from '../core/shared/resource-type'; import { STATISTICS_ENDPOINT } from './statistics-endpoint.resource-type'; +import { CacheableObject } from '../core/cache/cacheable-object.model'; /** * Model class for the statistics endpoint diff --git a/src/app/submission/edit/submission-edit.component.ts b/src/app/submission/edit/submission-edit.component.ts index c415b89b81c..ecb39043f22 100644 --- a/src/app/submission/edit/submission-edit.component.ts +++ b/src/app/submission/edit/submission-edit.component.ts @@ -18,8 +18,8 @@ import { getAllSucceededRemoteData } from '../../core/shared/operators'; import { ItemDataService } from '../../core/data/item-data.service'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { SubmissionJsonPatchOperationsService } from '../../core/submission/submission-json-patch-operations.service'; -import { SubmissionError } from '../objects/submission-objects.reducer'; import parseSectionErrors from '../utils/parseSectionErrors'; +import { SubmissionError } from '../objects/submission-error.model'; /** * This component allows to edit an existing workspaceitem/workflowitem. diff --git a/src/app/submission/form/submission-form.component.ts b/src/app/submission/form/submission-form.component.ts index 4cbffbca78b..f204800164b 100644 --- a/src/app/submission/form/submission-form.component.ts +++ b/src/app/submission/form/submission-form.component.ts @@ -11,12 +11,13 @@ import { WorkspaceitemSectionsObject } from '../../core/submission/models/worksp import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { UploaderOptions } from '../../shared/uploader/uploader-options.model'; -import { SubmissionError, SubmissionObjectEntry } from '../objects/submission-objects.reducer'; +import { SubmissionObjectEntry } from '../objects/submission-objects.reducer'; import { SectionDataObject } from '../sections/models/section-data.model'; import { SubmissionService } from '../submission.service'; import { Item } from '../../core/shared/item.model'; import { SectionsType } from '../sections/sections-type'; import { SectionsService } from '../sections/sections.service'; +import { SubmissionError } from '../objects/submission-error.model'; /** * This component represents the submission form. diff --git a/src/app/submission/objects/section-visibility.model.ts b/src/app/submission/objects/section-visibility.model.ts new file mode 100644 index 00000000000..c41735178c1 --- /dev/null +++ b/src/app/submission/objects/section-visibility.model.ts @@ -0,0 +1,7 @@ +/** + * An interface to represent section visibility + */ +export interface SectionVisibility { + main: any; + other: any; +} diff --git a/src/app/submission/objects/submission-error.model.ts b/src/app/submission/objects/submission-error.model.ts new file mode 100644 index 00000000000..78a3143b7d0 --- /dev/null +++ b/src/app/submission/objects/submission-error.model.ts @@ -0,0 +1,8 @@ +import { SubmissionSectionError } from './submission-section-error.model'; + +/** + * An interface to represent section error + */ +export interface SubmissionError { + [submissionId: string]: SubmissionSectionError[]; +} diff --git a/src/app/submission/objects/submission-objects.actions.ts b/src/app/submission/objects/submission-objects.actions.ts index 4935acb7927..1f36b225920 100644 --- a/src/app/submission/objects/submission-objects.actions.ts +++ b/src/app/submission/objects/submission-objects.actions.ts @@ -1,7 +1,6 @@ import { Action } from '@ngrx/store'; import { type } from '../../shared/ngrx/type'; -import { SectionVisibility, SubmissionError, SubmissionSectionError } from './submission-objects.reducer'; import { WorkspaceitemSectionUploadFileObject } from '../../core/submission/models/workspaceitem-section-upload-file.model'; import { WorkspaceitemSectionDataType, @@ -11,6 +10,9 @@ import { SubmissionObject } from '../../core/submission/models/submission-object import { SubmissionDefinitionsModel } from '../../core/config/models/config-submission-definitions.model'; import { SectionsType } from '../sections/sections-type'; import { Item } from '../../core/shared/item.model'; +import { SectionVisibility } from './section-visibility.model'; +import { SubmissionError } from './submission-error.model'; +import { SubmissionSectionError } from './submission-section-error.model'; /** * For each action type in an action group, make a simple diff --git a/src/app/submission/objects/submission-objects.effects.ts b/src/app/submission/objects/submission-objects.effects.ts index b4ba1c24809..12f79b5be92 100644 --- a/src/app/submission/objects/submission-objects.effects.ts +++ b/src/app/submission/objects/submission-objects.effects.ts @@ -43,7 +43,7 @@ import { UpdateSectionDataAction, UpdateSectionDataSuccessAction } from './submission-objects.actions'; -import { SubmissionObjectEntry, SubmissionSectionError, SubmissionSectionObject } from './submission-objects.reducer'; +import { SubmissionObjectEntry} from './submission-objects.reducer'; import { Item } from '../../core/shared/item.model'; import { RemoteData } from '../../core/data/remote-data'; import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; @@ -51,6 +51,8 @@ import { SubmissionObjectDataService } from '../../core/submission/submission-ob import { followLink } from '../../shared/utils/follow-link-config.model'; import parseSectionErrorPaths, { SectionErrorPath } from '../utils/parseSectionErrorPaths'; import { FormState } from '../../shared/form/form.reducer'; +import { SubmissionSectionObject } from './submission-section-object.model'; +import { SubmissionSectionError } from './submission-section-error.model'; @Injectable() export class SubmissionObjectEffects { diff --git a/src/app/submission/objects/submission-objects.reducer.ts b/src/app/submission/objects/submission-objects.reducer.ts index 4159c56ae11..564e5a701b4 100644 --- a/src/app/submission/objects/submission-objects.reducer.ts +++ b/src/app/submission/objects/submission-objects.reducer.ts @@ -35,114 +35,8 @@ import { SubmissionObjectActionTypes, UpdateSectionDataAction } from './submission-objects.actions'; -import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model'; import { WorkspaceitemSectionUploadObject } from '../../core/submission/models/workspaceitem-section-upload.model'; -import { SectionsType } from '../sections/sections-type'; - -/** - * An interface to represent section visibility - */ -export interface SectionVisibility { - main: any; - other: any; -} - -/** - * An interface to represent section object state - */ -export interface SubmissionSectionObject { - /** - * The section header - */ - header: string; - - /** - * The section configuration url - */ - config: string; - - /** - * A boolean representing if this section is mandatory - */ - mandatory: boolean; - - /** - * The section type - */ - sectionType: SectionsType; - - /** - * The section visibility - */ - visibility: SectionVisibility; - - /** - * A boolean representing if this section is collapsed - */ - collapsed: boolean; - - /** - * A boolean representing if this section is enabled - */ - enabled: boolean; - - /** - * The list of the metadata ids of the section. - */ - metadata: string[]; - - /** - * The section data object - */ - data: WorkspaceitemSectionDataType; - - /** - * The list of the section's errors to show. It contains the error list to display when section is not pristine - */ - errorsToShow: SubmissionSectionError[]; - - /** - * The list of the section's errors detected by the server. They may not be shown yet if section is pristine - */ - serverValidationErrors: SubmissionSectionError[]; - - /** - * A boolean representing if this section is loading - */ - isLoading: boolean; - - /** - * A boolean representing if this section is valid - */ - isValid: boolean; - - /** - * The formId related to this section - */ - formId: string; -} - -/** - * An interface to represent section error - */ -export interface SubmissionError { - [submissionId: string]: SubmissionSectionError[]; -} - -/** - * An interface to represent section error - */ -export interface SubmissionSectionError { - /** - * A string representing error path - */ - path: string; - - /** - * The error message - */ - message: string; -} +import { SubmissionSectionObject } from './submission-section-object.model'; /** * An interface to represent SubmissionSectionObject entry diff --git a/src/app/submission/objects/submission-section-error.model.ts b/src/app/submission/objects/submission-section-error.model.ts new file mode 100644 index 00000000000..cf0d232a5a6 --- /dev/null +++ b/src/app/submission/objects/submission-section-error.model.ts @@ -0,0 +1,14 @@ +/** + * An interface to represent section error + */ +export interface SubmissionSectionError { + /** + * A string representing error path + */ + path: string; + + /** + * The error message + */ + message: string; +} diff --git a/src/app/submission/objects/submission-section-object.model.ts b/src/app/submission/objects/submission-section-object.model.ts new file mode 100644 index 00000000000..16e437da80f --- /dev/null +++ b/src/app/submission/objects/submission-section-object.model.ts @@ -0,0 +1,79 @@ +import { SectionsType } from '../sections/sections-type'; +import { SectionVisibility } from './section-visibility.model'; +import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model'; +import { SubmissionSectionError } from './submission-section-error.model'; + +/** + * An interface to represent section object state + */ +export interface SubmissionSectionObject { + /** + * The section header + */ + header: string; + + /** + * The section configuration url + */ + config: string; + + /** + * A boolean representing if this section is mandatory + */ + mandatory: boolean; + + /** + * The section type + */ + sectionType: SectionsType; + + /** + * The section visibility + */ + visibility: SectionVisibility; + + /** + * A boolean representing if this section is collapsed + */ + collapsed: boolean; + + /** + * A boolean representing if this section is enabled + */ + enabled: boolean; + + /** + * The list of the metadata ids of the section. + */ + metadata: string[]; + + /** + * The section data object + */ + data: WorkspaceitemSectionDataType; + + /** + * The list of the section's errors to show. It contains the error list to display when section is not pristine + */ + errorsToShow: SubmissionSectionError[]; + + /** + * The list of the section's errors detected by the server. They may not be shown yet if section is pristine + */ + serverValidationErrors: SubmissionSectionError[]; + + /** + * A boolean representing if this section is loading + */ + isLoading: boolean; + + /** + * A boolean representing if this section is valid + */ + isValid: boolean; + + /** + * The formId related to this section + */ + formId: string; +} diff --git a/src/app/submission/sections/form/section-form.component.spec.ts b/src/app/submission/sections/form/section-form.component.spec.ts index 90861bce5eb..35a64046f2b 100644 --- a/src/app/submission/sections/form/section-form.component.spec.ts +++ b/src/app/submission/sections/form/section-form.component.spec.ts @@ -35,7 +35,6 @@ import { FormFieldModel } from '../../../shared/form/builder/models/form-field.m import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model'; import { DynamicRowGroupModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-group-model'; import { DsDynamicInputModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model'; -import { SubmissionSectionError } from '../../objects/submission-objects.reducer'; import { DynamicFormControlEvent, DynamicFormControlEventType } from '@ng-dynamic-forms/core'; import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; import { FormRowModel } from '../../../core/config/models/config-submission-form.model'; @@ -45,6 +44,7 @@ import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { RequestService } from '../../../core/data/request.service'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { cold } from 'jasmine-marbles'; +import { SubmissionSectionError } from '../../objects/submission-section-error.model'; function getMockSubmissionFormsConfigService(): SubmissionFormsConfigService { return jasmine.createSpyObj('FormOperationsService', { diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index 8ae246dcca0..1850735cb7f 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -14,7 +14,6 @@ import { SubmissionFormsConfigService } from '../../../core/config/submission-fo import { hasValue, isEmpty, isNotEmpty, isUndefined } from '../../../shared/empty.util'; import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner'; import { SubmissionFormsModel } from '../../../core/config/models/config-submission-forms.model'; -import { SubmissionSectionError, SubmissionSectionObject } from '../../objects/submission-objects.reducer'; import { FormFieldPreviousValueObject } from '../../../shared/form/builder/models/form-field-previous-value-object'; import { SectionDataObject } from '../models/section-data.model'; import { renderSectionFor } from '../sections-decorator'; @@ -34,6 +33,8 @@ import { followLink } from '../../../shared/utils/follow-link-config.model'; import { environment } from '../../../../environments/environment'; import { ConfigObject } from '../../../core/config/models/config.model'; import { RemoteData } from '../../../core/data/remote-data'; +import { SubmissionSectionObject } from '../../objects/submission-section-object.model'; +import { SubmissionSectionError } from '../../objects/submission-section-error.model'; /** * This component represents a section that contains a Form. diff --git a/src/app/submission/sections/models/section-data.model.ts b/src/app/submission/sections/models/section-data.model.ts index 9078b5dfb9e..6f8126dffc0 100644 --- a/src/app/submission/sections/models/section-data.model.ts +++ b/src/app/submission/sections/models/section-data.model.ts @@ -1,6 +1,6 @@ -import { SubmissionSectionError } from '../../objects/submission-objects.reducer'; import { WorkspaceitemSectionDataType } from '../../../core/submission/models/workspaceitem-sections.model'; import { SectionsType } from '../sections-type'; +import { SubmissionSectionError } from '../../objects/submission-section-error.model'; /** * An interface to represent section model diff --git a/src/app/submission/sections/sections.directive.ts b/src/app/submission/sections/sections.directive.ts index a42cd4be789..3ffb317b153 100644 --- a/src/app/submission/sections/sections.directive.ts +++ b/src/app/submission/sections/sections.directive.ts @@ -6,10 +6,10 @@ import { uniq } from 'lodash'; import { SectionsService } from './sections.service'; import { hasValue, isNotEmpty, isNotNull } from '../../shared/empty.util'; -import { SubmissionSectionError } from '../objects/submission-objects.reducer'; import parseSectionErrorPaths, { SectionErrorPath } from '../utils/parseSectionErrorPaths'; import { SubmissionService } from '../submission.service'; import { SectionsType } from './sections-type'; +import { SubmissionSectionError } from '../objects/submission-section-error.model'; /** * Directive for handling generic section functionality diff --git a/src/app/submission/sections/sections.service.spec.ts b/src/app/submission/sections/sections.service.spec.ts index 9fbcedcc4d2..5aa47d1447b 100644 --- a/src/app/submission/sections/sections.service.spec.ts +++ b/src/app/submission/sections/sections.service.spec.ts @@ -31,12 +31,12 @@ import { import { FormClearErrorsAction } from '../../shared/form/form.actions'; import parseSectionErrors from '../utils/parseSectionErrors'; import { SubmissionScopeType } from '../../core/submission/submission-scope-type'; -import { SubmissionSectionError } from '../objects/submission-objects.reducer'; import { getMockScrollToService } from '../../shared/mocks/scroll-to-service.mock'; import { storeModuleConfig } from '../../app.reducer'; import { SectionsType } from './sections-type'; import { FormService } from '../../shared/form/form.service'; import { getMockFormService } from '../../shared/mocks/form-service.mock'; +import { SubmissionSectionError } from '../objects/submission-section-error.model'; describe('SectionsService test suite', () => { let notificationsServiceStub: NotificationsServiceStub; diff --git a/src/app/submission/sections/sections.service.ts b/src/app/submission/sections/sections.service.ts index dd68d42a871..64f9e2efcdc 100644 --- a/src/app/submission/sections/sections.service.ts +++ b/src/app/submission/sections/sections.service.ts @@ -19,9 +19,7 @@ import { UpdateSectionDataAction } from '../objects/submission-objects.actions'; import { - SubmissionObjectEntry, - SubmissionSectionError, - SubmissionSectionObject + SubmissionObjectEntry } from '../objects/submission-objects.reducer'; import { submissionObjectFromIdSelector, @@ -43,6 +41,8 @@ import { parseReviver } from '@ng-dynamic-forms/core'; import { FormService } from '../../shared/form/form.service'; import { JsonPatchOperationPathCombiner } from '../../core/json-patch/builder/json-patch-operation-path-combiner'; import { FormError } from '../../shared/form/form.reducer'; +import { SubmissionSectionObject } from '../objects/submission-section-object.model'; +import { SubmissionSectionError } from '../objects/submission-section-error.model'; /** * A service that provides methods used in submission process. diff --git a/src/app/submission/selectors.ts b/src/app/submission/selectors.ts index df337323812..2c6c03a4ffc 100644 --- a/src/app/submission/selectors.ts +++ b/src/app/submission/selectors.ts @@ -2,7 +2,8 @@ import { createSelector, MemoizedSelector, Selector } from '@ngrx/store'; import { hasValue } from '../shared/empty.util'; import { submissionSelector, SubmissionState } from './submission.reducers'; -import { SubmissionObjectEntry, SubmissionSectionObject } from './objects/submission-objects.reducer'; +import { SubmissionObjectEntry} from './objects/submission-objects.reducer'; +import { SubmissionSectionObject } from './objects/submission-section-object.model'; /** * Export a function to return a subset of the state by key diff --git a/src/app/submission/submission.service.ts b/src/app/submission/submission.service.ts index 4b3df65de1d..9eb8cf110a5 100644 --- a/src/app/submission/submission.service.ts +++ b/src/app/submission/submission.service.ts @@ -22,10 +22,8 @@ import { SetActiveSectionAction } from './objects/submission-objects.actions'; import { - SubmissionError, SubmissionObjectEntry, - SubmissionSectionEntry, - SubmissionSectionObject + SubmissionSectionEntry } from './objects/submission-objects.reducer'; import { submissionObjectFromIdSelector } from './selectors'; import { HttpOptions } from '../core/dspace-rest/dspace-rest.service'; @@ -46,6 +44,8 @@ import { SearchService } from '../core/shared/search/search.service'; import { Item } from '../core/shared/item.model'; import { environment } from '../../environments/environment'; import { SubmissionJsonPatchOperationsService } from '../core/submission/submission-json-patch-operations.service'; +import { SubmissionSectionObject } from './objects/submission-section-object.model'; +import { SubmissionError } from './objects/submission-error.model'; /** * A service that provides methods used in submission process. From 2ffb72320221b923d0064fec6fc47a04d34606ac Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Thu, 10 Mar 2022 13:04:22 +0530 Subject: [PATCH 005/409] [CST-5329] Add validate only check in the Import > Metadata page --- .../metadata-import-page.component.html | 4 +++ .../metadata-import-page.component.spec.ts | 25 ++++++++++++++++++- .../metadata-import-page.component.ts | 8 ++++++ src/assets/i18n/en.json5 | 2 ++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html index 42a04b0de6b..c70bc459471 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html @@ -1,6 +1,10 @@

{{'admin.metadata-import.page.help' | translate}}

+

+ + {{'admin.metadata-import.page.validateOnly' | translate}} +

{ comp.setFile(fileMock); }); - describe('if proceed button is pressed', () => { + describe('if proceed button is pressed without validate only', () => { beforeEach(fakeAsync(() => { + comp.validateOnly = false; const proceed = fixture.debugElement.query(By.css('#proceedButton')).nativeElement; proceed.click(); fixture.detectChanges(); @@ -107,6 +108,28 @@ describe('MetadataImportPageComponent', () => { }); }); + describe('if proceed button is pressed with validate only', () => { + beforeEach(fakeAsync(() => { + comp.validateOnly = true; + const proceed = fixture.debugElement.query(By.css('#proceedButton')).nativeElement; + proceed.click(); + fixture.detectChanges(); + })); + it('metadata-import script is invoked with -f fileName and the mockFile and -v validate-only', () => { + const parameterValues: ProcessParameter[] = [ + Object.assign(new ProcessParameter(), { name: '-f', value: 'filename.txt' }), + Object.assign(new ProcessParameter(), { name: '-v', value: true }), + ]; + expect(scriptService.invoke).toHaveBeenCalledWith(METADATA_IMPORT_SCRIPT_NAME, parameterValues, [fileMock]); + }); + it('success notification is shown', () => { + expect(notificationService.success).toHaveBeenCalled(); + }); + it('redirected to process page', () => { + expect(router.navigateByUrl).toHaveBeenCalledWith('/processes/45'); + }); + }); + describe('if proceed is pressed; but script invoke fails', () => { beforeEach(fakeAsync(() => { jasmine.getEnv().allowRespy(true); diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.ts b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.ts index 3bdcca3084a..deb16c0d732 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.ts +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.ts @@ -30,6 +30,11 @@ export class MetadataImportPageComponent { */ fileObject: File; + /** + * The validate only flag + */ + validateOnly = true; + public constructor(private location: Location, protected translate: TranslateService, protected notificationsService: NotificationsService, @@ -62,6 +67,9 @@ export class MetadataImportPageComponent { const parameterValues: ProcessParameter[] = [ Object.assign(new ProcessParameter(), { name: '-f', value: this.fileObject.name }), ]; + if (this.validateOnly) { + parameterValues.push(Object.assign(new ProcessParameter(), { name: '-v', value: true })); + } this.scriptDataService.invoke(METADATA_IMPORT_SCRIPT_NAME, parameterValues, [this.fileObject]).pipe( getFirstCompletedRemoteData(), diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index f33a195cfed..426fcb12d27 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -538,6 +538,8 @@ "admin.metadata-import.page.error.addFile": "Select file first!", + "admin.metadata-import.page.validateOnly": "Validate Only", + From 027b281d7a61031370a62f1388d23b8369410808 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Thu, 10 Mar 2022 14:45:53 +0530 Subject: [PATCH 006/409] [CST-5329] Add validate only check in the Import > Metadata page --- .../metadata-import-page.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html index c70bc459471..fb96c4becd5 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html @@ -3,7 +3,7 @@

{{'admin.metadata-import.page.help' | translate}}

- {{'admin.metadata-import.page.validateOnly' | translate}} + {{'admin.metadata-import.page.validateOnly' | translate}}

Date: Thu, 17 Mar 2022 13:00:00 +0100 Subject: [PATCH 007/409] 88300: Issue 1379 - Angular: Browse-by Subject does not allow to proceed to next pages once filtered --- .../shared/browse-by/browse-by.component.html | 23 +++- .../browse-by/browse-by.component.spec.ts | 20 +++- .../shared/browse-by/browse-by.component.ts | 19 ++- .../text/starts-with-text.component.html | 19 --- .../text/starts-with-text.component.spec.ts | 110 ------------------ src/app/shared/testing/route-service.stub.ts | 7 +- src/assets/i18n/en.json5 | 6 +- 7 files changed, 65 insertions(+), 139 deletions(-) diff --git a/src/app/shared/browse-by/browse-by.component.html b/src/app/shared/browse-by/browse-by.component.html index c1333246812..4837c92db86 100644 --- a/src/app/shared/browse-by/browse-by.component.html +++ b/src/app/shared/browse-by/browse-by.component.html @@ -12,6 +12,10 @@

{{title | translate}}

+
@@ -29,14 +33,25 @@
- - + +
- diff --git a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.ts b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.ts index ab756db562f..cbf8497f358 100644 --- a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; -import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { VersionedItemComponent } from '../../../../item-page/simple/item-types/versioned-item/versioned-item.component'; @listableObjectComponent('OrgUnit', ViewMode.StandalonePage) @Component({ @@ -12,5 +12,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh /** * The component for displaying metadata and relations of an item of the type Organisation Unit */ -export class OrgUnitComponent extends ItemComponent { +export class OrgUnitComponent extends VersionedItemComponent { } diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.html b/src/app/entity-groups/research-entities/item-pages/person/person.component.html index 5c2fd227fdf..6e71f775d6b 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.html +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.html @@ -3,6 +3,9 @@

{{'person.page.titleprefix' | translate}}

+
diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts index 8b104cc9b13..ad2863034ac 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; -import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { VersionedItemComponent } from '../../../../item-page/simple/item-types/versioned-item/versioned-item.component'; @listableObjectComponent('Person', ViewMode.StandalonePage) @Component({ @@ -12,5 +12,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh /** * The component for displaying metadata and relations of an item of the type Person */ -export class PersonComponent extends ItemComponent { +export class PersonComponent extends VersionedItemComponent { } diff --git a/src/app/entity-groups/research-entities/item-pages/project/project.component.html b/src/app/entity-groups/research-entities/item-pages/project/project.component.html index 8f2ff6adcda..243dae8b432 100644 --- a/src/app/entity-groups/research-entities/item-pages/project/project.component.html +++ b/src/app/entity-groups/research-entities/item-pages/project/project.component.html @@ -3,6 +3,9 @@

{{'project.page.titleprefix' | translate}}

+
diff --git a/src/app/entity-groups/research-entities/item-pages/project/project.component.ts b/src/app/entity-groups/research-entities/item-pages/project/project.component.ts index e53d8afd693..066427fc0d5 100644 --- a/src/app/entity-groups/research-entities/item-pages/project/project.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/project/project.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; -import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { VersionedItemComponent } from '../../../../item-page/simple/item-types/versioned-item/versioned-item.component'; @listableObjectComponent('Project', ViewMode.StandalonePage) @Component({ @@ -12,5 +12,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh /** * The component for displaying metadata and relations of an item of the type Project */ -export class ProjectComponent extends ItemComponent { +export class ProjectComponent extends VersionedItemComponent { } diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index bace9fcd0ad..667dee96f53 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -12,6 +12,9 @@

{{'publication.page.titleprefix' | translate}}

+
diff --git a/src/app/item-page/simple/item-types/publication/publication.component.ts b/src/app/item-page/simple/item-types/publication/publication.component.ts index 5ace8d04739..ba5037a1043 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.ts +++ b/src/app/item-page/simple/item-types/publication/publication.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { ItemComponent } from '../shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { VersionedItemComponent } from '../versioned-item/versioned-item.component'; /** * Component that represents a publication Item page @@ -14,6 +14,6 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh templateUrl: './publication.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class PublicationComponent extends ItemComponent { +export class PublicationComponent extends VersionedItemComponent { } From 716cea376da914d56f1f96a7aab3d7bc69a63f07 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 22 Mar 2022 13:29:23 +0100 Subject: [PATCH 012/409] fix circular dependency issues relating to request models --- .../epeople-registry.component.spec.ts | 2 +- .../eperson-form.component.spec.ts | 2 +- .../bitstream-formats.component.spec.ts | 2 +- .../bitstream-formats.component.ts | 2 +- .../metadata-registry.component.spec.ts | 2 +- .../metadata-schema.component.spec.ts | 2 +- .../browse-by-date-page.component.spec.ts | 2 +- .../browse-by-title-page.component.spec.ts | 2 +- .../community-list-datasource.ts | 2 +- .../community-list-service.spec.ts | 2 +- .../community-list-service.ts | 2 +- .../community-list.component.ts | 2 +- ...page-sub-collection-list.component.spec.ts | 2 +- ...-page-sub-community-list.component.spec.ts | 2 +- src/app/core/auth/auth-request.service.ts | 3 +- src/app/core/auth/authenticated.guard.ts | 2 +- .../auth/token-response-parsing.service.ts | 2 +- .../browse-definition-data.service.spec.ts | 2 +- .../browse/browse-definition-data.service.ts | 4 +- src/app/core/browse/browse.service.spec.ts | 2 +- .../core/cache/builders/link.service.spec.ts | 2 +- .../remote-data-build.service.spec.ts | 2 +- .../builders/remote-data-build.service.ts | 6 +-- .../core/cache/object-cache.service.spec.ts | 3 +- src/app/core/cache/object-cache.service.ts | 2 +- .../core/cache/server-sync-buffer.effects.ts | 2 +- src/app/core/config/config.service.spec.ts | 3 +- src/app/core/config/config.service.ts | 2 +- .../config/submission-forms-config.service.ts | 2 +- .../submission-uploads-config.service.ts | 2 +- src/app/core/core-state.model.ts | 30 ++++++++++++ src/app/core/core.module.ts | 3 +- src/app/core/core.reducers.ts | 38 +++++---------- src/app/core/core.selectors.ts | 2 +- .../base-response-parsing.service.spec.ts | 3 +- .../data/base-response-parsing.service.ts | 2 +- src/app/core/data/bitstream-data.service.ts | 5 +- .../bitstream-format-data.service.spec.ts | 4 +- .../data/bitstream-format-data.service.ts | 2 +- src/app/core/data/bundle-data.service.spec.ts | 2 +- src/app/core/data/bundle-data.service.ts | 5 +- src/app/core/data/collection-data.service.ts | 8 ++-- src/app/core/data/comcol-data.service.spec.ts | 4 +- src/app/core/data/comcol-data.service.ts | 2 +- src/app/core/data/community-data.service.ts | 4 +- .../core/data/configuration-data.service.ts | 2 +- ...content-source-response-parsing.service.ts | 2 +- src/app/core/data/data.service.spec.ts | 5 +- src/app/core/data/data.service.ts | 4 +- .../data/debug-response-parsing.service.ts | 2 +- .../data/dso-redirect-data.service.spec.ts | 2 +- .../core/data/dso-redirect-data.service.ts | 2 +- .../core/data/dso-response-parsing.service.ts | 2 +- .../core/data/dspace-object-data.service.ts | 4 +- .../dspace-rest-response-parsing.service.ts | 2 +- .../endpoint-map-response-parsing.service.ts | 2 +- src/app/core/data/entity-type.service.ts | 2 +- .../data/eperson-registration.service.spec.ts | 2 +- src/app/core/data/external-source.service.ts | 4 +- .../facet-config-response-parsing.service.ts | 2 +- .../facet-value-response-parsing.service.ts | 2 +- .../authorization-data.service.spec.ts | 2 +- .../authorization-data.service.ts | 4 +- .../feature-data.service.ts | 2 +- ...discovery-page-response-parsing.service.ts | 2 +- src/app/core/data/find-list-options.model.ts | 14 ++++++ .../core/data/href-only-data.service.spec.ts | 2 +- src/app/core/data/href-only-data.service.ts | 4 +- src/app/core/data/item-data.service.spec.ts | 7 +-- src/app/core/data/item-data.service.ts | 6 ++- .../data/item-template-data.service.spec.ts | 6 +-- .../core/data/item-template-data.service.ts | 2 +- .../data/metadata-field-data.service.spec.ts | 2 +- .../core/data/metadata-field-data.service.ts | 4 +- .../core/data/metadata-schema-data.service.ts | 2 +- .../data/mydspace-response-parsing.service.ts | 2 +- .../object-updates.service.spec.ts | 2 +- .../object-updates/object-updates.service.ts | 2 +- src/app/core/data/parsing.service.ts | 2 +- .../data/processes/process-data.service.ts | 2 +- .../data/processes/script-data.service.ts | 5 +- .../registration-response-parsing.service.ts | 2 +- .../core/data/relationship-type.service.ts | 2 +- .../core/data/relationship.service.spec.ts | 5 +- src/app/core/data/relationship.service.ts | 6 ++- src/app/core/data/request-entry.model.ts | 13 +++++ src/app/core/data/request-state.model.ts | 8 ++++ src/app/core/data/request.actions.ts | 2 +- src/app/core/data/request.effects.ts | 7 +-- src/app/core/data/request.models.ts | 48 ++++++------------- src/app/core/data/request.reducer.spec.ts | 3 +- src/app/core/data/request.reducer.ts | 24 +--------- src/app/core/data/request.service.spec.ts | 9 ++-- src/app/core/data/request.service.ts | 14 +++--- src/app/core/data/response-state.model.ts | 13 +++++ ...rest-request-with-response-parser.model.ts | 14 ++++++ src/app/core/data/rest-request.model.ts | 20 ++++++++ src/app/core/data/root-data.service.ts | 4 +- .../data/search-response-parsing.service.ts | 2 +- src/app/core/data/site-data.service.spec.ts | 4 +- src/app/core/data/site-data.service.ts | 2 +- ...atus-code-only-response-parsing.service.ts | 2 +- src/app/core/data/version-data.service.ts | 4 +- .../core/data/version-history-data.service.ts | 4 +- .../core/data/workflow-action-data.service.ts | 4 +- .../core/eperson/eperson-data.service.spec.ts | 5 +- src/app/core/eperson/eperson-data.service.ts | 3 +- .../core/eperson/group-data.service.spec.ts | 5 +- src/app/core/eperson/group-data.service.ts | 3 +- src/app/core/history/selectors.ts | 2 +- src/app/core/index/index.effects.ts | 2 +- src/app/core/index/index.selectors.ts | 2 +- .../builder/json-patch-operations-builder.ts | 2 +- .../json-patch-operations.service.spec.ts | 4 +- .../json-patch-operations.service.ts | 2 +- src/app/core/json-patch/selectors.ts | 2 +- src/app/core/metadata/metadata.service.ts | 2 +- .../pagination/pagination.service.spec.ts | 2 +- src/app/core/pagination/pagination.service.ts | 2 +- .../core/registry/registry.service.spec.ts | 2 +- src/app/core/registry/registry.service.ts | 2 +- .../resource-policy.service.spec.ts | 4 +- .../resource-policy.service.ts | 4 +- src/app/core/services/route.service.ts | 2 +- src/app/core/shared/operators.spec.ts | 2 +- src/app/core/shared/request.operators.ts | 5 +- .../search-configuration.service.spec.ts | 2 +- .../search/search-configuration.service.ts | 2 +- .../core/shared/search/search.service.spec.ts | 4 +- src/app/core/shared/search/search.service.ts | 5 +- .../statistics/usage-report-data.service.ts | 2 +- .../submission-cc-license-data.service.ts | 2 +- .../submission-cc-license-url-data.service.ts | 2 +- ...sion-json-patch-operations.service.spec.ts | 2 +- ...ubmission-json-patch-operations.service.ts | 2 +- .../submission-response-parsing.service.ts | 2 +- .../submission/submission-rest.service.ts | 2 +- .../models/vocabulary-find-options.model.ts | 2 +- .../vocabularies/vocabulary.service.spec.ts | 2 +- .../vocabularies/vocabulary.service.ts | 4 +- .../submission/workflowitem-data.service.ts | 2 +- .../submission/workspaceitem-data.service.ts | 2 +- .../tasks/claimed-task-data.service.spec.ts | 4 +- .../core/tasks/claimed-task-data.service.ts | 4 +- .../core/tasks/pool-task-data.service.spec.ts | 4 +- src/app/core/tasks/pool-task-data.service.ts | 4 +- .../tasks/task-response-parsing.service.ts | 2 +- src/app/core/tasks/tasks.service.spec.ts | 5 +- src/app/core/tasks/tasks.service.ts | 2 +- .../forgot-password-form.component.spec.ts | 2 +- .../forgot-password-form.component.ts | 2 +- ...top-level-community-list.component.spec.ts | 2 +- ...-and-drop-bitstream-list.component.spec.ts | 2 +- .../full-file-section.component.spec.ts | 2 +- .../related-items/related-items-component.ts | 2 +- .../collection-selector.component.spec.ts | 2 +- .../my-dspace-page.component.spec.ts | 2 +- .../process-overview.component.spec.ts | 2 +- .../overview/process-overview.component.ts | 2 +- .../create-profile.component.spec.ts | 2 +- .../create-profile.component.ts | 2 +- .../browse-by/browse-by.component.spec.ts | 2 +- .../collection-dropdown.component.spec.ts | 2 +- .../collection-dropdown.component.ts | 2 +- src/app/shared/log-in/log-in.component.ts | 2 +- .../password/log-in-password.component.ts | 2 +- .../shibboleth/log-in-shibboleth.component.ts | 2 +- .../mocks/remote-data-build.service.mock.ts | 2 +- src/app/shared/mocks/request.service.mock.ts | 2 +- .../item-detail-preview.component.spec.ts | 2 +- .../pagination/pagination.component.spec.ts | 2 +- src/app/shared/pagination/pagination.utils.ts | 2 +- .../eperson-group-list.component.spec.ts | 2 +- .../eperson-group-list.component.ts | 2 +- .../search-form/search-form.component.spec.ts | 2 +- .../search-facet-option.component.spec.ts | 2 +- ...earch-facet-range-option.component.spec.ts | 2 +- ...ch-facet-selected-option.component.spec.ts | 2 +- .../search-label.component.spec.ts | 2 +- .../date/starts-with-date.component.spec.ts | 2 +- .../text/starts-with-text.component.spec.ts | 2 +- .../shared/testing/pagination-service.stub.ts | 2 +- .../testing/submission-rest-service.stub.ts | 2 +- src/app/shared/testing/utils.test.ts | 2 +- .../shared/utils/follow-link-config.model.ts | 2 +- .../vocabulary-treeview.component.ts | 2 +- src/app/statistics/statistics.service.spec.ts | 8 ++-- src/app/statistics/statistics.service.ts | 2 +- ...mport-external-searchbar.component.spec.ts | 2 +- ...ion-import-external-searchbar.component.ts | 2 +- 190 files changed, 403 insertions(+), 322 deletions(-) create mode 100644 src/app/core/core-state.model.ts create mode 100644 src/app/core/data/find-list-options.model.ts create mode 100644 src/app/core/data/request-entry.model.ts create mode 100644 src/app/core/data/request-state.model.ts create mode 100644 src/app/core/data/response-state.model.ts create mode 100644 src/app/core/data/rest-request-with-response-parser.model.ts create mode 100644 src/app/core/data/rest-request.model.ts diff --git a/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts b/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts index bcf7e8f1d92..c0d70fd0b25 100644 --- a/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts +++ b/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts @@ -9,7 +9,6 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import { RemoteData } from '../../core/data/remote-data'; -import { FindListOptions } from '../../core/data/request.models'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { PageInfo } from '../../core/shared/page-info.model'; @@ -27,6 +26,7 @@ import { AuthorizationDataService } from '../../core/data/feature-authorization/ import { RequestService } from '../../core/data/request.service'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('EPeopleRegistryComponent', () => { let component: EPeopleRegistryComponent; diff --git a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.spec.ts b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.spec.ts index 832f4f6ce55..163f3d308a0 100644 --- a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.spec.ts +++ b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.spec.ts @@ -8,7 +8,6 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { buildPaginatedList, PaginatedList } from '../../../core/data/paginated-list.model'; import { RemoteData } from '../../../core/data/remote-data'; -import { FindListOptions } from '../../../core/data/request.models'; import { EPersonDataService } from '../../../core/eperson/eperson-data.service'; import { EPerson } from '../../../core/eperson/models/eperson.model'; import { PageInfo } from '../../../core/shared/page-info.model'; @@ -28,6 +27,7 @@ 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'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('EPersonFormComponent', () => { let component: EPersonFormComponent; diff --git a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts index 8cfba1d37bd..7d3a726eec7 100644 --- a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts +++ b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts @@ -25,9 +25,9 @@ import { import { createPaginatedList } from '../../../shared/testing/utils.test'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('BitstreamFormatsComponent', () => { let comp: BitstreamFormatsComponent; diff --git a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.ts b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.ts index cbbcbe07a4f..89d8ac29f3d 100644 --- a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.ts +++ b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.ts @@ -5,7 +5,6 @@ import { PaginatedList } from '../../../core/data/paginated-list.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { BitstreamFormat } from '../../../core/shared/bitstream-format.model'; import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service'; -import { FindListOptions } from '../../../core/data/request.models'; import { map, switchMap, take } from 'rxjs/operators'; import { hasValue } from '../../../shared/empty.util'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -13,6 +12,7 @@ import { Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { NoContent } from '../../../core/shared/NoContent.model'; import { PaginationService } from '../../../core/pagination/pagination.service'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; /** * This component renders a list of bitstream formats diff --git a/src/app/admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts b/src/app/admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts index 0253725cb93..af92bbd1cef 100644 --- a/src/app/admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts +++ b/src/app/admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts @@ -21,8 +21,8 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('MetadataRegistryComponent', () => { let comp: MetadataRegistryComponent; diff --git a/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts b/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts index 6eb3c5b1a44..8b2abe577c3 100644 --- a/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts +++ b/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts @@ -25,9 +25,9 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u import { VarDirective } from '../../../shared/utils/var.directive'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('MetadataSchemaComponent', () => { let comp: MetadataSchemaComponent; diff --git a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts index 7b0ddcb18eb..15ec9d78db8 100644 --- a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts +++ b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts @@ -20,9 +20,9 @@ import { VarDirective } from '../../shared/utils/var.directive'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('BrowseByDatePageComponent', () => { let comp: BrowseByDatePageComponent; diff --git a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts index 584da1c45af..554b059ac5c 100644 --- a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts +++ b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts @@ -20,9 +20,9 @@ import { VarDirective } from '../../shared/utils/var.directive'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('BrowseByTitlePageComponent', () => { let comp: BrowseByTitlePageComponent; diff --git a/src/app/community-list-page/community-list-datasource.ts b/src/app/community-list-page/community-list-datasource.ts index f234125373b..7f4d9be2b75 100644 --- a/src/app/community-list-page/community-list-datasource.ts +++ b/src/app/community-list-page/community-list-datasource.ts @@ -1,11 +1,11 @@ import { Subscription } from 'rxjs/internal/Subscription'; -import { FindListOptions } from '../core/data/request.models'; import { hasValue } from '../shared/empty.util'; import { CommunityListService} from './community-list-service'; import { CollectionViewer, DataSource } from '@angular/cdk/collections'; import { BehaviorSubject, Observable, } from 'rxjs'; import { finalize } from 'rxjs/operators'; import { FlatNode } from './flat-node.model'; +import { FindListOptions } from '../core/data/find-list-options.model'; /** * DataSource object needed by a CDK Tree to render its nodes. diff --git a/src/app/community-list-page/community-list-service.spec.ts b/src/app/community-list-page/community-list-service.spec.ts index f0e69128267..401ffe0b116 100644 --- a/src/app/community-list-page/community-list-service.spec.ts +++ b/src/app/community-list-page/community-list-service.spec.ts @@ -12,9 +12,9 @@ import { CollectionDataService } from '../core/data/collection-data.service'; import { CommunityDataService } from '../core/data/community-data.service'; import { Community } from '../core/shared/community.model'; import { Collection } from '../core/shared/collection.model'; -import { FindListOptions } from '../core/data/request.models'; import { PageInfo } from '../core/shared/page-info.model'; import { FlatNode } from './flat-node.model'; +import { FindListOptions } from '../core/data/find-list-options.model'; describe('CommunityListService', () => { let store: StoreMock; diff --git a/src/app/community-list-page/community-list-service.ts b/src/app/community-list-page/community-list-service.ts index b5b6ffa3f50..d09da8964b6 100644 --- a/src/app/community-list-page/community-list-service.ts +++ b/src/app/community-list-page/community-list-service.ts @@ -6,7 +6,6 @@ import { filter, map, switchMap } from 'rxjs/operators'; import { AppState } from '../app.reducer'; import { CommunityDataService } from '../core/data/community-data.service'; -import { FindListOptions } from '../core/data/request.models'; import { Community } from '../core/shared/community.model'; import { Collection } from '../core/shared/collection.model'; import { PageInfo } from '../core/shared/page-info.model'; @@ -22,6 +21,7 @@ import { getFirstCompletedRemoteData, getFirstSucceededRemoteData } from '../cor import { followLink } from '../shared/utils/follow-link-config.model'; import { FlatNode } from './flat-node.model'; import { ShowMoreFlatNode } from './show-more-flat-node.model'; +import { FindListOptions } from '../core/data/find-list-options.model'; // Helper method to combine an flatten an array of observables of flatNode arrays export const combineAndFlatten = (obsList: Observable[]): Observable => diff --git a/src/app/community-list-page/community-list/community-list.component.ts b/src/app/community-list-page/community-list/community-list.component.ts index d92c1c38602..556387da251 100644 --- a/src/app/community-list-page/community-list/community-list.component.ts +++ b/src/app/community-list-page/community-list/community-list.component.ts @@ -1,12 +1,12 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { take } from 'rxjs/operators'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { CommunityListService} from '../community-list-service'; import { CommunityListDatasource } from '../community-list-datasource'; import { FlatTreeControl } from '@angular/cdk/tree'; import { isEmpty } from '../../shared/empty.util'; import { FlatNode } from '../flat-node.model'; +import { FindListOptions } from '../../core/data/find-list-options.model'; /** * A tree-structured list of nodes representing the communities, their subCommunities and collections. diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts index 93a6c6fbb1c..ec61fac6130 100644 --- a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts @@ -11,7 +11,6 @@ import { CommunityPageSubCollectionListComponent } from './community-page-sub-co import { Community } from '../../core/shared/community.model'; import { SharedModule } from '../../shared/shared.module'; import { CollectionDataService } from '../../core/data/collection-data.service'; -import { FindListOptions } from '../../core/data/request.models'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; @@ -25,6 +24,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('CommunityPageSubCollectionList Component', () => { let comp: CommunityPageSubCollectionListComponent; diff --git a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts index e573259b63d..2bc829a3b05 100644 --- a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts +++ b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts @@ -13,7 +13,6 @@ import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { SharedModule } from '../../shared/shared.module'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; -import { FindListOptions } from '../../core/data/request.models'; import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub'; import { CommunityDataService } from '../../core/data/community-data.service'; @@ -25,6 +24,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('CommunityPageSubCommunityListComponent Component', () => { let comp: CommunityPageSubCommunityListComponent; diff --git a/src/app/core/auth/auth-request.service.ts b/src/app/core/auth/auth-request.service.ts index 00a94822d3b..da38d730a5f 100644 --- a/src/app/core/auth/auth-request.service.ts +++ b/src/app/core/auth/auth-request.service.ts @@ -3,7 +3,7 @@ import { distinctUntilChanged, filter, map, mergeMap, switchMap, tap } from 'rxj import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RequestService } from '../data/request.service'; import { isNotEmpty } from '../../shared/empty.util'; -import { GetRequest, PostRequest, RestRequest, } from '../data/request.models'; +import { GetRequest, PostRequest, } from '../data/request.models'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { getFirstCompletedRemoteData } from '../shared/operators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; @@ -11,6 +11,7 @@ import { RemoteData } from '../data/remote-data'; import { AuthStatus } from './models/auth-status.model'; import { ShortLivedToken } from './models/short-lived-token.model'; import { URLCombiner } from '../url-combiner/url-combiner'; +import { RestRequest } from '../data/rest-request.model'; /** * Abstract service to send authentication requests diff --git a/src/app/core/auth/authenticated.guard.ts b/src/app/core/auth/authenticated.guard.ts index 0b9eeec5095..1ab1d2e0a51 100644 --- a/src/app/core/auth/authenticated.guard.ts +++ b/src/app/core/auth/authenticated.guard.ts @@ -11,9 +11,9 @@ import { Observable } from 'rxjs'; import { map, find, switchMap } from 'rxjs/operators'; import { select, Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { isAuthenticated, isAuthenticationLoading } from './selectors'; import { AuthService, LOGIN_ROUTE } from './auth.service'; +import { CoreState } from '../core-state.model'; /** * Prevent unauthorized activating and loading of routes diff --git a/src/app/core/auth/token-response-parsing.service.ts b/src/app/core/auth/token-response-parsing.service.ts index d39b3cc33db..1ba7a16b14e 100644 --- a/src/app/core/auth/token-response-parsing.service.ts +++ b/src/app/core/auth/token-response-parsing.service.ts @@ -1,9 +1,9 @@ import { ResponseParsingService } from '../data/parsing.service'; -import { RestRequest } from '../data/request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RestResponse, TokenResponse } from '../cache/response.models'; import { isNotEmpty } from '../../shared/empty.util'; import { Injectable } from '@angular/core'; +import { RestRequest } from '../data/rest-request.model'; @Injectable() /** diff --git a/src/app/core/browse/browse-definition-data.service.spec.ts b/src/app/core/browse/browse-definition-data.service.spec.ts index 1127748ca9c..92de3e1e293 100644 --- a/src/app/core/browse/browse-definition-data.service.spec.ts +++ b/src/app/core/browse/browse-definition-data.service.spec.ts @@ -1,7 +1,7 @@ import { BrowseDefinitionDataService } from './browse-definition-data.service'; -import { FindListOptions } from '../data/request.models'; import { followLink } from '../../shared/utils/follow-link-config.model'; import { EMPTY } from 'rxjs'; +import { FindListOptions } from '../data/find-list-options.model'; describe(`BrowseDefinitionDataService`, () => { let service: BrowseDefinitionDataService; diff --git a/src/app/core/browse/browse-definition-data.service.ts b/src/app/core/browse/browse-definition-data.service.ts index 31338417caf..1930947f761 100644 --- a/src/app/core/browse/browse-definition-data.service.ts +++ b/src/app/core/browse/browse-definition-data.service.ts @@ -6,7 +6,6 @@ import { BrowseDefinition } from '../shared/browse-definition.model'; import { RequestService } from '../data/request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -15,8 +14,9 @@ import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Observable } from 'rxjs'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions } from '../data/request.models'; import { PaginatedList } from '../data/paginated-list.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/browse/browse.service.spec.ts b/src/app/core/browse/browse.service.spec.ts index a28add2e30a..634bdbff540 100644 --- a/src/app/core/browse/browse.service.spec.ts +++ b/src/app/core/browse/browse.service.spec.ts @@ -5,7 +5,6 @@ import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-bu 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 { RequestEntry } from '../data/request.reducer'; import { RequestService } from '../data/request.service'; import { BrowseDefinition } from '../shared/browse-definition.model'; import { BrowseEntrySearchOptions } from './browse-entry-search-options.model'; @@ -13,6 +12,7 @@ import { BrowseService } from './browse.service'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createPaginatedList, getFirstUsedArgumentOfSpyMethod } from '../../shared/testing/utils.test'; import { getMockHrefOnlyDataService } from '../../shared/mocks/href-only-data.service.mock'; +import { RequestEntry } from '../data/request-entry.model'; describe('BrowseService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/cache/builders/link.service.spec.ts b/src/app/core/cache/builders/link.service.spec.ts index f567c39314b..9ec3f9356bf 100644 --- a/src/app/core/cache/builders/link.service.spec.ts +++ b/src/app/core/cache/builders/link.service.spec.ts @@ -1,13 +1,13 @@ import { Injectable } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; -import { FindListOptions } from '../../data/request.models'; import { HALLink } from '../../shared/hal-link.model'; import { HALResource } from '../../shared/hal-resource.model'; import { ResourceType } from '../../shared/resource-type'; import { LinkService } from './link.service'; import { DATA_SERVICE_FACTORY, LINK_DEFINITION_FACTORY, LINK_DEFINITION_MAP_FACTORY } from './build-decorators'; import { isEmpty } from 'rxjs/operators'; +import { FindListOptions } from '../../data/find-list-options.model'; const TEST_MODEL = new ResourceType('testmodel'); let result: any; diff --git a/src/app/core/cache/builders/remote-data-build.service.spec.ts b/src/app/core/cache/builders/remote-data-build.service.spec.ts index adda4617183..1d22da494f6 100644 --- a/src/app/core/cache/builders/remote-data-build.service.spec.ts +++ b/src/app/core/cache/builders/remote-data-build.service.spec.ts @@ -13,11 +13,11 @@ import { RequestService } from '../../data/request.service'; import { UnCacheableObject } from '../../shared/uncacheable-object.model'; import { RemoteData } from '../../data/remote-data'; import { Observable, of as observableOf } from 'rxjs'; -import { RequestEntry} from '../../data/request.reducer'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { take } from 'rxjs/operators'; import { HALLink } from '../../shared/hal-link.model'; import { RequestEntryState } from '../../data/request-entry-state.model'; +import { RequestEntry } from '../../data/request-entry.model'; describe('RemoteDataBuildService', () => { let service: RemoteDataBuildService; diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index 1ae2ef961e3..016f6b16f6a 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -11,10 +11,6 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u import { FollowLinkConfig, followLink } from '../../../shared/utils/follow-link-config.model'; import { PaginatedList } from '../../data/paginated-list.model'; import { RemoteData } from '../../data/remote-data'; -import { - RequestEntry, - ResponseState -} from '../../data/request.reducer'; import { RequestService } from '../../data/request.service'; import { ObjectCacheService } from '../object-cache.service'; import { LinkService } from './link.service'; @@ -27,6 +23,8 @@ import { getUrlWithoutEmbedParams } from '../../index/index.selectors'; import { getResourceTypeValueFor } from '../object-cache.reducer'; import { hasSucceeded, RequestEntryState } from '../../data/request-entry-state.model'; import { getRequestFromRequestHref, getRequestFromRequestUUID } from '../../shared/request.operators'; +import { RequestEntry } from '../../data/request-entry.model'; +import { ResponseState } from '../../data/response-state.model'; @Injectable() export class RemoteDataBuildService { diff --git a/src/app/core/cache/object-cache.service.spec.ts b/src/app/core/cache/object-cache.service.spec.ts index e9cc7694a7a..bde6831967d 100644 --- a/src/app/core/cache/object-cache.service.spec.ts +++ b/src/app/core/cache/object-cache.service.spec.ts @@ -7,7 +7,7 @@ import { Operation } from 'fast-json-patch'; import { empty, of as observableOf } from 'rxjs'; import { first } from 'rxjs/operators'; -import { coreReducers, CoreState } from '../core.reducers'; +import { coreReducers} from '../core.reducers'; import { RestRequestMethod } from '../data/rest-request-method'; import { Item } from '../shared/item.model'; import { @@ -24,6 +24,7 @@ import { HALLink } from '../shared/hal-link.model'; import { storeModuleConfig } from '../../app.reducer'; import { TestColdObservable } from 'jasmine-marbles/src/test-observables'; import { IndexName } from '../index/index-name.model'; +import { CoreState } from '../core-state.model'; describe('ObjectCacheService', () => { let service: ObjectCacheService; diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts index 8b9660a668b..6d48242178c 100644 --- a/src/app/core/cache/object-cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -5,7 +5,7 @@ import { combineLatest as observableCombineLatest, Observable, of as observableO import { distinctUntilChanged, filter, map, mergeMap, switchMap, take } from 'rxjs/operators'; import { hasValue, isNotEmpty, isEmpty } from '../../shared/empty.util'; -import { CoreState } from '../core.reducers'; +import { CoreState } from '../core-state.model'; import { coreSelector } from '../core.selectors'; import { RestRequestMethod } from '../data/rest-request-method'; import { diff --git a/src/app/core/cache/server-sync-buffer.effects.ts b/src/app/core/cache/server-sync-buffer.effects.ts index d8ed88e12c1..10eedac3024 100644 --- a/src/app/core/cache/server-sync-buffer.effects.ts +++ b/src/app/core/cache/server-sync-buffer.effects.ts @@ -8,7 +8,6 @@ import { EmptySSBAction, ServerSyncBufferActionTypes } from './server-sync-buffer.actions'; -import { CoreState } from '../core.reducers'; import { Action, createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; @@ -22,6 +21,7 @@ import { environment } from '../../../environments/environment'; import { ObjectCacheEntry } from './object-cache.reducer'; import { Operation } from 'fast-json-patch'; import { NoOpAction } from '../../shared/ngrx/no-op.action'; +import { CoreState } from '../core-state.model'; @Injectable() export class ServerSyncBufferEffects { diff --git a/src/app/core/config/config.service.spec.ts b/src/app/core/config/config.service.spec.ts index 1eca35d2234..be354ddc6f9 100644 --- a/src/app/core/config/config.service.spec.ts +++ b/src/app/core/config/config.service.spec.ts @@ -3,11 +3,12 @@ import { TestScheduler } from 'rxjs/testing'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { ConfigService } from './config.service'; import { RequestService } from '../data/request.service'; -import { FindListOptions, GetRequest } from '../data/request.models'; +import { GetRequest } from '../data/request.models'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; +import { FindListOptions } from '../data/find-list-options.model'; const LINK_NAME = 'test'; const BROWSE = 'search/findByCollection'; diff --git a/src/app/core/config/config.service.ts b/src/app/core/config/config.service.ts index ddf909b5b0f..e52f9482f43 100644 --- a/src/app/core/config/config.service.ts +++ b/src/app/core/config/config.service.ts @@ -6,7 +6,6 @@ import { ConfigObject } from './models/config.model'; import { RemoteData } from '../data/remote-data'; import { DataService } from '../data/data.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; @@ -14,6 +13,7 @@ import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; import { map } from 'rxjs/operators'; +import { CoreState } from '../core-state.model'; class DataServiceImpl extends DataService { constructor( diff --git a/src/app/core/config/submission-forms-config.service.ts b/src/app/core/config/submission-forms-config.service.ts index a5c3f980605..1db5c2fa019 100644 --- a/src/app/core/config/submission-forms-config.service.ts +++ b/src/app/core/config/submission-forms-config.service.ts @@ -5,7 +5,6 @@ import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; @@ -17,6 +16,7 @@ import { SubmissionFormsModel } from './models/config-submission-forms.model'; import { RemoteData } from '../data/remote-data'; import { Observable } from 'rxjs'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { CoreState } from '../core-state.model'; @Injectable() @dataService(SUBMISSION_FORMS_TYPE) diff --git a/src/app/core/config/submission-uploads-config.service.ts b/src/app/core/config/submission-uploads-config.service.ts index a9e35a3183e..8ad17749bd3 100644 --- a/src/app/core/config/submission-uploads-config.service.ts +++ b/src/app/core/config/submission-uploads-config.service.ts @@ -7,7 +7,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { SUBMISSION_UPLOADS_TYPE } from './models/config-type'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; @@ -16,6 +15,7 @@ import { SubmissionUploadsModel } from './models/config-submission-uploads.model import { RemoteData } from '../data/remote-data'; import { Observable } from 'rxjs'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { CoreState } from '../core-state.model'; /** * Provides methods to retrieve, from REST server, bitstream access conditions configurations applicable during the submission process. diff --git a/src/app/core/core-state.model.ts b/src/app/core/core-state.model.ts new file mode 100644 index 00000000000..b8211fdb555 --- /dev/null +++ b/src/app/core/core-state.model.ts @@ -0,0 +1,30 @@ +import { + BitstreamFormatRegistryState +} from '../admin/admin-registries/bitstream-formats/bitstream-format.reducers'; +import { ObjectCacheState } from './cache/object-cache.reducer'; +import { ServerSyncBufferState } from './cache/server-sync-buffer.reducer'; +import { ObjectUpdatesState } from './data/object-updates/object-updates.reducer'; +import { HistoryState } from './history/history.reducer'; +import { MetaIndexState } from './index/index.reducer'; +import { AuthState } from './auth/auth.reducer'; +import { JsonPatchOperationsState } from './json-patch/json-patch-operations.reducer'; +import { MetaTagState } from './metadata/meta-tag.reducer'; +import { RouteState } from './services/route.reducer'; +import { RequestState } from './data/request-state.model'; + +/** + * The core sub-state in the NgRx store + */ +export interface CoreState { + 'bitstreamFormats': BitstreamFormatRegistryState; + 'cache/object': ObjectCacheState; + 'cache/syncbuffer': ServerSyncBufferState; + 'cache/object-updates': ObjectUpdatesState; + 'data/request': RequestState; + 'history': HistoryState; + 'index': MetaIndexState; + 'auth': AuthState; + 'json/patch': JsonPatchOperationsState; + 'metaTag': MetaTagState; + 'route': RouteState; +} diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 026c87be9d1..4ffc22355ca 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -42,7 +42,7 @@ import { SubmissionSectionModel } from './config/models/config-submission-sectio import { SubmissionUploadsModel } from './config/models/config-submission-uploads.model'; import { SubmissionFormsConfigService } from './config/submission-forms-config.service'; import { coreEffects } from './core.effects'; -import { coreReducers, CoreState } from './core.reducers'; +import { coreReducers} from './core.reducers'; import { BitstreamFormatDataService } from './data/bitstream-format-data.service'; import { CollectionDataService } from './data/collection-data.service'; import { CommunityDataService } from './data/community-data.service'; @@ -163,6 +163,7 @@ import { RootDataService } from './data/root-data.service'; import { Root } from './data/root.model'; import { SearchConfig } from './shared/search/search-filters/search-config.model'; import { SequenceService } from './shared/sequence.service'; +import { CoreState } from './core-state.model'; /** * When not in production, endpoint responses can be mocked for testing purposes diff --git a/src/app/core/core.reducers.ts b/src/app/core/core.reducers.ts index 8b3ec32b462..c0165c53848 100644 --- a/src/app/core/core.reducers.ts +++ b/src/app/core/core.reducers.ts @@ -1,33 +1,19 @@ import { ActionReducerMap, } from '@ngrx/store'; -import { objectCacheReducer, ObjectCacheState } from './cache/object-cache.reducer'; -import { indexReducer, MetaIndexState } from './index/index.reducer'; -import { requestReducer, RequestState } from './data/request.reducer'; -import { authReducer, AuthState } from './auth/auth.reducer'; -import { jsonPatchOperationsReducer, JsonPatchOperationsState } from './json-patch/json-patch-operations.reducer'; -import { serverSyncBufferReducer, ServerSyncBufferState } from './cache/server-sync-buffer.reducer'; -import { objectUpdatesReducer, ObjectUpdatesState } from './data/object-updates/object-updates.reducer'; -import { routeReducer, RouteState } from './services/route.reducer'; +import { objectCacheReducer } from './cache/object-cache.reducer'; +import { indexReducer } from './index/index.reducer'; +import { requestReducer } from './data/request.reducer'; +import { authReducer } from './auth/auth.reducer'; +import { jsonPatchOperationsReducer } from './json-patch/json-patch-operations.reducer'; +import { serverSyncBufferReducer } from './cache/server-sync-buffer.reducer'; +import { objectUpdatesReducer } from './data/object-updates/object-updates.reducer'; +import { routeReducer } from './services/route.reducer'; import { - bitstreamFormatReducer, - BitstreamFormatRegistryState + bitstreamFormatReducer } from '../admin/admin-registries/bitstream-formats/bitstream-format.reducers'; -import { historyReducer, HistoryState } from './history/history.reducer'; -import { metaTagReducer, MetaTagState } from './metadata/meta-tag.reducer'; - -export interface CoreState { - 'bitstreamFormats': BitstreamFormatRegistryState; - 'cache/object': ObjectCacheState; - 'cache/syncbuffer': ServerSyncBufferState; - 'cache/object-updates': ObjectUpdatesState; - 'data/request': RequestState; - 'history': HistoryState; - 'index': MetaIndexState; - 'auth': AuthState; - 'json/patch': JsonPatchOperationsState; - 'metaTag': MetaTagState; - 'route': RouteState; -} +import { historyReducer } from './history/history.reducer'; +import { metaTagReducer } from './metadata/meta-tag.reducer'; +import { CoreState } from './core-state.model'; export const coreReducers: ActionReducerMap = { 'bitstreamFormats': bitstreamFormatReducer, diff --git a/src/app/core/core.selectors.ts b/src/app/core/core.selectors.ts index 60365be7c26..77c7974de2c 100644 --- a/src/app/core/core.selectors.ts +++ b/src/app/core/core.selectors.ts @@ -1,5 +1,5 @@ import { createFeatureSelector } from '@ngrx/store'; -import { CoreState } from './core.reducers'; +import { CoreState } from './core-state.model'; /** * Base selector to select the core state from the store diff --git a/src/app/core/data/base-response-parsing.service.spec.ts b/src/app/core/data/base-response-parsing.service.spec.ts index c8a96838549..1ad584eab8d 100644 --- a/src/app/core/data/base-response-parsing.service.spec.ts +++ b/src/app/core/data/base-response-parsing.service.spec.ts @@ -1,8 +1,9 @@ import { BaseResponseParsingService } from './base-response-parsing.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { GetRequest, RestRequest } from './request.models'; +import { GetRequest} from './request.models'; import { DSpaceObject } from '../shared/dspace-object.model'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { RestRequest } from './rest-request.model'; /* tslint:disable:max-classes-per-file */ class TestService extends BaseResponseParsingService { diff --git a/src/app/core/data/base-response-parsing.service.ts b/src/app/core/data/base-response-parsing.service.ts index 61945c3161e..c8f416b894b 100644 --- a/src/app/core/data/base-response-parsing.service.ts +++ b/src/app/core/data/base-response-parsing.service.ts @@ -6,9 +6,9 @@ import { ObjectCacheService } from '../cache/object-cache.service'; import { GenericConstructor } from '../shared/generic-constructor'; import { PaginatedList, buildPaginatedList } from './paginated-list.model'; import { getClassForType } from '../cache/builders/build-decorators'; -import { RestRequest } from './request.models'; import { environment } from '../../../environments/environment'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { RestRequest } from './rest-request.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/data/bitstream-data.service.ts b/src/app/core/data/bitstream-data.service.ts index ca5e2761d8f..16f2cc16c26 100644 --- a/src/app/core/data/bitstream-data.service.ts +++ b/src/app/core/data/bitstream-data.service.ts @@ -9,7 +9,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { Bitstream } from '../shared/bitstream.model'; import { BITSTREAM } from '../shared/bitstream.resource-type'; import { Bundle } from '../shared/bundle.model'; @@ -20,7 +19,7 @@ import { DataService } from './data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { buildPaginatedList, PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { FindListOptions, PutRequest } from './request.models'; +import { PutRequest } from './request.models'; import { RequestService } from './request.service'; import { BitstreamFormatDataService } from './bitstream-format-data.service'; import { BitstreamFormat } from '../shared/bitstream-format.model'; @@ -29,6 +28,8 @@ import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.util import { PageInfo } from '../shared/page-info.model'; import { RequestParam } from '../cache/models/request-param.model'; import { sendRequest } from '../shared/request.operators'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service to retrieve {@link Bitstream}s from the REST API diff --git a/src/app/core/data/bitstream-format-data.service.spec.ts b/src/app/core/data/bitstream-format-data.service.spec.ts index c072803c83d..c1ebf90a471 100644 --- a/src/app/core/data/bitstream-format-data.service.spec.ts +++ b/src/app/core/data/bitstream-format-data.service.spec.ts @@ -1,5 +1,4 @@ import { BitstreamFormatDataService } from './bitstream-format-data.service'; -import { RequestEntry } from './request.reducer'; import { RestResponse } from '../cache/response.models'; import { Observable, of as observableOf } from 'rxjs'; import { Action, Store } from '@ngrx/store'; @@ -17,8 +16,9 @@ import { BitstreamFormatsRegistrySelectAction } from '../../admin/admin-registries/bitstream-formats/bitstream-format.actions'; import { TestScheduler } from 'rxjs/testing'; -import { CoreState } from '../core.reducers'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; describe('BitstreamFormatDataService', () => { let service: BitstreamFormatDataService; diff --git a/src/app/core/data/bitstream-format-data.service.ts b/src/app/core/data/bitstream-format-data.service.ts index 1f787f4bbcf..1af3db81035 100644 --- a/src/app/core/data/bitstream-format-data.service.ts +++ b/src/app/core/data/bitstream-format-data.service.ts @@ -13,7 +13,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { BitstreamFormat } from '../shared/bitstream-format.model'; import { BITSTREAM_FORMAT } from '../shared/bitstream-format.resource-type'; @@ -25,6 +24,7 @@ import { RemoteData } from './remote-data'; import { PostRequest, PutRequest } from './request.models'; import { RequestService } from './request.service'; import { sendRequest } from '../shared/request.operators'; +import { CoreState } from '../core-state.model'; const bitstreamFormatsStateSelector = createSelector( coreSelector, diff --git a/src/app/core/data/bundle-data.service.spec.ts b/src/app/core/data/bundle-data.service.spec.ts index ed149a624f2..12eec9e33d6 100644 --- a/src/app/core/data/bundle-data.service.spec.ts +++ b/src/app/core/data/bundle-data.service.spec.ts @@ -3,7 +3,6 @@ import { Store } from '@ngrx/store'; import { compare, Operation } from 'fast-json-patch'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { CoreState } from '../core.reducers'; import { Item } from '../shared/item.model'; import { ChangeAnalyzer } from './change-analyzer'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; @@ -13,6 +12,7 @@ import { HALLink } from '../shared/hal-link.model'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { Bundle } from '../shared/bundle.model'; +import { CoreState } from '../core-state.model'; class DummyChangeAnalyzer implements ChangeAnalyzer { diff(object1: Item, object2: Item): Operation[] { diff --git a/src/app/core/data/bundle-data.service.ts b/src/app/core/data/bundle-data.service.ts index 3aa4efda244..aedf5091930 100644 --- a/src/app/core/data/bundle-data.service.ts +++ b/src/app/core/data/bundle-data.service.ts @@ -9,7 +9,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { Bundle } from '../shared/bundle.model'; import { BUNDLE } from '../shared/bundle.resource-type'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -18,11 +17,13 @@ import { DataService } from './data.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { FindListOptions, GetRequest } from './request.models'; +import { GetRequest } from './request.models'; import { RequestService } from './request.service'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; import { Bitstream } from '../shared/bitstream.model'; import { RequestEntryState } from './request-entry-state.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service to retrieve {@link Bundle}s from the REST API diff --git a/src/app/core/data/collection-data.service.ts b/src/app/core/data/collection-data.service.ts index e6255144b6a..c3a27f87a49 100644 --- a/src/app/core/data/collection-data.service.ts +++ b/src/app/core/data/collection-data.service.ts @@ -13,7 +13,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RequestParam } from '../cache/models/request-param.model'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { Collection } from '../shared/collection.model'; @@ -29,12 +28,13 @@ import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { ContentSourceRequest, - FindListOptions, - UpdateContentSourceRequest, - RestRequest + UpdateContentSourceRequest } from './request.models'; import { RequestService } from './request.service'; import { BitstreamDataService } from './bitstream-data.service'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; @Injectable() @dataService(COLLECTION) diff --git a/src/app/core/data/comcol-data.service.spec.ts b/src/app/core/data/comcol-data.service.spec.ts index 35704878756..49c7d4620f1 100644 --- a/src/app/core/data/comcol-data.service.spec.ts +++ b/src/app/core/data/comcol-data.service.spec.ts @@ -7,13 +7,11 @@ import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { Community } from '../shared/community.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ComColDataService } from './comcol-data.service'; import { CommunityDataService } from './community-data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; -import { FindListOptions } from './request.models'; import { RequestService } from './request.service'; import { createFailedRemoteDataObject$, @@ -22,6 +20,8 @@ import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { BitstreamDataService } from './bitstream-data.service'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; const LINK_NAME = 'test'; diff --git a/src/app/core/data/comcol-data.service.ts b/src/app/core/data/comcol-data.service.ts index cf59c7ac745..01cd18df0cc 100644 --- a/src/app/core/data/comcol-data.service.ts +++ b/src/app/core/data/comcol-data.service.ts @@ -5,7 +5,6 @@ import { ObjectCacheService } from '../cache/object-cache.service'; import { Community } from '../shared/community.model'; import { HALLink } from '../shared/hal-link.model'; import { DataService } from './data.service'; -import { FindListOptions } from './request.models'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -17,6 +16,7 @@ import { NoContent } from '../shared/NoContent.model'; import { createFailedRemoteDataObject$ } from '../../shared/remote-data.utils'; import { URLCombiner } from '../url-combiner/url-combiner'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { FindListOptions } from './find-list-options.model'; export abstract class ComColDataService extends DataService { protected abstract objectCache: ObjectCacheService; diff --git a/src/app/core/data/community-data.service.ts b/src/app/core/data/community-data.service.ts index 82afe561a90..903d9bc79c4 100644 --- a/src/app/core/data/community-data.service.ts +++ b/src/app/core/data/community-data.service.ts @@ -8,7 +8,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { Community } from '../shared/community.model'; import { COMMUNITY } from '../shared/community.resource-type'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -16,11 +15,12 @@ import { ComColDataService } from './comcol-data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { FindListOptions } from './request.models'; import { RequestService } from './request.service'; import { BitstreamDataService } from './bitstream-data.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { isNotEmpty } from '../../shared/empty.util'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; @Injectable() @dataService(COMMUNITY) diff --git a/src/app/core/data/configuration-data.service.ts b/src/app/core/data/configuration-data.service.ts index 91d5af6ecc6..711eb6562f1 100644 --- a/src/app/core/data/configuration-data.service.ts +++ b/src/app/core/data/configuration-data.service.ts @@ -6,7 +6,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from './data.service'; import { RemoteData } from './remote-data'; @@ -14,6 +13,7 @@ import { RequestService } from './request.service'; import { ConfigurationProperty } from '../shared/configuration-property.model'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { CONFIG_PROPERTY } from '../shared/config-property.resource-type'; +import { CoreState } from '../core-state.model'; /* tslint:disable:max-classes-per-file */ class DataServiceImpl extends DataService { diff --git a/src/app/core/data/content-source-response-parsing.service.ts b/src/app/core/data/content-source-response-parsing.service.ts index 42b8f85c421..066ccf28c9d 100644 --- a/src/app/core/data/content-source-response-parsing.service.ts +++ b/src/app/core/data/content-source-response-parsing.service.ts @@ -4,8 +4,8 @@ import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { ContentSource } from '../shared/content-source.model'; import { MetadataConfig } from '../shared/metadata-config.model'; -import { RestRequest } from './request.models'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; +import { RestRequest } from './rest-request.model'; @Injectable() /** diff --git a/src/app/core/data/data.service.spec.ts b/src/app/core/data/data.service.spec.ts index 56ef753a795..ee4810d79a1 100644 --- a/src/app/core/data/data.service.spec.ts +++ b/src/app/core/data/data.service.spec.ts @@ -7,14 +7,13 @@ import { followLink } from '../../shared/utils/follow-link-config.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { SortDirection, SortOptions } from '../cache/models/sort-options.model'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSpaceObject } from '../shared/dspace-object.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { Item } from '../shared/item.model'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { ChangeAnalyzer } from './change-analyzer'; import { DataService } from './data.service'; -import { FindListOptions, PatchRequest } from './request.models'; +import { PatchRequest } from './request.models'; import { RequestService } from './request.service'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; @@ -23,6 +22,8 @@ import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-bu import { TestScheduler } from 'rxjs/testing'; import { RemoteData } from './remote-data'; import { RequestEntryState } from './request-entry-state.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; const endpoint = 'https://rest.api/core'; diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index 12a66e50926..310ad704ecb 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -22,7 +22,6 @@ import { getClassForType } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RequestParam } from '../cache/models/request-param.model'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceObject } from '../shared/dspace-object.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -34,7 +33,6 @@ import { RemoteData } from './remote-data'; import { CreateRequest, GetRequest, - FindListOptions, PatchRequest, PutRequest, DeleteRequest @@ -45,6 +43,8 @@ import { UpdateDataService } from './update-data.service'; import { GenericConstructor } from '../shared/generic-constructor'; import { NoContent } from '../shared/NoContent.model'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; export abstract class DataService implements UpdateDataService { protected abstract requestService: RequestService; diff --git a/src/app/core/data/debug-response-parsing.service.ts b/src/app/core/data/debug-response-parsing.service.ts index fbc07cbb395..992a29e4b84 100644 --- a/src/app/core/data/debug-response-parsing.service.ts +++ b/src/app/core/data/debug-response-parsing.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { RestResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ResponseParsingService } from './parsing.service'; -import { RestRequest } from './request.models'; +import { RestRequest } from './rest-request.model'; @Injectable() export class DebugResponseParsingService implements ResponseParsingService { diff --git a/src/app/core/data/dso-redirect-data.service.spec.ts b/src/app/core/data/dso-redirect-data.service.spec.ts index bcd25487c2e..3f3a799e457 100644 --- a/src/app/core/data/dso-redirect-data.service.spec.ts +++ b/src/app/core/data/dso-redirect-data.service.spec.ts @@ -6,13 +6,13 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { followLink } from '../../shared/utils/follow-link-config.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DsoRedirectDataService } from './dso-redirect-data.service'; import { GetRequest, IdentifierType } from './request.models'; import { RequestService } from './request.service'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { Item } from '../shared/item.model'; +import { CoreState } from '../core-state.model'; describe('DsoRedirectDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/dso-redirect-data.service.ts b/src/app/core/data/dso-redirect-data.service.ts index 83395d47193..6270689f035 100644 --- a/src/app/core/data/dso-redirect-data.service.ts +++ b/src/app/core/data/dso-redirect-data.service.ts @@ -9,7 +9,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from './data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; @@ -20,6 +19,7 @@ import { getFirstCompletedRemoteData } from '../shared/operators'; import { DSpaceObject } from '../shared/dspace-object.model'; import { Item } from '../shared/item.model'; import { getItemPageRoute } from '../../item-page/item-page-routing-paths'; +import { CoreState } from '../core-state.model'; @Injectable() export class DsoRedirectDataService extends DataService { diff --git a/src/app/core/data/dso-response-parsing.service.ts b/src/app/core/data/dso-response-parsing.service.ts index 7dde1f53a17..fd5a22fae96 100644 --- a/src/app/core/data/dso-response-parsing.service.ts +++ b/src/app/core/data/dso-response-parsing.service.ts @@ -3,12 +3,12 @@ import { Injectable } from '@angular/core'; import { ObjectCacheService } from '../cache/object-cache.service'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RestResponse, DSOSuccessResponse } from '../cache/response.models'; -import { RestRequest } from './request.models'; import { ResponseParsingService } from './parsing.service'; import { BaseResponseParsingService } from './base-response-parsing.service'; import { hasNoValue, hasValue } from '../../shared/empty.util'; import { DSpaceObject } from '../shared/dspace-object.model'; +import { RestRequest } from './rest-request.model'; @Injectable() export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService { diff --git a/src/app/core/data/dspace-object-data.service.ts b/src/app/core/data/dspace-object-data.service.ts index eb230e2f543..f78debf9cd2 100644 --- a/src/app/core/data/dspace-object-data.service.ts +++ b/src/app/core/data/dspace-object-data.service.ts @@ -7,7 +7,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSpaceObject } from '../shared/dspace-object.model'; import { DSPACE_OBJECT } from '../shared/dspace-object.resource-type'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -15,8 +14,9 @@ import { DataService } from './data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; -import { FindListOptions } from './request.models'; import { PaginatedList } from './paginated-list.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /* tslint:disable:max-classes-per-file */ class DataServiceImpl extends DataService { 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 27af802ce81..22506b7d7d7 100644 --- a/src/app/core/data/dspace-rest-response-parsing.service.ts +++ b/src/app/core/data/dspace-rest-response-parsing.service.ts @@ -6,7 +6,6 @@ import { ObjectCacheService } from '../cache/object-cache.service'; import { GenericConstructor } from '../shared/generic-constructor'; import { PaginatedList, buildPaginatedList } from './paginated-list.model'; import { getClassForType } from '../cache/builders/build-decorators'; -import { RestRequest } from './request.models'; import { environment } from '../../../environments/environment'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceObject } from '../shared/dspace-object.model'; @@ -17,6 +16,7 @@ import { RestRequestMethod } from './rest-request-method'; import { getUrlWithoutEmbedParams, getEmbedSizeParams } from '../index/index.selectors'; import { URLCombiner } from '../url-combiner/url-combiner'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { RestRequest } from './rest-request.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/data/endpoint-map-response-parsing.service.ts b/src/app/core/data/endpoint-map-response-parsing.service.ts index 73396e78bbe..728714876c4 100644 --- a/src/app/core/data/endpoint-map-response-parsing.service.ts +++ b/src/app/core/data/endpoint-map-response-parsing.service.ts @@ -7,12 +7,12 @@ import { import { hasValue } from '../../shared/empty.util'; import { getClassForType } from '../cache/builders/build-decorators'; import { GenericConstructor } from '../shared/generic-constructor'; -import { RestRequest } from './request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ParsedResponse } from '../cache/response.models'; import { DSpaceObject } from '../shared/dspace-object.model'; import { environment } from '../../../environments/environment'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { RestRequest } from './rest-request.model'; /** * ResponseParsingService able to deal with HAL Endpoints that are only needed as steps diff --git a/src/app/core/data/entity-type.service.ts b/src/app/core/data/entity-type.service.ts index ca9ea15bc6c..cedad93a140 100644 --- a/src/app/core/data/entity-type.service.ts +++ b/src/app/core/data/entity-type.service.ts @@ -3,7 +3,6 @@ import { DataService } from './data.service'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -18,6 +17,7 @@ import { PaginatedList } from './paginated-list.model'; import { ItemType } from '../shared/item-relationships/item-type.model'; import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../shared/operators'; import { RelationshipTypeService } from './relationship-type.service'; +import { CoreState } from '../core-state.model'; /** * Service handling all ItemType requests diff --git a/src/app/core/data/eperson-registration.service.spec.ts b/src/app/core/data/eperson-registration.service.spec.ts index 768d83c0246..6f73813bd45 100644 --- a/src/app/core/data/eperson-registration.service.spec.ts +++ b/src/app/core/data/eperson-registration.service.spec.ts @@ -1,7 +1,6 @@ import { RequestService } from './request.service'; import { EpersonRegistrationService } from './eperson-registration.service'; import { RestResponse } from '../cache/response.models'; -import { RequestEntry } from './request.reducer'; import { cold } from 'jasmine-marbles'; import { PostRequest } from './request.models'; import { Registration } from '../shared/registration.model'; @@ -9,6 +8,7 @@ import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-servic import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { of as observableOf } from 'rxjs/internal/observable/of'; import { TestScheduler } from 'rxjs/testing'; +import { RequestEntry } from './request-entry.model'; describe('EpersonRegistrationService', () => { let testScheduler; diff --git a/src/app/core/data/external-source.service.ts b/src/app/core/data/external-source.service.ts index a3a0a532ec6..9c6f75e6b89 100644 --- a/src/app/core/data/external-source.service.ts +++ b/src/app/core/data/external-source.service.ts @@ -4,12 +4,10 @@ import { ExternalSource } from '../shared/external-source.model'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { distinctUntilChanged, map, switchMap, take } from 'rxjs/operators'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; @@ -19,6 +17,8 @@ import { PaginatedList } from './paginated-list.model'; import { ExternalSourceEntry } from '../shared/external-source-entry.model'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service handling all external source requests diff --git a/src/app/core/data/facet-config-response-parsing.service.ts b/src/app/core/data/facet-config-response-parsing.service.ts index fc543c9072f..1fb3848f2da 100644 --- a/src/app/core/data/facet-config-response-parsing.service.ts +++ b/src/app/core/data/facet-config-response-parsing.service.ts @@ -3,9 +3,9 @@ import { SearchFilterConfig } from '../../shared/search/search-filter-config.mod import { ParsedResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; -import { RestRequest } from './request.models'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; import { FacetConfigResponse } from '../../shared/search/facet-config-response.model'; +import { RestRequest } from './rest-request.model'; @Injectable() export class FacetConfigResponseParsingService extends DspaceRestResponseParsingService { diff --git a/src/app/core/data/facet-value-response-parsing.service.ts b/src/app/core/data/facet-value-response-parsing.service.ts index 6b9e8326850..8053e97cf6c 100644 --- a/src/app/core/data/facet-value-response-parsing.service.ts +++ b/src/app/core/data/facet-value-response-parsing.service.ts @@ -3,9 +3,9 @@ import { FacetValue } from '../../shared/search/facet-value.model'; import { ParsedResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; -import { RestRequest } from './request.models'; import { FacetValues } from '../../shared/search/facet-values.model'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; +import { RestRequest } from './rest-request.model'; @Injectable() export class FacetValueResponseParsingService extends DspaceRestResponseParsingService { diff --git a/src/app/core/data/feature-authorization/authorization-data.service.spec.ts b/src/app/core/data/feature-authorization/authorization-data.service.spec.ts index 01bd23d7c7c..df46d3f0a18 100644 --- a/src/app/core/data/feature-authorization/authorization-data.service.spec.ts +++ b/src/app/core/data/feature-authorization/authorization-data.service.spec.ts @@ -4,7 +4,6 @@ import { AuthService } from '../../auth/auth.service'; import { Site } from '../../shared/site.model'; import { EPerson } from '../../eperson/models/eperson.model'; import { of as observableOf } from 'rxjs'; -import { FindListOptions } from '../request.models'; import { FeatureID } from './feature-id'; import { hasValue } from '../../../shared/empty.util'; import { RequestParam } from '../../cache/models/request-param.model'; @@ -12,6 +11,7 @@ import { Authorization } from '../../shared/authorization.model'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createPaginatedList } from '../../../shared/testing/utils.test'; import { Feature } from '../../shared/feature.model'; +import { FindListOptions } from '../find-list-options.model'; describe('AuthorizationDataService', () => { let service: AuthorizationDataService; diff --git a/src/app/core/data/feature-authorization/authorization-data.service.ts b/src/app/core/data/feature-authorization/authorization-data.service.ts index b9812cdbb31..1f8c8b2284d 100644 --- a/src/app/core/data/feature-authorization/authorization-data.service.ts +++ b/src/app/core/data/feature-authorization/authorization-data.service.ts @@ -7,7 +7,6 @@ import { Authorization } from '../../shared/authorization.model'; import { RequestService } from '../request.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -15,7 +14,6 @@ import { HttpClient } from '@angular/common/http'; import { DSOChangeAnalyzer } from '../dso-change-analyzer.service'; import { AuthService } from '../../auth/auth.service'; import { SiteDataService } from '../site-data.service'; -import { FindListOptions } from '../request.models'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { RemoteData } from '../remote-data'; import { PaginatedList } from '../paginated-list.model'; @@ -26,6 +24,8 @@ import { AuthorizationSearchParams } from './authorization-search-params'; import { addSiteObjectUrlIfEmpty, oneAuthorizationMatchesFeature } from './authorization-utils'; import { FeatureID } from './feature-id'; import { getFirstCompletedRemoteData } from '../../shared/operators'; +import { CoreState } from '../../core-state.model'; +import { FindListOptions } from '../find-list-options.model'; /** * A service to retrieve {@link Authorization}s from the REST API diff --git a/src/app/core/data/feature-authorization/feature-data.service.ts b/src/app/core/data/feature-authorization/feature-data.service.ts index 12be6f84524..cbe83566607 100644 --- a/src/app/core/data/feature-authorization/feature-data.service.ts +++ b/src/app/core/data/feature-authorization/feature-data.service.ts @@ -6,12 +6,12 @@ import { Feature } from '../../shared/feature.model'; import { RequestService } from '../request.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DSOChangeAnalyzer } from '../dso-change-analyzer.service'; +import { CoreState } from '../../core-state.model'; /** * A service to retrieve {@link Feature}s from the REST API diff --git a/src/app/core/data/filtered-discovery-page-response-parsing.service.ts b/src/app/core/data/filtered-discovery-page-response-parsing.service.ts index 7a2ff7962d5..4f28a16318d 100644 --- a/src/app/core/data/filtered-discovery-page-response-parsing.service.ts +++ b/src/app/core/data/filtered-discovery-page-response-parsing.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; import { ResponseParsingService } from './parsing.service'; -import { RestRequest } from './request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { BaseResponseParsingService } from './base-response-parsing.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { FilteredDiscoveryQueryResponse, RestResponse } from '../cache/response.models'; +import { RestRequest } from './rest-request.model'; /** * A ResponseParsingService used to parse RawRestResponse coming from the REST API to a discovery query (string) diff --git a/src/app/core/data/find-list-options.model.ts b/src/app/core/data/find-list-options.model.ts new file mode 100644 index 00000000000..52a527d9e07 --- /dev/null +++ b/src/app/core/data/find-list-options.model.ts @@ -0,0 +1,14 @@ +import { SortOptions } from '../cache/models/sort-options.model'; +import { RequestParam } from '../cache/models/request-param.model'; + +/** + * The options for a find list request + */ +export class FindListOptions { + scopeID?: string; + elementsPerPage?: number; + currentPage?: number; + sort?: SortOptions; + searchParams?: RequestParam[]; + startsWith?: string; +} diff --git a/src/app/core/data/href-only-data.service.spec.ts b/src/app/core/data/href-only-data.service.spec.ts index dd4be832038..64c451837d5 100644 --- a/src/app/core/data/href-only-data.service.spec.ts +++ b/src/app/core/data/href-only-data.service.spec.ts @@ -1,8 +1,8 @@ import { HrefOnlyDataService } from './href-only-data.service'; import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; -import { FindListOptions } from './request.models'; import { DataService } from './data.service'; +import { FindListOptions } from './find-list-options.model'; describe(`HrefOnlyDataService`, () => { let service: HrefOnlyDataService; diff --git a/src/app/core/data/href-only-data.service.ts b/src/app/core/data/href-only-data.service.ts index 4baffea5453..d5656e0eb62 100644 --- a/src/app/core/data/href-only-data.service.ts +++ b/src/app/core/data/href-only-data.service.ts @@ -2,7 +2,6 @@ import { DataService } from './data.service'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -10,7 +9,6 @@ import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { Injectable } from '@angular/core'; import { VOCABULARY_ENTRY } from '../submission/vocabularies/models/vocabularies.resource-type'; -import { FindListOptions } from './request.models'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteData } from './remote-data'; @@ -19,6 +17,8 @@ import { PaginatedList } from './paginated-list.model'; import { ITEM_TYPE } from '../shared/item-relationships/item-type.resource-type'; import { LICENSE } from '../shared/license.resource-type'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /* tslint:disable:max-classes-per-file */ class DataServiceImpl extends DataService { diff --git a/src/app/core/data/item-data.service.spec.ts b/src/app/core/data/item-data.service.spec.ts index 30a132aeaeb..846d0e72eb0 100644 --- a/src/app/core/data/item-data.service.spec.ts +++ b/src/app/core/data/item-data.service.spec.ts @@ -8,13 +8,14 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { BrowseService } from '../browse/browse.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { RestResponse } from '../cache/response.models'; -import { CoreState } from '../core.reducers'; import { ExternalSourceEntry } from '../shared/external-source-entry.model'; import { ItemDataService } from './item-data.service'; -import { DeleteRequest, FindListOptions, PostRequest } from './request.models'; -import { RequestEntry } from './request.reducer'; +import { DeleteRequest, PostRequest } from './request.models'; import { RequestService } from './request.service'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; +import { FindListOptions } from './find-list-options.model'; describe('ItemDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index 1c152701a10..db7c982303d 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -9,7 +9,6 @@ import { BrowseService } from '../browse/browse.service'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { Collection } from '../shared/collection.model'; import { ExternalSourceEntry } from '../shared/external-source-entry.model'; @@ -22,7 +21,7 @@ import { DataService } from './data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { DeleteRequest, FindListOptions, GetRequest, PostRequest, PutRequest, RestRequest } from './request.models'; +import { DeleteRequest, GetRequest, PostRequest, PutRequest} from './request.models'; import { RequestService } from './request.service'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; import { Bundle } from '../shared/bundle.model'; @@ -34,6 +33,9 @@ import { GenericConstructor } from '../shared/generic-constructor'; import { ResponseParsingService } from './parsing.service'; import { StatusCodeOnlyResponseParsingService } from './status-code-only-response-parsing.service'; import { sendRequest } from '../shared/request.operators'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; @Injectable() @dataService(ITEM) diff --git a/src/app/core/data/item-template-data.service.spec.ts b/src/app/core/data/item-template-data.service.spec.ts index 14585275065..4b8aa362baa 100644 --- a/src/app/core/data/item-template-data.service.spec.ts +++ b/src/app/core/data/item-template-data.service.spec.ts @@ -1,12 +1,9 @@ import { ItemTemplateDataService } from './item-template-data.service'; -import { RestRequest } from './request.models'; -import { RequestEntry } from './request.reducer'; import { RestResponse } from '../cache/response.models'; import { RequestService } from './request.service'; import { Observable, of as observableOf } from 'rxjs'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { BrowseService } from '../browse/browse.service'; import { cold } from 'jasmine-marbles'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -15,6 +12,9 @@ import { HttpClient } from '@angular/common/http'; import { CollectionDataService } from './collection-data.service'; import { RestRequestMethod } from './rest-request-method'; import { Item } from '../shared/item.model'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; describe('ItemTemplateDataService', () => { let service: ItemTemplateDataService; diff --git a/src/app/core/data/item-template-data.service.ts b/src/app/core/data/item-template-data.service.ts index 19e6941385c..c391ce1a72d 100644 --- a/src/app/core/data/item-template-data.service.ts +++ b/src/app/core/data/item-template-data.service.ts @@ -9,7 +9,6 @@ import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -23,6 +22,7 @@ import { NoContent } from '../shared/NoContent.model'; import { hasValue } from '../../shared/empty.util'; import { Operation } from 'fast-json-patch'; import { getFirstCompletedRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; /* tslint:disable:max-classes-per-file */ /** diff --git a/src/app/core/data/metadata-field-data.service.spec.ts b/src/app/core/data/metadata-field-data.service.spec.ts index bb621f74b3a..54a174e365a 100644 --- a/src/app/core/data/metadata-field-data.service.spec.ts +++ b/src/app/core/data/metadata-field-data.service.spec.ts @@ -4,12 +4,12 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { of as observableOf } from 'rxjs'; import { RestResponse } from '../cache/response.models'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; -import { FindListOptions } from './request.models'; import { MetadataFieldDataService } from './metadata-field-data.service'; import { MetadataSchema } from '../metadata/metadata-schema.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { RequestParam } from '../cache/models/request-param.model'; +import { FindListOptions } from './find-list-options.model'; describe('MetadataFieldDataService', () => { let metadataFieldService: MetadataFieldDataService; diff --git a/src/app/core/data/metadata-field-data.service.ts b/src/app/core/data/metadata-field-data.service.ts index 3b11859361e..5a78213c847 100644 --- a/src/app/core/data/metadata-field-data.service.ts +++ b/src/app/core/data/metadata-field-data.service.ts @@ -7,7 +7,6 @@ import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; @@ -16,11 +15,12 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { METADATA_FIELD } from '../metadata/metadata-field.resource-type'; import { MetadataField } from '../metadata/metadata-field.model'; import { MetadataSchema } from '../metadata/metadata-schema.model'; -import { FindListOptions } from './request.models'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import { RequestParam } from '../cache/models/request-param.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint diff --git a/src/app/core/data/metadata-schema-data.service.ts b/src/app/core/data/metadata-schema-data.service.ts index ff1796313e4..f277f6cab6c 100644 --- a/src/app/core/data/metadata-schema-data.service.ts +++ b/src/app/core/data/metadata-schema-data.service.ts @@ -5,7 +5,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { MetadataSchema } from '../metadata/metadata-schema.model'; import { METADATA_SCHEMA } from '../metadata/metadata-schema.resource-type'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -16,6 +15,7 @@ import { Observable } from 'rxjs'; import { hasValue } from '../../shared/empty.util'; import { tap } from 'rxjs/operators'; import { RemoteData } from './remote-data'; +import { CoreState } from '../core-state.model'; /** * A service responsible for fetching/sending data from/to the REST API on the metadataschemas endpoint diff --git a/src/app/core/data/mydspace-response-parsing.service.ts b/src/app/core/data/mydspace-response-parsing.service.ts index f71eaeb811b..edb9e3c80fd 100644 --- a/src/app/core/data/mydspace-response-parsing.service.ts +++ b/src/app/core/data/mydspace-response-parsing.service.ts @@ -1,12 +1,12 @@ import { Injectable } from '@angular/core'; import { ParsedResponse } from '../cache/response.models'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; -import { RestRequest } from './request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { hasValue } from '../../shared/empty.util'; import { SearchObjects } from '../../shared/search/search-objects.model'; import { MetadataMap, MetadataValue } from '../shared/metadata.models'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; +import { RestRequest } from './rest-request.model'; @Injectable() export class MyDSpaceResponseParsingService extends DspaceRestResponseParsingService { diff --git a/src/app/core/data/object-updates/object-updates.service.spec.ts b/src/app/core/data/object-updates/object-updates.service.spec.ts index b0c63851e3b..9cf856f03a0 100644 --- a/src/app/core/data/object-updates/object-updates.service.spec.ts +++ b/src/app/core/data/object-updates/object-updates.service.spec.ts @@ -1,5 +1,4 @@ import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectUpdatesService } from './object-updates.service'; import { DiscardObjectUpdatesAction, @@ -16,6 +15,7 @@ import { OBJECT_UPDATES_TRASH_PATH } from './object-updates.reducer'; import { Relationship } from '../../shared/item-relationships/relationship.model'; import { Injector } from '@angular/core'; import { FieldChangeType } from './field-change-type.model'; +import { CoreState } from '../../core-state.model'; describe('ObjectUpdatesService', () => { let service: ObjectUpdatesService; diff --git a/src/app/core/data/object-updates/object-updates.service.ts b/src/app/core/data/object-updates/object-updates.service.ts index 0bdae06ce26..2fb6d47d31c 100644 --- a/src/app/core/data/object-updates/object-updates.service.ts +++ b/src/app/core/data/object-updates/object-updates.service.ts @@ -1,6 +1,5 @@ import { Injectable, Injector } from '@angular/core'; import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { coreSelector } from '../../core.selectors'; import { FieldState, @@ -35,6 +34,7 @@ import { GenericConstructor } from '../../shared/generic-constructor'; import { Identifiable } from './identifiable.model'; import { FieldUpdates } from './field-updates.model'; import { FieldChangeType } from './field-change-type.model'; +import { CoreState } from '../../core-state.model'; function objectUpdatesStateSelector(): MemoizedSelector { return createSelector(coreSelector, (state: CoreState) => state['cache/object-updates']); diff --git a/src/app/core/data/parsing.service.ts b/src/app/core/data/parsing.service.ts index bebbd63fd79..fbebe75b2b5 100644 --- a/src/app/core/data/parsing.service.ts +++ b/src/app/core/data/parsing.service.ts @@ -1,6 +1,6 @@ import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; -import { RestRequest } from './request.models'; import { ParsedResponse } from '../cache/response.models'; +import { RestRequest } from './rest-request.model'; export interface ResponseParsingService { parse(request: RestRequest, data: RawRestResponse): ParsedResponse; diff --git a/src/app/core/data/processes/process-data.service.ts b/src/app/core/data/processes/process-data.service.ts index cadcdb3bfe4..81b4cbd5035 100644 --- a/src/app/core/data/processes/process-data.service.ts +++ b/src/app/core/data/processes/process-data.service.ts @@ -3,7 +3,6 @@ import { DataService } from '../data.service'; import { RequestService } from '../request.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -18,6 +17,7 @@ import { PaginatedList } from '../paginated-list.model'; import { Bitstream } from '../../shared/bitstream.model'; import { RemoteData } from '../remote-data'; import { BitstreamDataService } from '../bitstream-data.service'; +import { CoreState } from '../../core-state.model'; @Injectable() @dataService(PROCESS) diff --git a/src/app/core/data/processes/script-data.service.ts b/src/app/core/data/processes/script-data.service.ts index 69b42701734..bf51fadea1b 100644 --- a/src/app/core/data/processes/script-data.service.ts +++ b/src/app/core/data/processes/script-data.service.ts @@ -2,7 +2,6 @@ import { Injectable } from '@angular/core'; import { DataService } from '../data.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -13,12 +12,14 @@ import { ProcessParameter } from '../../../process-page/processes/process-parame import { map, take } from 'rxjs/operators'; import { URLCombiner } from '../../url-combiner/url-combiner'; import { RemoteData } from '../remote-data'; -import { MultipartPostRequest, RestRequest } from '../request.models'; +import { MultipartPostRequest} from '../request.models'; import { RequestService } from '../request.service'; import { Observable } from 'rxjs'; import { dataService } from '../../cache/builders/build-decorators'; import { SCRIPT } from '../../../process-page/scripts/script.resource-type'; import { Process } from '../../../process-page/processes/process.model'; +import { RestRequest } from '../rest-request.model'; +import { CoreState } from '../../core-state.model'; export const METADATA_IMPORT_SCRIPT_NAME = 'metadata-import'; export const METADATA_EXPORT_SCRIPT_NAME = 'metadata-export'; diff --git a/src/app/core/data/registration-response-parsing.service.ts b/src/app/core/data/registration-response-parsing.service.ts index e11838e0ac7..067deea557a 100644 --- a/src/app/core/data/registration-response-parsing.service.ts +++ b/src/app/core/data/registration-response-parsing.service.ts @@ -4,8 +4,8 @@ import { } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ResponseParsingService } from './parsing.service'; -import { RestRequest } from './request.models'; import { Registration } from '../shared/registration.model'; +import { RestRequest } from './rest-request.model'; @Injectable({ providedIn: 'root', diff --git a/src/app/core/data/relationship-type.service.ts b/src/app/core/data/relationship-type.service.ts index 4dac0440903..07608b8cf9b 100644 --- a/src/app/core/data/relationship-type.service.ts +++ b/src/app/core/data/relationship-type.service.ts @@ -10,7 +10,6 @@ import { followLink } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ItemType } from '../shared/item-relationships/item-type.model'; import { RelationshipType } from '../shared/item-relationships/relationship-type.model'; @@ -22,6 +21,7 @@ import { ItemDataService } from './item-data.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; +import { CoreState } from '../core-state.model'; /** * Check if one side of a RelationshipType is the ItemType with the given label diff --git a/src/app/core/data/relationship.service.spec.ts b/src/app/core/data/relationship.service.spec.ts index 0f7dd319c37..d27c8dd6b25 100644 --- a/src/app/core/data/relationship.service.spec.ts +++ b/src/app/core/data/relationship.service.spec.ts @@ -6,15 +6,16 @@ import { Relationship } from '../shared/item-relationships/relationship.model'; import { Item } from '../shared/item.model'; import { PageInfo } from '../shared/page-info.model'; import { buildPaginatedList } from './paginated-list.model'; -import { DeleteRequest, FindListOptions } from './request.models'; +import { DeleteRequest} from './request.models'; import { RelationshipService } from './relationship.service'; import { RequestService } from './request.service'; -import { RequestEntry } from './request.reducer'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { getMockRemoteDataBuildServiceHrefMap } from '../../shared/mocks/remote-data-build.service.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { createPaginatedList } from '../../shared/testing/utils.test'; +import { RequestEntry } from './request-entry.model'; +import { FindListOptions } from './find-list-options.model'; describe('RelationshipService', () => { let service: RelationshipService; diff --git a/src/app/core/data/relationship.service.ts b/src/app/core/data/relationship.service.ts index 7bd36d0cece..e9e99314080 100644 --- a/src/app/core/data/relationship.service.ts +++ b/src/app/core/data/relationship.service.ts @@ -21,7 +21,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RequestParam } from '../cache/models/request-param.model'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RelationshipType } from '../shared/item-relationships/relationship-type.model'; @@ -39,11 +38,14 @@ import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { ItemDataService } from './item-data.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { DeleteRequest, FindListOptions, PostRequest, RestRequest } from './request.models'; +import { DeleteRequest, PostRequest} from './request.models'; import { RequestService } from './request.service'; import { NoContent } from '../shared/NoContent.model'; import { RequestEntryState } from './request-entry-state.model'; import { sendRequest } from '../shared/request.operators'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; const relationshipListsStateSelector = (state: AppState) => state.relationshipLists; diff --git a/src/app/core/data/request-entry.model.ts b/src/app/core/data/request-entry.model.ts new file mode 100644 index 00000000000..1555c99ed43 --- /dev/null +++ b/src/app/core/data/request-entry.model.ts @@ -0,0 +1,13 @@ +import { RestRequestWithResponseParser } from './rest-request-with-response-parser.model'; +import { RequestEntryState } from './request-entry-state.model'; +import { ResponseState } from './response-state.model'; + +/** + * An entry for a request in the NgRx store + */ +export class RequestEntry { + request: RestRequestWithResponseParser; + state: RequestEntryState; + response: ResponseState; + lastUpdated: number; +} diff --git a/src/app/core/data/request-state.model.ts b/src/app/core/data/request-state.model.ts new file mode 100644 index 00000000000..5872dab2940 --- /dev/null +++ b/src/app/core/data/request-state.model.ts @@ -0,0 +1,8 @@ +import { RequestEntry } from './request-entry.model'; + +/** + * The request sub-state of the NgRx store + */ +export interface RequestState { + [uuid: string]: RequestEntry; +} diff --git a/src/app/core/data/request.actions.ts b/src/app/core/data/request.actions.ts index 8b3511d3e40..cc5415afbef 100644 --- a/src/app/core/data/request.actions.ts +++ b/src/app/core/data/request.actions.ts @@ -1,8 +1,8 @@ import { Action } from '@ngrx/store'; import { type } from '../../shared/ngrx/type'; -import { RestRequest } from './request.models'; import { HALLink } from '../shared/hal-link.model'; import { UnCacheableObject } from '../shared/uncacheable-object.model'; +import { RestRequest } from './rest-request.model'; /** * The list of RequestAction type definitions diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index e5a4fc7df2a..b297ca6692a 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -16,11 +16,12 @@ import { RequestSuccessAction, ResetResponseTimestampsAction } from './request.actions'; -import { RestRequest } from './request.models'; -import { RequestEntry } from './request.reducer'; import { RequestService } from './request.service'; import { ParsedResponse } from '../cache/response.models'; import { RequestError } from './request-error.model'; +import { RestRequest } from './rest-request.model'; +import { RestRequestWithResponseParser } from './rest-request-with-response-parser.model'; +import { RequestEntry } from './request-entry.model'; @Injectable() export class RequestEffects { @@ -34,7 +35,7 @@ export class RequestEffects { }), filter((entry: RequestEntry) => hasValue(entry)), map((entry: RequestEntry) => entry.request), - mergeMap((request: RestRequest) => { + mergeMap((request: RestRequestWithResponseParser) => { let body = request.body; if (isNotEmpty(request.body) && !request.isMultipart) { const serializer = new DSpaceSerializer(getClassForType(request.body.type)); diff --git a/src/app/core/data/request.models.ts b/src/app/core/data/request.models.ts index 990c37d192b..45b9b4143dd 100644 --- a/src/app/core/data/request.models.ts +++ b/src/app/core/data/request.models.ts @@ -1,15 +1,16 @@ -import { SortOptions } from '../cache/models/sort-options.model'; import { GenericConstructor } from '../shared/generic-constructor'; import { ResponseParsingService } from './parsing.service'; import { EndpointMapResponseParsingService } from './endpoint-map-response-parsing.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; -import { SubmissionResponseParsingService } from '../submission/submission-response-parsing.service'; +import { + SubmissionResponseParsingService +} from '../submission/submission-response-parsing.service'; import { RestRequestMethod } from './rest-request-method'; -import { RequestParam } from '../cache/models/request-param.model'; import { TaskResponseParsingService } from '../tasks/task-response-parsing.service'; import { ContentSourceResponseParsingService } from './content-source-response-parsing.service'; +import { RestRequestWithResponseParser } from './rest-request-with-response-parser.model'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; -import { environment } from '../../../environments/environment'; +import { FindListOptions } from './find-list-options.model'; /* tslint:disable:max-classes-per-file */ @@ -19,25 +20,13 @@ export enum IdentifierType { HANDLE = 'handle' } -export abstract class RestRequest { - public responseMsToLive = environment.cache.msToLive.default; - public isMultipart = false; - - constructor( - public uuid: string, - public href: string, - public method: RestRequestMethod = RestRequestMethod.GET, - public body?: any, - public options?: HttpOptions, - ) { - } - +class DSpaceRestRequest extends RestRequestWithResponseParser { getResponseParser(): GenericConstructor { return DspaceRestResponseParsingService; } } -export class GetRequest extends RestRequest { +export class GetRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -48,7 +37,7 @@ export class GetRequest extends RestRequest { } } -export class PostRequest extends RestRequest { +export class PostRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -62,7 +51,7 @@ export class PostRequest extends RestRequest { /** * Request representing a multipart post request */ -export class MultipartPostRequest extends RestRequest { +export class MultipartPostRequest extends DSpaceRestRequest { public isMultipart = true; constructor( public uuid: string, @@ -74,7 +63,7 @@ export class MultipartPostRequest extends RestRequest { } } -export class PutRequest extends RestRequest { +export class PutRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -85,7 +74,7 @@ export class PutRequest extends RestRequest { } } -export class DeleteRequest extends RestRequest { +export class DeleteRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -96,7 +85,7 @@ export class DeleteRequest extends RestRequest { } } -export class OptionsRequest extends RestRequest { +export class OptionsRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -107,7 +96,7 @@ export class OptionsRequest extends RestRequest { } } -export class HeadRequest extends RestRequest { +export class HeadRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -118,7 +107,7 @@ export class HeadRequest extends RestRequest { } } -export class PatchRequest extends RestRequest { +export class PatchRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -129,15 +118,6 @@ export class PatchRequest extends RestRequest { } } -export class FindListOptions { - scopeID?: string; - elementsPerPage?: number; - currentPage?: number; - sort?: SortOptions; - searchParams?: RequestParam[]; - startsWith?: string; -} - export class FindListRequest extends GetRequest { constructor( uuid: string, diff --git a/src/app/core/data/request.reducer.spec.ts b/src/app/core/data/request.reducer.spec.ts index 2073b4faa1a..f6f557ad8f7 100644 --- a/src/app/core/data/request.reducer.spec.ts +++ b/src/app/core/data/request.reducer.spec.ts @@ -9,8 +9,9 @@ import { ResetResponseTimestampsAction } from './request.actions'; import { GetRequest } from './request.models'; -import { requestReducer, RequestState } from './request.reducer'; +import { requestReducer} from './request.reducer'; import { RequestEntryState } from './request-entry-state.model'; +import { RequestState } from './request-state.model'; class NullAction extends RequestSuccessAction { type = null; diff --git a/src/app/core/data/request.reducer.ts b/src/app/core/data/request.reducer.ts index 8b6f50dda8e..5019fc2231c 100644 --- a/src/app/core/data/request.reducer.ts +++ b/src/app/core/data/request.reducer.ts @@ -9,31 +9,9 @@ import { RequestSuccessAction, ResetResponseTimestampsAction } from './request.actions'; -import { RestRequest } from './request.models'; -import { HALLink } from '../shared/hal-link.model'; -import { UnCacheableObject } from '../shared/uncacheable-object.model'; import { isNull } from '../../shared/empty.util'; import { hasSucceeded, isStale, RequestEntryState } from './request-entry-state.model'; - -export class ResponseState { - timeCompleted: number; - statusCode: number; - errorMessage?: string; - payloadLink?: HALLink; - unCacheableObject?: UnCacheableObject; -} - -// tslint:disable-next-line:max-classes-per-file -export class RequestEntry { - request: RestRequest; - state: RequestEntryState; - response: ResponseState; - lastUpdated: number; -} - -export interface RequestState { - [uuid: string]: RequestEntry; -} +import { RequestState } from './request-state.model'; // Object.create(null) ensures the object has no default js properties (e.g. `__proto__`) const initialState = Object.create(null); diff --git a/src/app/core/data/request.service.spec.ts b/src/app/core/data/request.service.spec.ts index 50d753ab456..a49761ae5da 100644 --- a/src/app/core/data/request.service.spec.ts +++ b/src/app/core/data/request.service.spec.ts @@ -6,7 +6,7 @@ import { TestScheduler } from 'rxjs/testing'; import { getMockObjectCacheService } from '../../shared/mocks/object-cache.service.mock'; import { defaultUUID, getMockUUIDService } from '../../shared/mocks/uuid.service.mock'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { coreReducers, CoreState } from '../core.reducers'; +import { coreReducers} from '../core.reducers'; import { UUIDService } from '../shared/uuid.service'; import { RequestConfigureAction, RequestExecuteAction } from './request.actions'; import { @@ -16,15 +16,16 @@ import { OptionsRequest, PatchRequest, PostRequest, - PutRequest, - RestRequest + PutRequest } from './request.models'; -import { RequestEntry} from './request.reducer'; import { RequestService } from './request.service'; import { TestBed, waitForAsync } from '@angular/core/testing'; import { storeModuleConfig } from '../../app.reducer'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { RequestEntryState } from './request-entry-state.model'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; describe('RequestService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index b381fdd1fd1..3903bcfc99c 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -8,7 +8,6 @@ import { cloneDeep } from 'lodash'; import { hasValue, isEmpty, isNotEmpty, hasNoValue } from '../../shared/empty.util'; import { ObjectCacheEntry } from '../cache/object-cache.reducer'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { IndexState, MetaIndexState } from '../index/index.reducer'; import { requestIndexSelector, getUrlWithoutEmbedParams } from '../index/index.selectors'; import { UUIDService } from '../shared/uuid.service'; @@ -17,12 +16,15 @@ import { RequestExecuteAction, RequestStaleAction } from './request.actions'; -import { GetRequest, RestRequest } from './request.models'; -import { RequestEntry, RequestState} from './request.reducer'; +import { GetRequest} from './request.models'; import { CommitSSBAction } from '../cache/server-sync-buffer.actions'; import { RestRequestMethod } from './rest-request-method'; import { coreSelector } from '../core.selectors'; import { isLoading, isStale } from './request-entry-state.model'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { RequestState } from './request-state.model'; +import { RequestEntry } from './request-entry.model'; /** * The base selector function to select the request state in the store @@ -145,7 +147,7 @@ export class RequestService { /** * Check if a GET request is currently pending */ - isPending(request: GetRequest): boolean { + isPending(request: RestRequest): boolean { // If the request is not a GET request, it will never be considered pending, because you may // want to execute the exact same e.g. POST multiple times if (request.method !== RestRequestMethod.GET) { @@ -242,7 +244,7 @@ export class RequestService { if (this.shouldDispatchRequest(request, useCachedVersionIfAvailable)) { this.dispatchRequest(request); if (request.method === RestRequestMethod.GET) { - this.trackRequestsOnTheirWayToTheStore(request); + this.trackRequestsOnTheirWayToTheStore(request as GetRequest); } return true; } else { @@ -315,7 +317,7 @@ export class RequestService { * @param {boolean} useCachedVersionIfAvailable Whether or not to allow the use of a cached version * @returns {boolean} True if the request is cached or still pending */ - public shouldDispatchRequest(request: GetRequest, useCachedVersionIfAvailable: boolean): boolean { + public shouldDispatchRequest(request: RestRequest, useCachedVersionIfAvailable: boolean): boolean { // if it's not a GET request if (request.method !== RestRequestMethod.GET) { return true; diff --git a/src/app/core/data/response-state.model.ts b/src/app/core/data/response-state.model.ts new file mode 100644 index 00000000000..97203fcdd55 --- /dev/null +++ b/src/app/core/data/response-state.model.ts @@ -0,0 +1,13 @@ +import { HALLink } from '../shared/hal-link.model'; +import { UnCacheableObject } from '../shared/uncacheable-object.model'; + +/** + * The response substate in the NgRx store + */ +export class ResponseState { + timeCompleted: number; + statusCode: number; + errorMessage?: string; + payloadLink?: HALLink; + unCacheableObject?: UnCacheableObject; +} diff --git a/src/app/core/data/rest-request-with-response-parser.model.ts b/src/app/core/data/rest-request-with-response-parser.model.ts new file mode 100644 index 00000000000..1c9677ebb17 --- /dev/null +++ b/src/app/core/data/rest-request-with-response-parser.model.ts @@ -0,0 +1,14 @@ +import { RestRequest } from './rest-request.model'; +import { GenericConstructor } from '../shared/generic-constructor'; +import { ResponseParsingService } from './parsing.service'; + +/** + * A RestRequest with a method to retrieve the ResponseParsingService needed for its response + */ +export abstract class RestRequestWithResponseParser extends RestRequest { + + /** + * Get the ResponseParsingService needed to parse the response to this request + */ + abstract getResponseParser(): GenericConstructor; +} diff --git a/src/app/core/data/rest-request.model.ts b/src/app/core/data/rest-request.model.ts new file mode 100644 index 00000000000..05b583639b0 --- /dev/null +++ b/src/app/core/data/rest-request.model.ts @@ -0,0 +1,20 @@ +import { environment } from '../../../environments/environment'; +import { RestRequestMethod } from './rest-request-method'; +import { HttpOptions } from '../dspace-rest/dspace-rest.service'; + +/** + * A request to the DSpace REST API + */ +export abstract class RestRequest { + public responseMsToLive = environment.cache.msToLive.default; + public isMultipart = false; + + constructor( + public uuid: string, + public href: string, + public method: RestRequestMethod = RestRequestMethod.GET, + public body?: any, + public options?: HttpOptions, + ) { + } +} diff --git a/src/app/core/data/root-data.service.ts b/src/app/core/data/root-data.service.ts index 8b4e8366716..b5245c8d48c 100644 --- a/src/app/core/data/root-data.service.ts +++ b/src/app/core/data/root-data.service.ts @@ -6,7 +6,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -15,8 +14,9 @@ import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { Observable } from 'rxjs'; import { RemoteData } from './remote-data'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; -import { FindListOptions } from './request.models'; import { PaginatedList } from './paginated-list.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/data/search-response-parsing.service.ts b/src/app/core/data/search-response-parsing.service.ts index be2fbe90fc9..e5100aba66e 100644 --- a/src/app/core/data/search-response-parsing.service.ts +++ b/src/app/core/data/search-response-parsing.service.ts @@ -5,8 +5,8 @@ import { ParsedResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { MetadataMap, MetadataValue } from '../shared/metadata.models'; -import { RestRequest } from './request.models'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; +import { RestRequest } from './rest-request.model'; @Injectable() export class SearchResponseParsingService extends DspaceRestResponseParsingService { diff --git a/src/app/core/data/site-data.service.spec.ts b/src/app/core/data/site-data.service.spec.ts index c6b69914884..1e8b135db85 100644 --- a/src/app/core/data/site-data.service.spec.ts +++ b/src/app/core/data/site-data.service.spec.ts @@ -5,14 +5,14 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv import { ObjectCacheService } from '../cache/object-cache.service'; import { Site } from '../shared/site.model'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { FindListOptions } from './request.models'; import { TestScheduler } from 'rxjs/testing'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { createPaginatedList } from '../../shared/testing/utils.test'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; describe('SiteDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/site-data.service.ts b/src/app/core/data/site-data.service.ts index a91b599e58f..b2ba9d6dfb6 100644 --- a/src/app/core/data/site-data.service.ts +++ b/src/app/core/data/site-data.service.ts @@ -7,7 +7,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { getFirstSucceededRemoteData } from '../shared/operators'; import { Site } from '../shared/site.model'; @@ -17,6 +16,7 @@ import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; +import { CoreState } from '../core-state.model'; /** * Service responsible for handling requests related to the Site object diff --git a/src/app/core/data/status-code-only-response-parsing.service.ts b/src/app/core/data/status-code-only-response-parsing.service.ts index 4f0030371f6..ad6a01429d4 100644 --- a/src/app/core/data/status-code-only-response-parsing.service.ts +++ b/src/app/core/data/status-code-only-response-parsing.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { RestResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ResponseParsingService } from './parsing.service'; -import { RestRequest } from './request.models'; +import { RestRequest } from './rest-request.model'; /** * A responseparser that will only look at the status code and status diff --git a/src/app/core/data/version-data.service.ts b/src/app/core/data/version-data.service.ts index 11a3838eb0a..14dd94c7745 100644 --- a/src/app/core/data/version-data.service.ts +++ b/src/app/core/data/version-data.service.ts @@ -4,16 +4,16 @@ import { Version } from '../shared/version.model'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { dataService } from '../cache/builders/build-decorators'; import { VERSION } from '../shared/version.resource-type'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * Service responsible for handling requests related to the Version object diff --git a/src/app/core/data/version-history-data.service.ts b/src/app/core/data/version-history-data.service.ts index 8f148f168df..42977aa67e5 100644 --- a/src/app/core/data/version-history-data.service.ts +++ b/src/app/core/data/version-history-data.service.ts @@ -4,13 +4,11 @@ import { Injectable } from '@angular/core'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; import { RemoteData } from './remote-data'; @@ -21,6 +19,8 @@ import { dataService } from '../cache/builders/build-decorators'; import { VERSION_HISTORY } from '../shared/version-history.resource-type'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { VersionDataService } from './version-data.service'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * Service responsible for handling requests related to the VersionHistory object diff --git a/src/app/core/data/workflow-action-data.service.ts b/src/app/core/data/workflow-action-data.service.ts index c5a2980d9f6..ab8f187b2ff 100644 --- a/src/app/core/data/workflow-action-data.service.ts +++ b/src/app/core/data/workflow-action-data.service.ts @@ -3,17 +3,17 @@ import { WorkflowAction } from '../tasks/models/workflow-action-object.model'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { Injectable } from '@angular/core'; import { dataService } from '../cache/builders/build-decorators'; import { WORKFLOW_ACTION } from '../tasks/models/workflow-action-object.resource-type'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service responsible for fetching/sending data from/to the REST API on the workflowactions endpoint diff --git a/src/app/core/eperson/eperson-data.service.spec.ts b/src/app/core/eperson/eperson-data.service.spec.ts index cd7b664379e..2cf849b8310 100644 --- a/src/app/core/eperson/eperson-data.service.spec.ts +++ b/src/app/core/eperson/eperson-data.service.spec.ts @@ -12,9 +12,8 @@ import { EPeopleRegistryEditEPersonAction } from '../../access-control/epeople-registry/epeople-registry.actions'; import { RequestParam } from '../cache/models/request-param.model'; -import { CoreState } from '../core.reducers'; import { ChangeAnalyzer } from '../data/change-analyzer'; -import { DeleteRequest, FindListOptions, PatchRequest, PostRequest } from '../data/request.models'; +import { DeleteRequest, PatchRequest, PostRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { Item } from '../shared/item.model'; @@ -27,6 +26,8 @@ import { getMockRemoteDataBuildServiceHrefMap } from '../../shared/mocks/remote- import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { createPaginatedList, createRequestEntry$ } from '../../shared/testing/utils.test'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('EPersonDataService', () => { let service: EPersonDataService; diff --git a/src/app/core/eperson/eperson-data.service.ts b/src/app/core/eperson/eperson-data.service.ts index bceb38f163f..d801ab6fa47 100644 --- a/src/app/core/eperson/eperson-data.service.ts +++ b/src/app/core/eperson/eperson-data.service.ts @@ -21,7 +21,7 @@ import { DataService } from '../data/data.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { PaginatedList, buildPaginatedList } from '../data/paginated-list.model'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions, PatchRequest, PostRequest, } from '../data/request.models'; +import { PatchRequest, PostRequest, } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { getRemoteDataPayload, getFirstSucceededRemoteData, } from '../shared/operators'; @@ -29,6 +29,7 @@ import { EPerson } from './models/eperson.model'; import { EPERSON } from './models/eperson.resource-type'; import { NoContent } from '../shared/NoContent.model'; import { PageInfo } from '../shared/page-info.model'; +import { FindListOptions } from '../data/find-list-options.model'; const ePeopleRegistryStateSelector = (state: AppState) => state.epeopleRegistry; const editEPersonSelector = createSelector(ePeopleRegistryStateSelector, (ePeopleRegistryState: EPeopleRegistryState) => ePeopleRegistryState.editEPerson); diff --git a/src/app/core/eperson/group-data.service.spec.ts b/src/app/core/eperson/group-data.service.spec.ts index 378c3c96671..c30b74e966f 100644 --- a/src/app/core/eperson/group-data.service.spec.ts +++ b/src/app/core/eperson/group-data.service.spec.ts @@ -11,9 +11,8 @@ import { } from '../../access-control/group-registry/group-registry.actions'; import { GroupMock, GroupMock2 } from '../../shared/testing/group-mock'; import { RequestParam } from '../cache/models/request-param.model'; -import { CoreState } from '../core.reducers'; import { ChangeAnalyzer } from '../data/change-analyzer'; -import { DeleteRequest, FindListOptions, PostRequest } from '../data/request.models'; +import { DeleteRequest, PostRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { Item } from '../shared/item.model'; @@ -25,6 +24,8 @@ import { TranslateLoaderMock } from '../../shared/testing/translate-loader.mock' import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { EPersonMock, EPersonMock2 } from '../../shared/testing/eperson.mock'; import { createPaginatedList, createRequestEntry$ } from '../../shared/testing/utils.test'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('GroupDataService', () => { let service: GroupDataService; diff --git a/src/app/core/eperson/group-data.service.ts b/src/app/core/eperson/group-data.service.ts index 5b8f474d1ad..bc09c5b9737 100644 --- a/src/app/core/eperson/group-data.service.ts +++ b/src/app/core/eperson/group-data.service.ts @@ -19,7 +19,7 @@ import { DataService } from '../data/data.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { PaginatedList } from '../data/paginated-list.model'; import { RemoteData } from '../data/remote-data'; -import { CreateRequest, DeleteRequest, FindListOptions, PostRequest } from '../data/request.models'; +import { CreateRequest, DeleteRequest, PostRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; @@ -33,6 +33,7 @@ import { DSONameService } from '../breadcrumbs/dso-name.service'; import { Community } from '../shared/community.model'; import { Collection } from '../shared/collection.model'; import { NoContent } from '../shared/NoContent.model'; +import { FindListOptions } from '../data/find-list-options.model'; const groupRegistryStateSelector = (state: AppState) => state.groupRegistry; const editGroupSelector = createSelector(groupRegistryStateSelector, (groupRegistryState: GroupRegistryState) => groupRegistryState.editGroup); diff --git a/src/app/core/history/selectors.ts b/src/app/core/history/selectors.ts index 5c77cd65f0f..925b56c795d 100644 --- a/src/app/core/history/selectors.ts +++ b/src/app/core/history/selectors.ts @@ -1,6 +1,6 @@ -import { CoreState } from '../core.reducers'; import { createSelector } from '@ngrx/store'; import { coreSelector } from '../core.selectors'; +import { CoreState } from '../core-state.model'; export const historySelector = createSelector( coreSelector, diff --git a/src/app/core/index/index.effects.ts b/src/app/core/index/index.effects.ts index 58acc08acc6..60e9af6129e 100644 --- a/src/app/core/index/index.effects.ts +++ b/src/app/core/index/index.effects.ts @@ -17,9 +17,9 @@ import { hasValue } from '../../shared/empty.util'; import { RestRequestMethod } from '../data/rest-request-method'; import { getUrlWithoutEmbedParams, uuidFromHrefSelector } from './index.selectors'; import { Store, select } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { NoOpAction } from '../../shared/ngrx/no-op.action'; import { IndexName } from './index-name.model'; +import { CoreState } from '../core-state.model'; @Injectable() export class UUIDIndexEffects { diff --git a/src/app/core/index/index.selectors.ts b/src/app/core/index/index.selectors.ts index 435398d0a42..697616c3210 100644 --- a/src/app/core/index/index.selectors.ts +++ b/src/app/core/index/index.selectors.ts @@ -1,11 +1,11 @@ import { createSelector, MemoizedSelector } from '@ngrx/store'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; -import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { URLCombiner } from '../url-combiner/url-combiner'; import { IndexState, MetaIndexState } from './index.reducer'; import * as parse from 'url-parse'; import { IndexName } from './index-name.model'; +import { CoreState } from '../core-state.model'; /** * Return the given url without `embed` params. diff --git a/src/app/core/json-patch/builder/json-patch-operations-builder.ts b/src/app/core/json-patch/builder/json-patch-operations-builder.ts index d3896c4a6c2..f5a584fd3d0 100644 --- a/src/app/core/json-patch/builder/json-patch-operations-builder.ts +++ b/src/app/core/json-patch/builder/json-patch-operations-builder.ts @@ -1,5 +1,4 @@ import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { NewPatchAddOperationAction, NewPatchMoveOperationAction, @@ -13,6 +12,7 @@ import { dateToISOFormat, dateToString, isNgbDateStruct } from '../../../shared/ import { VocabularyEntry } from '../../submission/vocabularies/models/vocabulary-entry.model'; import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model'; import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model'; +import { CoreState } from '../../core-state.model'; /** * Provides methods to dispatch JsonPatch Operations Actions diff --git a/src/app/core/json-patch/json-patch-operations.service.spec.ts b/src/app/core/json-patch/json-patch-operations.service.spec.ts index d1b29487770..10fc2f2ed84 100644 --- a/src/app/core/json-patch/json-patch-operations.service.spec.ts +++ b/src/app/core/json-patch/json-patch-operations.service.spec.ts @@ -12,7 +12,6 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; import { JsonPatchOperationsService } from './json-patch-operations.service'; import { SubmitDataResponseDefinitionObject } from '../shared/submit-data-response-definition.model'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { JsonPatchOperationsEntry, JsonPatchOperationsResourceEntry } from './json-patch-operations.reducer'; import { @@ -21,9 +20,10 @@ import { RollbacktPatchOperationsAction, StartTransactionPatchOperationsAction } from './json-patch-operations.actions'; -import { RequestEntry } from '../data/request.reducer'; import { createFailedRemoteDataObject, createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { deepClone } from 'fast-json-patch'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from '../data/request-entry.model'; class TestService extends JsonPatchOperationsService { diff --git a/src/app/core/json-patch/json-patch-operations.service.ts b/src/app/core/json-patch/json-patch-operations.service.ts index c3363f4db4a..1dfbd404cc6 100644 --- a/src/app/core/json-patch/json-patch-operations.service.ts +++ b/src/app/core/json-patch/json-patch-operations.service.ts @@ -6,7 +6,6 @@ import { hasValue, isEmpty, isNotEmpty, isNotUndefined, isUndefined } from '../. import { PatchRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { CoreState } from '../core.reducers'; import { jsonPatchOperationsByResourceType } from './selectors'; import { JsonPatchOperationsResourceEntry } from './json-patch-operations.reducer'; import { @@ -18,6 +17,7 @@ import { JsonPatchOperationModel } from './json-patch.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteData } from '../data/remote-data'; +import { CoreState } from '../core-state.model'; /** * An abstract class that provides methods to make JSON Patch requests. diff --git a/src/app/core/json-patch/selectors.ts b/src/app/core/json-patch/selectors.ts index 1ccde294de2..20eb8538916 100644 --- a/src/app/core/json-patch/selectors.ts +++ b/src/app/core/json-patch/selectors.ts @@ -1,8 +1,8 @@ import { MemoizedSelector } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { JsonPatchOperationsEntry, JsonPatchOperationsResourceEntry } from './json-patch-operations.reducer'; import { keySelector, subStateSelector } from '../../submission/selectors'; +import { CoreState } from '../core-state.model'; /** * Return MemoizedSelector to select all jsonPatchOperations for a specified resource type, stored in the state diff --git a/src/app/core/metadata/metadata.service.ts b/src/app/core/metadata/metadata.service.ts index 1c6946b0d3e..469a908ab59 100644 --- a/src/app/core/metadata/metadata.service.ts +++ b/src/app/core/metadata/metadata.service.ts @@ -31,7 +31,7 @@ import { MetaTagState } from './meta-tag.reducer'; import { createSelector, select, Store } from '@ngrx/store'; import { AddMetaTagAction, ClearMetaTagAction } from './meta-tag.actions'; import { coreSelector } from '../core.selectors'; -import { CoreState } from '../core.reducers'; +import { CoreState } from '../core-state.model'; /** * The base selector function to select the metaTag section in the store diff --git a/src/app/core/pagination/pagination.service.spec.ts b/src/app/core/pagination/pagination.service.spec.ts index 18f94cc84c6..94b6b48d59d 100644 --- a/src/app/core/pagination/pagination.service.spec.ts +++ b/src/app/core/pagination/pagination.service.spec.ts @@ -3,7 +3,7 @@ import { RouterStub } from '../../shared/testing/router.stub'; import { of as observableOf } from 'rxjs'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../cache/models/sort-options.model'; -import { FindListOptions } from '../data/request.models'; +import { FindListOptions } from '../data/find-list-options.model'; describe('PaginationService', () => { diff --git a/src/app/core/pagination/pagination.service.ts b/src/app/core/pagination/pagination.service.ts index dae69918346..bddb565c899 100644 --- a/src/app/core/pagination/pagination.service.ts +++ b/src/app/core/pagination/pagination.service.ts @@ -5,10 +5,10 @@ import { PaginationComponentOptions } from '../../shared/pagination/pagination-c import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { filter, map, take } from 'rxjs/operators'; import { SortDirection, SortOptions } from '../cache/models/sort-options.model'; -import { FindListOptions } from '../data/request.models'; import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; import { difference } from '../../shared/object.util'; import { isNumeric } from 'rxjs/internal-compatibility'; +import { FindListOptions } from '../data/find-list-options.model'; @Injectable({ diff --git a/src/app/core/registry/registry.service.spec.ts b/src/app/core/registry/registry.service.spec.ts index 199f43e98e2..db52a0547ec 100644 --- a/src/app/core/registry/registry.service.spec.ts +++ b/src/app/core/registry/registry.service.spec.ts @@ -23,13 +23,13 @@ import { MetadataField } from '../metadata/metadata-field.model'; import { MetadataSchema } from '../metadata/metadata-schema.model'; import { RegistryService } from './registry.service'; import { storeModuleConfig } from '../../app.reducer'; -import { FindListOptions } from '../data/request.models'; import { MetadataSchemaDataService } from '../data/metadata-schema-data.service'; import { MetadataFieldDataService } from '../data/metadata-field-data.service'; import { createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { RemoteData } from '../data/remote-data'; import { NoContent } from '../shared/NoContent.model'; +import { FindListOptions } from '../data/find-list-options.model'; @Component({ template: '' }) class DummyComponent { diff --git a/src/app/core/registry/registry.service.ts b/src/app/core/registry/registry.service.ts index 0046dbdb19c..7a377405bd0 100644 --- a/src/app/core/registry/registry.service.ts +++ b/src/app/core/registry/registry.service.ts @@ -2,7 +2,6 @@ import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { Injectable } from '@angular/core'; import { RemoteData } from '../data/remote-data'; import { PaginatedList } from '../data/paginated-list.model'; -import { FindListOptions } from '../data/request.models'; import { hasValue, hasValueOperator, isNotEmptyOperator } from '../../shared/empty.util'; import { getFirstSucceededRemoteDataPayload } from '../shared/operators'; import { createSelector, select, Store } from '@ngrx/store'; @@ -30,6 +29,7 @@ import { MetadataFieldDataService } from '../data/metadata-field-data.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { RequestParam } from '../cache/models/request-param.model'; import { NoContent } from '../shared/NoContent.model'; +import { FindListOptions } from '../data/find-list-options.model'; const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry; const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema); diff --git a/src/app/core/resource-policy/resource-policy.service.spec.ts b/src/app/core/resource-policy/resource-policy.service.spec.ts index 9330def8e88..59316c00981 100644 --- a/src/app/core/resource-policy/resource-policy.service.spec.ts +++ b/src/app/core/resource-policy/resource-policy.service.spec.ts @@ -12,13 +12,13 @@ import { RequestService } from '../data/request.service'; import { ResourcePolicyService } from './resource-policy.service'; import { PolicyType } from './models/policy-type.model'; import { ActionType } from './models/action-type.model'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { PageInfo } from '../shared/page-info.model'; import { buildPaginatedList } from '../data/paginated-list.model'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; -import { RequestEntry } from '../data/request.reducer'; import { RestResponse } from '../cache/response.models'; +import { RequestEntry } from '../data/request-entry.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('ResourcePolicyService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/resource-policy/resource-policy.service.ts b/src/app/core/resource-policy/resource-policy.service.ts index 0f4c6a78f8d..eeba5a10118 100644 --- a/src/app/core/resource-policy/resource-policy.service.ts +++ b/src/app/core/resource-policy/resource-policy.service.ts @@ -8,13 +8,11 @@ import { dataService } from '../cache/builders/build-decorators'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; -import { FindListOptions } from '../data/request.models'; import { Collection } from '../shared/collection.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ResourcePolicy } from './models/resource-policy.model'; import { RemoteData } from '../data/remote-data'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { RESOURCE_POLICY } from './models/resource-policy.resource-type'; @@ -27,6 +25,8 @@ import { isNotEmpty } from '../../shared/empty.util'; import { map } from 'rxjs/operators'; import { NoContent } from '../shared/NoContent.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/services/route.service.ts b/src/app/core/services/route.service.ts index 23b7ccec85e..b84bb40373a 100644 --- a/src/app/core/services/route.service.ts +++ b/src/app/core/services/route.service.ts @@ -7,11 +7,11 @@ import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; import { isEqual } from 'lodash'; import { AddParameterAction, SetParameterAction, SetParametersAction, SetQueryParameterAction, SetQueryParametersAction } from './route.actions'; -import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { hasValue } from '../../shared/empty.util'; import { historySelector } from '../history/selectors'; import { AddUrlToHistoryAction } from '../history/history.actions'; +import { CoreState } from '../core-state.model'; /** * Selector to select all route parameters from the store diff --git a/src/app/core/shared/operators.spec.ts b/src/app/core/shared/operators.spec.ts index eb102065cd7..872c087325e 100644 --- a/src/app/core/shared/operators.spec.ts +++ b/src/app/core/shared/operators.spec.ts @@ -2,7 +2,6 @@ import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { GetRequest } from '../data/request.models'; -import { RequestEntry } from '../data/request.reducer'; import { RequestService } from '../data/request.service'; import { getAllSucceededRemoteData, @@ -16,6 +15,7 @@ import { } from '../../shared/remote-data.utils'; import { getRequestFromRequestHref, getRequestFromRequestUUID, getResponseFromEntry, sendRequest } from './request.operators'; import { redirectOn4xx } from './authorized.operators'; +import { RequestEntry } from '../data/request-entry.model'; // tslint:disable:no-shadowed-variable diff --git a/src/app/core/shared/request.operators.ts b/src/app/core/shared/request.operators.ts index 3caba824b94..c529259f035 100644 --- a/src/app/core/shared/request.operators.ts +++ b/src/app/core/shared/request.operators.ts @@ -1,9 +1,10 @@ import { RequestService } from '../data/request.service'; import { Observable } from 'rxjs'; -import { RestRequest } from '../data/request.models'; import { filter, map, mergeMap, tap } from 'rxjs/operators'; -import { RequestEntry, ResponseState } from '../data/request.reducer'; import { hasValue, hasValueOperator } from '../../shared/empty.util'; +import { RestRequest } from '../data/rest-request.model'; +import { RequestEntry } from '../data/request-entry.model'; +import { ResponseState } from '../data/response-state.model'; /** * This file contains custom RxJS operators that can be used in multiple places diff --git a/src/app/core/shared/search/search-configuration.service.spec.ts b/src/app/core/shared/search/search-configuration.service.spec.ts index 30be28f65fd..0cb97630725 100644 --- a/src/app/core/shared/search/search-configuration.service.spec.ts +++ b/src/app/core/shared/search/search-configuration.service.spec.ts @@ -8,12 +8,12 @@ import { combineLatest as observableCombineLatest, Observable, of as observableO import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; import { HALEndpointServiceStub } from '../../../shared/testing/hal-endpoint-service.stub'; import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock'; -import { RequestEntry } from '../../data/request.reducer'; import { map } from 'rxjs/operators'; import { RemoteData } from '../../data/remote-data'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { SearchObjects } from '../../../shared/search/search-objects.model'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; +import { RequestEntry } from '../../data/request-entry.model'; describe('SearchConfigurationService', () => { let service: SearchConfigurationService; diff --git a/src/app/core/shared/search/search-configuration.service.ts b/src/app/core/shared/search/search-configuration.service.ts index d62e5ea01bb..0a2afe61830 100644 --- a/src/app/core/shared/search/search-configuration.service.ts +++ b/src/app/core/shared/search/search-configuration.service.ts @@ -491,7 +491,7 @@ export class SearchConfigurationService implements OnDestroy { let filters: SearchFilterConfig[]; if (isNotEmpty(rd.payload.filters)) { filters = rd.payload.filters - .map((filter: any) => Object.assign(new SearchFilterConfig(), filter)); + .map((f: any) => Object.assign(new SearchFilterConfig(), f)); } else { filters = []; } diff --git a/src/app/core/shared/search/search.service.spec.ts b/src/app/core/shared/search/search.service.spec.ts index d41f6d8d721..c9b6152efdd 100644 --- a/src/app/core/shared/search/search.service.spec.ts +++ b/src/app/core/shared/search/search.service.spec.ts @@ -11,7 +11,6 @@ import { HALEndpointService } from '../hal-endpoint.service'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model'; import { RemoteData } from '../../data/remote-data'; -import { RequestEntry } from '../../data/request.reducer'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; import { CommunityDataService } from '../../data/community-data.service'; import { ViewMode } from '../view-mode.model'; @@ -25,9 +24,10 @@ import { SearchObjects } from '../../../shared/search/search-objects.model'; import { PaginationService } from '../../pagination/pagination.service'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../cache/models/sort-options.model'; -import { FindListOptions } from '../../data/request.models'; import { SearchConfigurationService } from './search-configuration.service'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { RequestEntry } from '../../data/request-entry.model'; +import { FindListOptions } from '../../data/find-list-options.model'; @Component({ template: '' }) class DummyComponent { diff --git a/src/app/core/shared/search/search.service.ts b/src/app/core/shared/search/search.service.ts index 13340874e72..8219cb803c8 100644 --- a/src/app/core/shared/search/search.service.ts +++ b/src/app/core/shared/search/search.service.ts @@ -7,7 +7,7 @@ import { LinkService } from '../../cache/builders/link.service'; import { PaginatedList } from '../../data/paginated-list.model'; import { ResponseParsingService } from '../../data/parsing.service'; import { RemoteData } from '../../data/remote-data'; -import { GetRequest, RestRequest } from '../../data/request.models'; +import { GetRequest} from '../../data/request.models'; import { RequestService } from '../../data/request.service'; import { DSpaceObject } from '../dspace-object.model'; import { GenericConstructor } from '../generic-constructor'; @@ -43,11 +43,12 @@ import { SearchConfigurationService } from './search-configuration.service'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { DataService } from '../../data/data.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DSOChangeAnalyzer } from '../../data/dso-change-analyzer.service'; +import { RestRequest } from '../../data/rest-request.model'; +import { CoreState } from '../../core-state.model'; /* tslint:disable:max-classes-per-file */ /** diff --git a/src/app/core/statistics/usage-report-data.service.ts b/src/app/core/statistics/usage-report-data.service.ts index 74385777b1b..be23f71c48c 100644 --- a/src/app/core/statistics/usage-report-data.service.ts +++ b/src/app/core/statistics/usage-report-data.service.ts @@ -5,7 +5,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; @@ -15,6 +14,7 @@ import { UsageReport } from './models/usage-report.model'; import { Observable } from 'rxjs'; import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../shared/operators'; import { map } from 'rxjs/operators'; +import { CoreState } from '../core-state.model'; /** * A service to retrieve {@link UsageReport}s from the REST API diff --git a/src/app/core/submission/submission-cc-license-data.service.ts b/src/app/core/submission/submission-cc-license-data.service.ts index 5a3fa1ec2b0..4c92ad708a9 100644 --- a/src/app/core/submission/submission-cc-license-data.service.ts +++ b/src/app/core/submission/submission-cc-license-data.service.ts @@ -5,13 +5,13 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; import { SUBMISSION_CC_LICENSE } from './models/submission-cc-licence.resource-type'; import { SubmissionCcLicence } from './models/submission-cc-license.model'; import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; +import { CoreState } from '../core-state.model'; @Injectable() @dataService(SUBMISSION_CC_LICENSE) diff --git a/src/app/core/submission/submission-cc-license-url-data.service.ts b/src/app/core/submission/submission-cc-license-url-data.service.ts index 0ca3853d0e3..1e72f791937 100644 --- a/src/app/core/submission/submission-cc-license-url-data.service.ts +++ b/src/app/core/submission/submission-cc-license-url-data.service.ts @@ -5,7 +5,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; @@ -17,6 +16,7 @@ import { Observable } from 'rxjs'; import { filter, map, switchMap } from 'rxjs/operators'; import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../shared/operators'; import { isNotEmpty } from '../../shared/empty.util'; +import { CoreState } from '../core-state.model'; @Injectable() @dataService(SUBMISSION_CC_LICENSE_URL) diff --git a/src/app/core/submission/submission-json-patch-operations.service.spec.ts b/src/app/core/submission/submission-json-patch-operations.service.spec.ts index 72c807ffa1d..5472e868563 100644 --- a/src/app/core/submission/submission-json-patch-operations.service.spec.ts +++ b/src/app/core/submission/submission-json-patch-operations.service.spec.ts @@ -3,12 +3,12 @@ import { Store } from '@ngrx/store'; import { getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { SubmissionJsonPatchOperationsService } from './submission-json-patch-operations.service'; import { RequestService } from '../data/request.service'; import { SubmissionPatchRequest } from '../data/request.models'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { CoreState } from '../core-state.model'; describe('SubmissionJsonPatchOperationsService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/submission/submission-json-patch-operations.service.ts b/src/app/core/submission/submission-json-patch-operations.service.ts index cd6308f7f3d..5771c85b574 100644 --- a/src/app/core/submission/submission-json-patch-operations.service.ts +++ b/src/app/core/submission/submission-json-patch-operations.service.ts @@ -7,8 +7,8 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { JsonPatchOperationsService } from '../json-patch/json-patch-operations.service'; import { SubmitDataResponseDefinitionObject } from '../shared/submit-data-response-definition.model'; import { SubmissionPatchRequest } from '../data/request.models'; -import { CoreState } from '../core.reducers'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { CoreState } from '../core-state.model'; /** * A service that provides methods to make JSON Patch requests. diff --git a/src/app/core/submission/submission-response-parsing.service.ts b/src/app/core/submission/submission-response-parsing.service.ts index 3b028c67cc3..ff847762357 100644 --- a/src/app/core/submission/submission-response-parsing.service.ts +++ b/src/app/core/submission/submission-response-parsing.service.ts @@ -3,7 +3,6 @@ import { deepClone } from 'fast-json-patch'; import { DSOResponseParsingService } from '../data/dso-response-parsing.service'; import { ResponseParsingService } from '../data/parsing.service'; -import { RestRequest } from '../data/request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ParsedResponse } from '../cache/response.models'; import { isEmpty, isNotEmpty, isNotNull } from '../../shared/empty.util'; @@ -14,6 +13,7 @@ import { FormFieldMetadataValueObject } from '../../shared/form/builder/models/f import { SubmissionObject } from './models/submission-object.model'; import { WorkflowItem } from './models/workflowitem.model'; import { WorkspaceItem } from './models/workspaceitem.model'; +import { RestRequest } from '../data/rest-request.model'; /** * Export a function to check if object has same properties of FormFieldMetadataValueObject diff --git a/src/app/core/submission/submission-rest.service.ts b/src/app/core/submission/submission-rest.service.ts index 000f8396f82..cf4b741af23 100644 --- a/src/app/core/submission/submission-rest.service.ts +++ b/src/app/core/submission/submission-rest.service.ts @@ -8,7 +8,6 @@ import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { DeleteRequest, PostRequest, - RestRequest, SubmissionDeleteRequest, SubmissionPatchRequest, SubmissionPostRequest, @@ -22,6 +21,7 @@ import { getFirstCompletedRemoteData } from '../shared/operators'; import { URLCombiner } from '../url-combiner/url-combiner'; import { RemoteData } from '../data/remote-data'; import { SubmissionResponse } from './submission-response.model'; +import { RestRequest } from '../data/rest-request.model'; /** * The service handling all submission REST requests diff --git a/src/app/core/submission/vocabularies/models/vocabulary-find-options.model.ts b/src/app/core/submission/vocabularies/models/vocabulary-find-options.model.ts index 977228ea9df..7feacd591bc 100644 --- a/src/app/core/submission/vocabularies/models/vocabulary-find-options.model.ts +++ b/src/app/core/submission/vocabularies/models/vocabulary-find-options.model.ts @@ -1,7 +1,7 @@ import { SortOptions } from '../../../cache/models/sort-options.model'; -import { FindListOptions } from '../../../data/request.models'; import { RequestParam } from '../../../cache/models/request-param.model'; import { isNotEmpty } from '../../../../shared/empty.util'; +import { FindListOptions } from '../../../data/find-list-options.model'; /** * Representing properties used to build a vocabulary find request diff --git a/src/app/core/submission/vocabularies/vocabulary.service.spec.ts b/src/app/core/submission/vocabularies/vocabulary.service.spec.ts index 9f8bec307f2..8f733e01491 100644 --- a/src/app/core/submission/vocabularies/vocabulary.service.spec.ts +++ b/src/app/core/submission/vocabularies/vocabulary.service.spec.ts @@ -16,7 +16,6 @@ import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; -import { RequestEntry } from '../../data/request.reducer'; import { RestResponse } from '../../cache/response.models'; import { VocabularyService } from './vocabulary.service'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; @@ -26,6 +25,7 @@ import { VocabularyFindOptions } from './models/vocabulary-find-options.model'; import { HrefOnlyDataService } from '../../data/href-only-data.service'; import { getMockHrefOnlyDataService } from '../../../shared/mocks/href-only-data.service.mock'; import { createPaginatedList } from '../../../shared/testing/utils.test'; +import { RequestEntry } from '../../data/request-entry.model'; describe('VocabularyService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/submission/vocabularies/vocabulary.service.ts b/src/app/core/submission/vocabularies/vocabulary.service.ts index da58512441d..2e7f1911ca7 100644 --- a/src/app/core/submission/vocabularies/vocabulary.service.ts +++ b/src/app/core/submission/vocabularies/vocabulary.service.ts @@ -9,11 +9,9 @@ import { FollowLinkConfig, followLink } from '../../../shared/utils/follow-link- import { dataService } from '../../cache/builders/build-decorators'; import { DataService } from '../../data/data.service'; import { RequestService } from '../../data/request.service'; -import { FindListOptions } from '../../data/request.models'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { RemoteData } from '../../data/remote-data'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { ChangeAnalyzer } from '../../data/change-analyzer'; @@ -33,6 +31,8 @@ import { RequestParam } from '../../cache/models/request-param.model'; import { VocabularyOptions } from './models/vocabulary-options.model'; import { PageInfo } from '../../shared/page-info.model'; import { HrefOnlyDataService } from '../../data/href-only-data.service'; +import { CoreState } from '../../core-state.model'; +import { FindListOptions } from '../../data/find-list-options.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/submission/workflowitem-data.service.ts b/src/app/core/submission/workflowitem-data.service.ts index 099cfa8627f..c97426e681d 100644 --- a/src/app/core/submission/workflowitem-data.service.ts +++ b/src/app/core/submission/workflowitem-data.service.ts @@ -4,7 +4,6 @@ import { HttpClient } from '@angular/common/http'; import { Store } from '@ngrx/store'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { CoreState } from '../core.reducers'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; import { WorkflowItem } from './models/workflowitem.model'; @@ -19,6 +18,7 @@ import { hasValue } from '../../shared/empty.util'; import { RemoteData } from '../data/remote-data'; import { NoContent } from '../shared/NoContent.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; /** * A service that provides methods to make REST requests with workflow items endpoint. diff --git a/src/app/core/submission/workspaceitem-data.service.ts b/src/app/core/submission/workspaceitem-data.service.ts index 2fc95bdd007..f4a4321b01d 100644 --- a/src/app/core/submission/workspaceitem-data.service.ts +++ b/src/app/core/submission/workspaceitem-data.service.ts @@ -4,7 +4,6 @@ import { HttpClient } from '@angular/common/http'; import { Store } from '@ngrx/store'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { CoreState } from '../core.reducers'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -12,6 +11,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { ObjectCacheService } from '../cache/object-cache.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { WorkspaceItem } from './models/workspaceitem.model'; +import { CoreState } from '../core-state.model'; /** * A service that provides methods to make REST requests with workspaceitems endpoint. diff --git a/src/app/core/tasks/claimed-task-data.service.spec.ts b/src/app/core/tasks/claimed-task-data.service.spec.ts index ab9727592e9..722324d94ca 100644 --- a/src/app/core/tasks/claimed-task-data.service.spec.ts +++ b/src/app/core/tasks/claimed-task-data.service.spec.ts @@ -6,15 +6,15 @@ 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 { NotificationsService } from '../../shared/notifications/notifications.service'; -import { CoreState } from '../core.reducers'; import { ClaimedTaskDataService } from './claimed-task-data.service'; import { of as observableOf } from 'rxjs/internal/observable/of'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('ClaimedTaskDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/tasks/claimed-task-data.service.ts b/src/app/core/tasks/claimed-task-data.service.ts index 9cfd5a44d65..3860f848702 100644 --- a/src/app/core/tasks/claimed-task-data.service.ts +++ b/src/app/core/tasks/claimed-task-data.service.ts @@ -7,7 +7,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -16,10 +15,11 @@ import { CLAIMED_TASK } from './models/claimed-task-object.resource-type'; import { ProcessTaskResponse } from './models/process-task-response'; import { TasksService } from './tasks.service'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { getFirstSucceededRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /** * The service handling all REST requests for ClaimedTask diff --git a/src/app/core/tasks/pool-task-data.service.spec.ts b/src/app/core/tasks/pool-task-data.service.spec.ts index 7279c96e5c7..d06076009ed 100644 --- a/src/app/core/tasks/pool-task-data.service.spec.ts +++ b/src/app/core/tasks/pool-task-data.service.spec.ts @@ -6,15 +6,15 @@ 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 { NotificationsService } from '../../shared/notifications/notifications.service'; -import { CoreState } from '../core.reducers'; import { PoolTaskDataService } from './pool-task-data.service'; import { getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; import { of as observableOf } from 'rxjs/internal/observable/of'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('PoolTaskDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/tasks/pool-task-data.service.ts b/src/app/core/tasks/pool-task-data.service.ts index d44e402e7f0..042c9a3455a 100644 --- a/src/app/core/tasks/pool-task-data.service.ts +++ b/src/app/core/tasks/pool-task-data.service.ts @@ -7,7 +7,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -15,9 +14,10 @@ import { PoolTask } from './models/pool-task-object.model'; import { POOL_TASK } from './models/pool-task-object.resource-type'; import { TasksService } from './tasks.service'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /** * The service handling all REST requests for PoolTask diff --git a/src/app/core/tasks/task-response-parsing.service.ts b/src/app/core/tasks/task-response-parsing.service.ts index 75c40567189..e2e009386fe 100644 --- a/src/app/core/tasks/task-response-parsing.service.ts +++ b/src/app/core/tasks/task-response-parsing.service.ts @@ -1,12 +1,12 @@ import { Injectable } from '@angular/core'; import { ResponseParsingService } from '../data/parsing.service'; -import { RestRequest } from '../data/request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { BaseResponseParsingService } from '../data/base-response-parsing.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { ParsedResponse } from '../cache/response.models'; +import { RestRequest } from '../data/rest-request.model'; /** * Provides methods to parse response for a task request. diff --git a/src/app/core/tasks/tasks.service.spec.ts b/src/app/core/tasks/tasks.service.spec.ts index f0c86d2abfb..aa267b90769 100644 --- a/src/app/core/tasks/tasks.service.spec.ts +++ b/src/app/core/tasks/tasks.service.spec.ts @@ -4,13 +4,12 @@ import { TestScheduler } from 'rxjs/testing'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { TasksService } from './tasks.service'; import { RequestService } from '../data/request.service'; -import { FindListOptions, TaskDeleteRequest, TaskPostRequest } from '../data/request.models'; +import { TaskDeleteRequest, TaskPostRequest } from '../data/request.models'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { TaskObject } from './models/task-object.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient, HttpHeaders } from '@angular/common/http'; @@ -22,6 +21,8 @@ import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; import { of } from 'rxjs'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; const LINK_NAME = 'test'; diff --git a/src/app/core/tasks/tasks.service.ts b/src/app/core/tasks/tasks.service.ts index d96e3320f2f..2b76412a9c6 100644 --- a/src/app/core/tasks/tasks.service.ts +++ b/src/app/core/tasks/tasks.service.ts @@ -6,7 +6,6 @@ import { distinctUntilChanged, filter, find, map, mergeMap, tap } from 'rxjs/ope import { DataService } from '../data/data.service'; import { DeleteRequest, - FindListOptions, PostRequest, TaskDeleteRequest, TaskPostRequest @@ -18,6 +17,7 @@ import { getAllCompletedRemoteData, getFirstCompletedRemoteData } from '../share import { RemoteData } from '../data/remote-data'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { FindListOptions } from '../data/find-list-options.model'; /** * An abstract class that provides methods to handle task requests. diff --git a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.spec.ts b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.spec.ts index 30048acc6d6..55abd5edd87 100644 --- a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.spec.ts +++ b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.spec.ts @@ -11,12 +11,12 @@ import { Store } from '@ngrx/store'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { CoreState } from '../../core/core.reducers'; import { Registration } from '../../core/shared/registration.model'; import { ForgotPasswordFormComponent } from './forgot-password-form.component'; import { By } from '@angular/platform-browser'; import { AuthenticateAction } from '../../core/auth/auth.actions'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { CoreState } from '../../core/core-state.model'; describe('ForgotPasswordFormComponent', () => { let comp: ForgotPasswordFormComponent; diff --git a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts index 707c70f19cf..e6e5e5cb06f 100644 --- a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts +++ b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts @@ -8,10 +8,10 @@ import { map } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; import { AuthenticateAction } from '../../core/auth/auth.actions'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core/core.reducers'; import { RemoteData } from '../../core/data/remote-data'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { CoreState } from '../../core/core-state.model'; @Component({ selector: 'ds-forgot-password-form', diff --git a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts index 00408e46966..eb52ca9243e 100644 --- a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts +++ b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts @@ -13,7 +13,6 @@ import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { SharedModule } from '../../shared/shared.module'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; -import { FindListOptions } from '../../core/data/request.models'; import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub'; import { CommunityDataService } from '../../core/data/community-data.service'; @@ -25,6 +24,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('TopLevelCommunityList Component', () => { let comp: TopLevelCommunityListComponent; 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 index 807d9f83574..133b13cb279 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.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 @@ -19,8 +19,8 @@ import { RequestService } from '../../../../../core/data/request.service'; import { PaginationService } from '../../../../../core/pagination/pagination.service'; import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../../core/data/request.models'; import { PaginationServiceStub } from '../../../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../../../core/data/find-list-options.model'; describe('PaginatedDragAndDropBitstreamListComponent', () => { let comp: PaginatedDragAndDropBitstreamListComponent; diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.spec.ts b/src/app/item-page/full/field-components/file-section/full-file-section.component.spec.ts index 9b225632dfe..396e6c32160 100644 --- a/src/app/item-page/full/field-components/file-section/full-file-section.component.spec.ts +++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.spec.ts @@ -18,9 +18,9 @@ import { NotificationsService } from '../../../../shared/notifications/notificat import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service.stub'; import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../core/data/request.models'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; describe('FullFileSectionComponent', () => { let comp: FullFileSectionComponent; diff --git a/src/app/item-page/simple/related-items/related-items-component.ts b/src/app/item-page/simple/related-items/related-items-component.ts index f752d3589e6..e0d65b9a6dc 100644 --- a/src/app/item-page/simple/related-items/related-items-component.ts +++ b/src/app/item-page/simple/related-items/related-items-component.ts @@ -3,10 +3,10 @@ import { Item } from '../../../core/shared/item.model'; import { Observable } from 'rxjs'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { ViewMode } from '../../../core/shared/view-mode.model'; import { RelationshipService } from '../../../core/data/relationship.service'; import { AbstractIncrementalListComponent } from '../abstract-incremental-list/abstract-incremental-list.component'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; @Component({ selector: 'ds-related-items', diff --git a/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts b/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts index 53646a27d81..c33d27ec77f 100644 --- a/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts +++ b/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts @@ -15,13 +15,13 @@ import { CollectionDropdownComponent } from '../../shared/collection-dropdown/co import { Collection } from '../../core/shared/collection.model'; import { RemoteData } from '../../core/data/remote-data'; import { Community } from '../../core/shared/community.model'; -import { FindListOptions } from '../../core/data/request.models'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { CollectionDataService } from '../../core/data/collection-data.service'; import { MockElementRef } from '../../shared/testing/element-ref.mock'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('CollectionSelectorComponent', () => { diff --git a/src/app/my-dspace-page/my-dspace-page.component.spec.ts b/src/app/my-dspace-page/my-dspace-page.component.spec.ts index a7f16d41844..d2d742f9408 100644 --- a/src/app/my-dspace-page/my-dspace-page.component.spec.ts +++ b/src/app/my-dspace-page/my-dspace-page.component.spec.ts @@ -139,7 +139,7 @@ describe('MyDSpacePageComponent', () => { fixture.detectChanges(); searchServiceObject = (comp as any).service; searchConfigurationServiceObject = (comp as any).searchConfigService; - console.log(searchConfigurationServiceObject) + console.log(searchConfigurationServiceObject); }); afterEach(() => { diff --git a/src/app/process-page/overview/process-overview.component.spec.ts b/src/app/process-page/overview/process-overview.component.spec.ts index 98e78f6b36f..4cbd7e34539 100644 --- a/src/app/process-page/overview/process-overview.component.spec.ts +++ b/src/app/process-page/overview/process-overview.component.spec.ts @@ -16,8 +16,8 @@ import { of as observableOf } from 'rxjs'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('ProcessOverviewComponent', () => { let component: ProcessOverviewComponent; diff --git a/src/app/process-page/overview/process-overview.component.ts b/src/app/process-page/overview/process-overview.component.ts index 03fcf27222a..7afcd9cb766 100644 --- a/src/app/process-page/overview/process-overview.component.ts +++ b/src/app/process-page/overview/process-overview.component.ts @@ -4,13 +4,13 @@ import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { Process } from '../processes/process.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { map, switchMap } from 'rxjs/operators'; import { ProcessDataService } from '../../core/data/processes/process-data.service'; import { PaginationService } from '../../core/pagination/pagination.service'; +import { FindListOptions } from '../../core/data/find-list-options.model'; @Component({ selector: 'ds-process-overview', diff --git a/src/app/register-page/create-profile/create-profile.component.spec.ts b/src/app/register-page/create-profile/create-profile.component.spec.ts index 63710442297..06b04995427 100644 --- a/src/app/register-page/create-profile/create-profile.component.spec.ts +++ b/src/app/register-page/create-profile/create-profile.component.spec.ts @@ -12,7 +12,6 @@ import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { of as observableOf } from 'rxjs'; import { By } from '@angular/platform-browser'; -import { CoreState } from '../../core/core.reducers'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { AuthenticateAction } from '../../core/auth/auth.actions'; import { RouterStub } from '../../shared/testing/router.stub'; @@ -22,6 +21,7 @@ import { EndUserAgreementService } from '../../core/end-user-agreement/end-user-agreement.service'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { CoreState } from '../../core/core-state.model'; describe('CreateProfileComponent', () => { let comp: CreateProfileComponent; diff --git a/src/app/register-page/create-profile/create-profile.component.ts b/src/app/register-page/create-profile/create-profile.component.ts index 790e1d6fc5d..8c38e3a5468 100644 --- a/src/app/register-page/create-profile/create-profile.component.ts +++ b/src/app/register-page/create-profile/create-profile.component.ts @@ -9,7 +9,6 @@ import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { LangConfig } from '../../../config/lang-config.interface'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core/core.reducers'; import { AuthenticateAction } from '../../core/auth/auth.actions'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { environment } from '../../../environments/environment'; @@ -20,6 +19,7 @@ import { EndUserAgreementService } from '../../core/end-user-agreement/end-user-agreement.service'; import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { CoreState } from '../../core/core-state.model'; /** * Component that renders the create profile page to be used by a user registering through a token 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 806f4bdb6f9..e266c613784 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -18,9 +18,9 @@ import { PaginationComponentOptions } from '../pagination/pagination-component-o import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; import { storeModuleConfig } from '../../app.reducer'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('BrowseByComponent', () => { let comp: BrowseByComponent; diff --git a/src/app/shared/collection-dropdown/collection-dropdown.component.spec.ts b/src/app/shared/collection-dropdown/collection-dropdown.component.spec.ts index f08df65ca45..ce90d5d6a74 100644 --- a/src/app/shared/collection-dropdown/collection-dropdown.component.spec.ts +++ b/src/app/shared/collection-dropdown/collection-dropdown.component.spec.ts @@ -18,8 +18,8 @@ import { TranslateLoaderMock } from '../mocks/translate-loader.mock'; import { Community } from '../../core/shared/community.model'; import { MockElementRef } from '../testing/element-ref.mock'; import { FollowLinkConfig } from '../utils/follow-link-config.model'; -import { FindListOptions } from '../../core/data/request.models'; import { Observable } from 'rxjs/internal/Observable'; +import { FindListOptions } from '../../core/data/find-list-options.model'; const community: Community = Object.assign(new Community(), { id: 'ce64f48e-2c9b-411a-ac36-ee429c0e6a88', diff --git a/src/app/shared/collection-dropdown/collection-dropdown.component.ts b/src/app/shared/collection-dropdown/collection-dropdown.component.ts index c91ddbdb0a9..4a5fc705a82 100644 --- a/src/app/shared/collection-dropdown/collection-dropdown.component.ts +++ b/src/app/shared/collection-dropdown/collection-dropdown.component.ts @@ -15,7 +15,6 @@ import { debounceTime, distinctUntilChanged, map, mergeMap, reduce, startWith, s import { hasValue } from '../empty.util'; import { RemoteData } from '../../core/data/remote-data'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { Community } from '../../core/shared/community.model'; import { CollectionDataService } from '../../core/data/collection-data.service'; @@ -25,6 +24,7 @@ import { getFirstSucceededRemoteDataPayload, getFirstSucceededRemoteWithNotEmptyData } from '../../core/shared/operators'; +import { FindListOptions } from '../../core/data/find-list-options.model'; /** * An interface to represent a collection entry diff --git a/src/app/shared/log-in/log-in.component.ts b/src/app/shared/log-in/log-in.component.ts index c0df6adec8f..120f3ac4fad 100644 --- a/src/app/shared/log-in/log-in.component.ts +++ b/src/app/shared/log-in/log-in.component.ts @@ -8,12 +8,12 @@ import { isAuthenticated, isAuthenticationLoading } from '../../core/auth/selectors'; -import { CoreState } from '../../core/core.reducers'; import { getForgotPasswordRoute, getRegisterRoute } from '../../app-routing-paths'; import { hasValue } from '../empty.util'; import { AuthService } from '../../core/auth/auth.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../core/data/feature-authorization/feature-id'; +import { CoreState } from '../../core/core-state.model'; /** * /users/sign-in diff --git a/src/app/shared/log-in/methods/password/log-in-password.component.ts b/src/app/shared/log-in/methods/password/log-in-password.component.ts index c72881d3bfc..e4a92ded296 100644 --- a/src/app/shared/log-in/methods/password/log-in-password.component.ts +++ b/src/app/shared/log-in/methods/password/log-in-password.component.ts @@ -7,7 +7,6 @@ import { Observable } from 'rxjs'; import { AuthenticateAction, ResetAuthenticationMessagesAction } from '../../../../core/auth/auth.actions'; import { getAuthenticationError, getAuthenticationInfo, } from '../../../../core/auth/selectors'; -import { CoreState } from '../../../../core/core.reducers'; import { isNotEmpty } from '../../../empty.util'; import { fadeOut } from '../../../animations/fade'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; @@ -15,6 +14,7 @@ import { renderAuthMethodFor } from '../log-in.methods-decorator'; import { AuthMethod } from '../../../../core/auth/models/auth.method'; import { AuthService } from '../../../../core/auth/auth.service'; import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; +import { CoreState } from '../../../../core/core-state.model'; /** * /users/sign-in diff --git a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts index b0704d5cb15..d218a7ca4ed 100644 --- a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts +++ b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts @@ -7,7 +7,6 @@ import { renderAuthMethodFor } from '../log-in.methods-decorator'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; import { AuthMethod } from '../../../../core/auth/models/auth.method'; -import { CoreState } from '../../../../core/core.reducers'; import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors'; import { RouteService } from '../../../../core/services/route.service'; import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service'; @@ -16,6 +15,7 @@ import { AuthService } from '../../../../core/auth/auth.service'; import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; import { take } from 'rxjs/operators'; import { URLCombiner } from '../../../../core/url-combiner/url-combiner'; +import { CoreState } from '../../../../core/core-state.model'; @Component({ selector: 'ds-log-in-shibboleth', diff --git a/src/app/shared/mocks/remote-data-build.service.mock.ts b/src/app/shared/mocks/remote-data-build.service.mock.ts index 90071f8dc66..7b96c5a67ab 100644 --- a/src/app/shared/mocks/remote-data-build.service.mock.ts +++ b/src/app/shared/mocks/remote-data-build.service.mock.ts @@ -3,10 +3,10 @@ import { map, switchMap } from 'rxjs/operators'; import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service'; import { PaginatedList, buildPaginatedList } from '../../core/data/paginated-list.model'; import { RemoteData } from '../../core/data/remote-data'; -import { RequestEntry } from '../../core/data/request.reducer'; import { PageInfo } from '../../core/shared/page-info.model'; import { hasValue } from '../empty.util'; import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; +import { RequestEntry } from '../../core/data/request-entry.model'; export function getMockRemoteDataBuildService(toRemoteDataObservable$?: Observable>, buildList$?: Observable>>): RemoteDataBuildService { return { diff --git a/src/app/shared/mocks/request.service.mock.ts b/src/app/shared/mocks/request.service.mock.ts index 106fa8b6c77..f07aec587e6 100644 --- a/src/app/shared/mocks/request.service.mock.ts +++ b/src/app/shared/mocks/request.service.mock.ts @@ -1,7 +1,7 @@ import {of as observableOf, Observable } from 'rxjs'; import { RequestService } from '../../core/data/request.service'; -import { RequestEntry } from '../../core/data/request.reducer'; import SpyObj = jasmine.SpyObj; +import { RequestEntry } from '../../core/data/request-entry.model'; export function getMockRequestService(requestEntry$: Observable = observableOf(new RequestEntry())): SpyObj { return jasmine.createSpyObj('requestService', { diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts index 07acf3ea75a..0b5acd343bd 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts @@ -15,7 +15,6 @@ import { DefaultChangeAnalyzer } from '../../../../core/data/default-change-anal import { DSOChangeAnalyzer } from '../../../../core/data/dso-change-analyzer.service'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; import { RemoteData } from '../../../../core/data/remote-data'; -import { FindListOptions } from '../../../../core/data/request.models'; import { Bitstream } from '../../../../core/shared/bitstream.model'; import { FileService } from '../../../../core/shared/file.service'; import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; @@ -32,6 +31,7 @@ import { VarDirective } from '../../../utils/var.directive'; import { ItemDetailPreviewFieldComponent } from './item-detail-preview-field/item-detail-preview-field.component'; import { ItemDetailPreviewComponent } from './item-detail-preview.component'; import { createPaginatedList } from '../../../testing/utils.test'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; function getMockFileService(): FileService { return jasmine.createSpyObj('FileService', { diff --git a/src/app/shared/pagination/pagination.component.spec.ts b/src/app/shared/pagination/pagination.component.spec.ts index cf2d1c13fde..0edab7c662c 100644 --- a/src/app/shared/pagination/pagination.component.spec.ts +++ b/src/app/shared/pagination/pagination.component.spec.ts @@ -32,9 +32,9 @@ import { SortDirection, SortOptions } from '../../core/cache/models/sort-options import { createTestComponent } from '../testing/utils.test'; import { storeModuleConfig } from '../../app.reducer'; import { PaginationService } from '../../core/pagination/pagination.service'; -import { FindListOptions } from '../../core/data/request.models'; import { BehaviorSubject, of as observableOf } from 'rxjs'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; function expectPages(fixture: ComponentFixture, pagesDef: string[]): void { const de = fixture.debugElement.query(By.css('.pagination')); diff --git a/src/app/shared/pagination/pagination.utils.ts b/src/app/shared/pagination/pagination.utils.ts index 5701c96b54c..f70a3d1030b 100644 --- a/src/app/shared/pagination/pagination.utils.ts +++ b/src/app/shared/pagination/pagination.utils.ts @@ -1,5 +1,5 @@ import { PaginationComponentOptions } from './pagination-component-options.model'; -import { FindListOptions } from '../../core/data/request.models'; +import { FindListOptions } from '../../core/data/find-list-options.model'; /** * Transform a PaginationComponentOptions object into a FindListOptions object diff --git a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts index 73aaab5170b..91d9200c2da 100644 --- a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts +++ b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts @@ -20,9 +20,9 @@ import { buildPaginatedList } from '../../../../core/data/paginated-list.model'; import { PageInfo } from '../../../../core/shared/page-info.model'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../core/data/request.models'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; describe('EpersonGroupListComponent test suite', () => { let comp: EpersonGroupListComponent; diff --git a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts index 11b5b5e7b36..3277f724a22 100644 --- a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts +++ b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts @@ -10,7 +10,6 @@ import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; import { PaginationComponentOptions } from '../../../pagination/pagination-component-options.model'; import { DataService } from '../../../../core/data/data.service'; import { hasValue, isNotEmpty } from '../../../empty.util'; -import { FindListOptions } from '../../../../core/data/request.models'; import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; import { getDataServiceFor } from '../../../../core/cache/builders/build-decorators'; import { EPERSON } from '../../../../core/eperson/models/eperson.resource-type'; @@ -21,6 +20,7 @@ import { GroupDataService } from '../../../../core/eperson/group-data.service'; import { fadeInOut } from '../../../animations/fade'; import { getFirstCompletedRemoteData } from '../../../../core/shared/operators'; import { PaginationService } from '../../../../core/pagination/pagination.service'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; export interface SearchEvent { scope: string; diff --git a/src/app/shared/search-form/search-form.component.spec.ts b/src/app/shared/search-form/search-form.component.spec.ts index 1469eac5663..77b51d813d8 100644 --- a/src/app/shared/search-form/search-form.component.spec.ts +++ b/src/app/shared/search-form/search-form.component.spec.ts @@ -10,11 +10,11 @@ import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { SearchService } from '../../core/shared/search/search.service'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { of as observableOf } from 'rxjs'; import { PaginationService } from '../../core/pagination/pagination.service'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('SearchFormComponent', () => { let comp: SearchFormComponent; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts index 7299a39c325..59b14776a28 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts @@ -17,9 +17,9 @@ import { SearchFilterConfig } from '../../../../search-filter-config.model'; import { SearchFacetOptionComponent } from './search-facet-option.component'; import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../../../core/data/request.models'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../../../core/data/find-list-options.model'; describe('SearchFacetOptionComponent', () => { let comp: SearchFacetOptionComponent; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts index 9ed8dee0ea6..324773192fe 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts @@ -21,9 +21,9 @@ import { } from '../../search-range-filter/search-range-filter.component'; import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../../../core/data/request.models'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../../../core/data/find-list-options.model'; describe('SearchFacetRangeOptionComponent', () => { let comp: SearchFacetRangeOptionComponent; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts index 8f422b41bff..2fb9b67fcac 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts @@ -16,9 +16,9 @@ import { SearchFilterConfig } from '../../../../search-filter-config.model'; import { SearchFacetSelectedOptionComponent } from './search-facet-selected-option.component'; import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../../../core/data/request.models'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../../../core/data/find-list-options.model'; describe('SearchFacetSelectedOptionComponent', () => { let comp: SearchFacetSelectedOptionComponent; diff --git a/src/app/shared/search/search-labels/search-label/search-label.component.spec.ts b/src/app/shared/search/search-labels/search-label/search-label.component.spec.ts index b3f9471cbdb..50bcbc69381 100644 --- a/src/app/shared/search/search-labels/search-label/search-label.component.spec.ts +++ b/src/app/shared/search/search-labels/search-label/search-label.component.spec.ts @@ -13,10 +13,10 @@ import { SearchConfigurationServiceStub } from '../../../testing/search-configur import { SearchService } from '../../../../core/shared/search/search.service'; import { PaginationComponentOptions } from '../../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../core/data/request.models'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { PaginationServiceStub } from '../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; describe('SearchLabelComponent', () => { let comp: SearchLabelComponent; diff --git a/src/app/shared/starts-with/date/starts-with-date.component.spec.ts b/src/app/shared/starts-with/date/starts-with-date.component.spec.ts index dfee88c9550..138f8d43ac3 100644 --- a/src/app/shared/starts-with/date/starts-with-date.component.spec.ts +++ b/src/app/shared/starts-with/date/starts-with-date.component.spec.ts @@ -13,9 +13,9 @@ import { EnumKeysPipe } from '../../utils/enum-keys-pipe'; import { RouterStub } from '../../testing/router.stub'; import { PaginationComponentOptions } from '../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('StartsWithDateComponent', () => { let comp: StartsWithDateComponent; diff --git a/src/app/shared/starts-with/text/starts-with-text.component.spec.ts b/src/app/shared/starts-with/text/starts-with-text.component.spec.ts index 9f9d9d6d426..f8715e6ebfd 100644 --- a/src/app/shared/starts-with/text/starts-with-text.component.spec.ts +++ b/src/app/shared/starts-with/text/starts-with-text.component.spec.ts @@ -10,10 +10,10 @@ import { By } from '@angular/platform-browser'; import { StartsWithTextComponent } from './starts-with-text.component'; import { PaginationComponentOptions } from '../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { of as observableOf } from 'rxjs'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('StartsWithTextComponent', () => { let comp: StartsWithTextComponent; diff --git a/src/app/shared/testing/pagination-service.stub.ts b/src/app/shared/testing/pagination-service.stub.ts index 985a5bfc4a8..3ea8e732c8f 100644 --- a/src/app/shared/testing/pagination-service.stub.ts +++ b/src/app/shared/testing/pagination-service.stub.ts @@ -1,7 +1,7 @@ import { of as observableOf } from 'rxjs'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; +import { FindListOptions } from '../../core/data/find-list-options.model'; export class PaginationServiceStub { diff --git a/src/app/shared/testing/submission-rest-service.stub.ts b/src/app/shared/testing/submission-rest-service.stub.ts index 53b2341b507..b6ec9a86a2a 100644 --- a/src/app/shared/testing/submission-rest-service.stub.ts +++ b/src/app/shared/testing/submission-rest-service.stub.ts @@ -2,8 +2,8 @@ import { of as observableOf } from 'rxjs'; import { Store } from '@ngrx/store'; import { RequestService } from '../../core/data/request.service'; -import { CoreState } from '../../core/core.reducers'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; +import { CoreState } from '../../core/core-state.model'; export class SubmissionRestServiceStub { protected linkPath = 'workspaceitems'; diff --git a/src/app/shared/testing/utils.test.ts b/src/app/shared/testing/utils.test.ts index 1e62ee8f004..2f3b85d7911 100644 --- a/src/app/shared/testing/utils.test.ts +++ b/src/app/shared/testing/utils.test.ts @@ -2,10 +2,10 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { Observable } from 'rxjs/internal/Observable'; -import { RequestEntry} from '../../core/data/request.reducer'; import { of as observableOf } from 'rxjs/internal/observable/of'; import { UnCacheableObject } from '../../core/shared/uncacheable-object.model'; import { RequestEntryState } from '../../core/data/request-entry-state.model'; +import { RequestEntry } from '../../core/data/request-entry.model'; /** * Returns true if a Native Element has a specified css class. diff --git a/src/app/shared/utils/follow-link-config.model.ts b/src/app/shared/utils/follow-link-config.model.ts index 08153e1217b..8d785dbaaf5 100644 --- a/src/app/shared/utils/follow-link-config.model.ts +++ b/src/app/shared/utils/follow-link-config.model.ts @@ -1,6 +1,6 @@ -import { FindListOptions } from '../../core/data/request.models'; import { HALResource } from '../../core/shared/hal-resource.model'; import { hasValue } from '../empty.util'; +import { FindListOptions } from '../../core/data/find-list-options.model'; /** * A class to send the retrieval of a {@link HALLink} diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts b/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts index 41ba7751716..48c60e005cc 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts +++ b/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts @@ -10,7 +10,6 @@ import { TranslateService } from '@ngx-translate/core'; import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { hasValue, isEmpty, isNotEmpty } from '../empty.util'; import { isAuthenticated } from '../../core/auth/selectors'; -import { CoreState } from '../../core/core.reducers'; import { VocabularyTreeviewService } from './vocabulary-treeview.service'; import { LOAD_MORE, LOAD_MORE_ROOT, TreeviewFlatNode, TreeviewNode } from './vocabulary-treeview-node.model'; import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model'; @@ -18,6 +17,7 @@ import { PageInfo } from '../../core/shared/page-info.model'; import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model'; import { VocabularyTreeFlattener } from './vocabulary-tree-flattener'; import { VocabularyTreeFlatDataSource } from './vocabulary-tree-flat-data-source'; +import { CoreState } from '../../core/core-state.model'; /** * Component that show a hierarchical vocabulary in a tree view diff --git a/src/app/statistics/statistics.service.spec.ts b/src/app/statistics/statistics.service.spec.ts index cdf81afdb6d..347d3afb5ed 100644 --- a/src/app/statistics/statistics.service.spec.ts +++ b/src/app/statistics/statistics.service.spec.ts @@ -2,10 +2,10 @@ import { StatisticsService } from './statistics.service'; import { RequestService } from '../core/data/request.service'; import { HALEndpointServiceStub } from '../shared/testing/hal-endpoint-service.stub'; import { getMockRequestService } from '../shared/mocks/request.service.mock'; -import { TrackRequest } from './track-request.model'; import { isEqual } from 'lodash'; import { DSpaceObjectType } from '../core/shared/dspace-object-type.model'; import { SearchOptions } from '../shared/search/search-options.model'; +import { RestRequest } from '../core/data/rest-request.model'; describe('StatisticsService', () => { let service: StatisticsService; @@ -27,7 +27,7 @@ describe('StatisticsService', () => { it('should send a request to track an item view ', () => { const mockItem: any = {uuid: 'mock-item-uuid', type: 'item'}; service.trackViewEvent(mockItem); - const request: TrackRequest = requestService.send.calls.mostRecent().args[0]; + const request: RestRequest = requestService.send.calls.mostRecent().args[0]; expect(request.body).toBeDefined('request.body'); const body = JSON.parse(request.body); expect(body.targetId).toBe('mock-item-uuid'); @@ -51,7 +51,7 @@ describe('StatisticsService', () => { }; const sort = {by: 'search-field', order: 'ASC'}; service.trackSearchEvent(mockSearch, page, sort); - const request: TrackRequest = requestService.send.calls.mostRecent().args[0]; + const request: RestRequest = requestService.send.calls.mostRecent().args[0]; const body = JSON.parse(request.body); it('should specify the right query', () => { @@ -108,7 +108,7 @@ describe('StatisticsService', () => { } ]; service.trackSearchEvent(mockSearch, page, sort, filters); - const request: TrackRequest = requestService.send.calls.mostRecent().args[0]; + const request: RestRequest = requestService.send.calls.mostRecent().args[0]; const body = JSON.parse(request.body); it('should specify the dsoType', () => { diff --git a/src/app/statistics/statistics.service.ts b/src/app/statistics/statistics.service.ts index 9e12e627b57..0031773f766 100644 --- a/src/app/statistics/statistics.service.ts +++ b/src/app/statistics/statistics.service.ts @@ -5,8 +5,8 @@ import { map, take } from 'rxjs/operators'; import { TrackRequest } from './track-request.model'; import { hasValue, isNotEmpty } from '../shared/empty.util'; import { HALEndpointService } from '../core/shared/hal-endpoint.service'; -import { RestRequest } from '../core/data/request.models'; import { SearchOptions } from '../shared/search/search-options.model'; +import { RestRequest } from '../core/data/rest-request.model'; /** * The statistics service diff --git a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.spec.ts b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.spec.ts index 983e0355afa..08b746ebdca 100644 --- a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.spec.ts +++ b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.spec.ts @@ -18,11 +18,11 @@ import { PageInfo } from '../../../core/shared/page-info.model'; import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model'; import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils'; import { ExternalSource } from '../../../core/shared/external-source.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { HostWindowService } from '../../../shared/host-window.service'; import { HostWindowServiceStub } from '../../../shared/testing/host-window-service.stub'; import { getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('SubmissionImportExternalSearchbarComponent test suite', () => { let comp: SubmissionImportExternalSearchbarComponent; 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 30f5184d578..0f1128243aa 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 @@ -17,10 +17,10 @@ import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated- import { RemoteData } from '../../../core/data/remote-data'; import { PageInfo } from '../../../core/shared/page-info.model'; import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils'; -import { FindListOptions } from '../../../core/data/request.models'; import { getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators'; import { HostWindowService } from '../../../shared/host-window.service'; import { hasValue } from '../../../shared/empty.util'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; /** * Interface for the selected external source element. From 41ad1727963b6e4ef70d36e7dfc939fc9a79d2a8 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 22 Mar 2022 14:00:55 +0100 Subject: [PATCH 013/409] add github actions check for circular dependencies --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6f4a11acc8d..c08299c584d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,6 +78,9 @@ jobs: - name: Run lint run: yarn run lint + - name: Check for circular dependencies + run: npx madge --exclude '(bitstream|bundle|collection|config-submission-form|eperson|item|version)\.model\.ts$' --circular --extensions ts ./ + - name: Run build run: yarn run build:prod From c5110f89bc17290b6e224f9366cfa14dfa431d58 Mon Sep 17 00:00:00 2001 From: reetagithub <51482276+reetagithub@users.noreply.github.com> Date: Thu, 24 Mar 2022 11:18:18 +0200 Subject: [PATCH 014/409] Update fi.json5 Modified some keys to harmonize the translations of term 'administrative'. Also, translated "Administer Workflow" to a verb instead of a noun. --- src/assets/i18n/fi.json5 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/assets/i18n/fi.json5 b/src/assets/i18n/fi.json5 index 02f020a45d1..860062fa67c 100644 --- a/src/assets/i18n/fi.json5 +++ b/src/assets/i18n/fi.json5 @@ -107,7 +107,7 @@ "admin.registries.bitstream-formats.edit.head": "Tiedostoformaatti: {{ 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": "Sisäisiksi merkittyjä formaatteja käytetään hallinnollisiin tarkoituksiin, ja ne on piilotettu käyttäjiltä.", + "admin.registries.bitstream-formats.edit.internal.hint": "Sisäisiksi merkittyjä formaatteja käytetään ylläpitotarkoituksiin, ja ne on piilotettu käyttäjiltä.", // "admin.registries.bitstream-formats.edit.internal.label": "Internal", "admin.registries.bitstream-formats.edit.internal.label": "Sisäinen", @@ -662,7 +662,7 @@ // "admin.search.breadcrumbs": "Administrative Search", - "admin.search.breadcrumbs": "Hallinnollinen haku", + "admin.search.breadcrumbs": "Ylläpitäjän haku", // "admin.search.collection.edit": "Edit", "admin.search.collection.edit": "Muokkaa", @@ -692,19 +692,19 @@ "admin.search.item.withdraw": "Poista käytöstä", // "admin.search.title": "Administrative Search", - "admin.search.title": "Hallinnollinen haku", + "admin.search.title": "Ylläpitäjän haku", // "administrativeView.search.results.head": "Administrative Search", - "administrativeView.search.results.head": "Hallinnollinen haku", + "administrativeView.search.results.head": "Ylläpitäjän haku", // "admin.workflow.breadcrumbs": "Administer Workflow", - "admin.workflow.breadcrumbs": "Hallinnointityönkulku", + "admin.workflow.breadcrumbs": "Hallinnoi työnkulkua", // "admin.workflow.title": "Administer Workflow", - "admin.workflow.title": "Hallinnointityönkulku", + "admin.workflow.title": "Hallinnoi työnkulkua", // "admin.workflow.item.workflow": "Workflow", "admin.workflow.item.workflow": "Työnkulku", @@ -2954,7 +2954,7 @@ // "menu.section.admin_search": "Admin Search", - "menu.section.admin_search": "Admin-haku", + "menu.section.admin_search": "Ylläpitäjän haku", @@ -3033,7 +3033,7 @@ "menu.section.icon.access_control": "Pääsyoikeudet", // "menu.section.icon.admin_search": "Admin search menu section", - "menu.section.icon.admin_search": "Admin-haku", + "menu.section.icon.admin_search": "Ylläpitäjän haku", // "menu.section.icon.control_panel": "Control Panel menu section", "menu.section.icon.control_panel": "Hallintapaneeli", @@ -3168,7 +3168,7 @@ // "menu.section.workflow": "Administer Workflow", - "menu.section.workflow": "Hallinnointityönkulku", + "menu.section.workflow": "Hallinnoi työnkulkua", // "mydspace.description": "", @@ -5079,7 +5079,7 @@ // "workflowAdmin.search.results.head": "Administer Workflow", - "workflowAdmin.search.results.head": "Hallinnointityönkulku", + "workflowAdmin.search.results.head": "Hallinnoi työnkulkua", From 46a0ea10f40539463abb05fbcbbe1aa8da62f444 Mon Sep 17 00:00:00 2001 From: Pratik Rajkotiya Date: Fri, 25 Mar 2022 18:28:26 +0530 Subject: [PATCH 015/409] [CST-5535] WIP --- src/app/health-page/health.module.ts | 12 +++++++++ src/app/health-page/health.routing.module.ts | 25 ++++++++++++++++++ .../health-page/health/health.component.html | 1 + .../health-page/health/health.component.scss | 0 .../health/health.component.spec.ts | 25 ++++++++++++++++++ .../health-page/health/health.component.ts | 26 +++++++++++++++++++ 6 files changed, 89 insertions(+) create mode 100644 src/app/health-page/health.module.ts create mode 100644 src/app/health-page/health.routing.module.ts create mode 100644 src/app/health-page/health/health.component.html create mode 100644 src/app/health-page/health/health.component.scss create mode 100644 src/app/health-page/health/health.component.spec.ts create mode 100644 src/app/health-page/health/health.component.ts diff --git a/src/app/health-page/health.module.ts b/src/app/health-page/health.module.ts new file mode 100644 index 00000000000..46a66421682 --- /dev/null +++ b/src/app/health-page/health.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { HealthComponent } from './health/health.component'; + + +@NgModule({ + declarations: [ + HealthComponent + ] + }) + export class HealthModule { + + } \ No newline at end of file diff --git a/src/app/health-page/health.routing.module.ts b/src/app/health-page/health.routing.module.ts new file mode 100644 index 00000000000..70ed2a0e432 --- /dev/null +++ b/src/app/health-page/health.routing.module.ts @@ -0,0 +1,25 @@ +import { RouterModule } from '@angular/router'; +import { NgModule } from '@angular/core'; +import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; +import { HealthComponent } from './health/health.component'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { + path: '', + canActivate: [AuthenticatedGuard], + children: [ + { + path: '', + component: HealthComponent, + }, + ] + }, + + ]) + ] +}) +export class HealthPageRoutingModule { + +} diff --git a/src/app/health-page/health/health.component.html b/src/app/health-page/health/health.component.html new file mode 100644 index 00000000000..f96dc0a28f0 --- /dev/null +++ b/src/app/health-page/health/health.component.html @@ -0,0 +1 @@ +

health works!

diff --git a/src/app/health-page/health/health.component.scss b/src/app/health-page/health/health.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/health-page/health/health.component.spec.ts b/src/app/health-page/health/health.component.spec.ts new file mode 100644 index 00000000000..9423481b325 --- /dev/null +++ b/src/app/health-page/health/health.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HealthComponent } from './health.component'; + +describe('HealthComponent', () => { + let component: HealthComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ HealthComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HealthComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/health-page/health/health.component.ts b/src/app/health-page/health/health.component.ts new file mode 100644 index 00000000000..46ff73cc09d --- /dev/null +++ b/src/app/health-page/health/health.component.ts @@ -0,0 +1,26 @@ +import { Component, OnInit } from '@angular/core'; +import { DspaceRestService } from '../../core/dspace-rest/dspace-rest.service'; +import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; + +@Component({ + selector: 'ds-health', + templateUrl: './health.component.html', + styleUrls: ['./health.component.scss'] +}) +export class HealthComponent implements OnInit { + + constructor(protected halService: HALEndpointService, + protected restService: DspaceRestService) { + } + + ngOnInit(): void { + this.halService.getRootHref(); + console.log('this.halService.getRootHref()',); + this.restService.get(this.halService.getRootHref() + '/actuator' + '/health').subscribe((data)=>{ + console.log(data); + + }) + + } + +} From 108f6e60f932e459982e2c8d54b9497d6424c8f5 Mon Sep 17 00:00:00 2001 From: Pratik Rajkotiya Date: Fri, 25 Mar 2022 18:37:25 +0530 Subject: [PATCH 016/409] [CST-5535] WIP --- server.ts | 14 ++++++++++++++ .../admin/admin-sidebar/admin-sidebar.component.ts | 12 ++++++++++++ src/app/app-routing.module.ts | 5 +++++ src/assets/i18n/en.json5 | 2 ++ 4 files changed, 33 insertions(+) diff --git a/server.ts b/server.ts index da3b877bc13..57ab3cb69fa 100644 --- a/server.ts +++ b/server.ts @@ -157,6 +157,20 @@ export function app() { */ server.use('/iiif', express.static(IIIF_VIEWER, {index:false})); + /** + * Checking server status + */ + server.get('/app/health', async (req,res) => { + try { + const serverStatus = await https.get(`${environment.rest.baseUrl}/actuator/health`); + res.send(serverStatus); + } catch (error) { + res.send({ + error: error.message + }); + } + }); + // Register the ngApp callback function to handle incoming requests server.get('*', ngApp); diff --git a/src/app/admin/admin-sidebar/admin-sidebar.component.ts b/src/app/admin/admin-sidebar/admin-sidebar.component.ts index dc9d2a817ff..431a8785da9 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar.component.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar.component.ts @@ -308,6 +308,18 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit { icon: 'terminal', index: 10 }, + { + id: 'health', + active: false, + visible: isSiteAdmin, + model: { + type: MenuItemType.LINK, + text: 'menu.section.health', + link: '/health' + } as LinkMenuItemModel, + icon: 'heartbeat', + index: 11 + }, ]; menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, Object.assign(menuSection, { shouldPersistOnRouteChange: true diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 88f7791b1b2..6456547355c 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -208,6 +208,11 @@ import { ServerCheckGuard } from './core/server-check/server-check.guard'; loadChildren: () => import('./statistics-page/statistics-page-routing.module') .then((m) => m.StatisticsPageRoutingModule) }, + { + path: 'health', + loadChildren: () => import('./health-page/health.routing.module') + .then((m) => m.HealthPageRoutingModule) + }, { path: ACCESS_CONTROL_MODULE_PATH, loadChildren: () => import('./access-control/access-control.module').then((m) => m.AccessControlModule), diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index f33a195cfed..ba0508bdb57 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2543,6 +2543,8 @@ "menu.section.processes": "Processes", + "menu.section.health": "Health", + "menu.section.registries": "Registries", From 392d0e366d3209ef8e50071b5b8a0bba2c6e35bb Mon Sep 17 00:00:00 2001 From: Pratik Rajkotiya Date: Tue, 5 Apr 2022 18:46:58 +0530 Subject: [PATCH 017/409] [CST-5535] test cases added. --- package.json | 1 + src/app/app-routing.module.ts | 4 +- src/app/health-page/health-data.service.ts | 32 ++++ src/app/health-page/health.module.ts | 15 +- src/app/health-page/health.routing.module.ts | 3 + .../health-page/health/health.component.html | 40 ++++- .../health-page/health/health.component.scss | 8 + .../health/health.component.spec.ts | 141 +++++++++++++++++- .../health-page/health/health.component.ts | 98 ++++++++++-- src/assets/i18n/en.json5 | 6 + yarn.lock | 5 + 11 files changed, 333 insertions(+), 20 deletions(-) create mode 100644 src/app/health-page/health-data.service.ts diff --git a/package.json b/package.json index 99ab1d2e079..95f659e9ebb 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "@angular/core": "~11.2.14", "@angular/forms": "~11.2.14", "@angular/localize": "11.2.14", + "@angular/material": "9.2.0", "@angular/platform-browser": "~11.2.14", "@angular/platform-browser-dynamic": "~11.2.14", "@angular/platform-server": "~11.2.14", diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 6456547355c..80310774c8b 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -210,8 +210,8 @@ import { ServerCheckGuard } from './core/server-check/server-check.guard'; }, { path: 'health', - loadChildren: () => import('./health-page/health.routing.module') - .then((m) => m.HealthPageRoutingModule) + loadChildren: () => import('./health-page/health.module') + .then((m) => m.HealthModule) }, { path: ACCESS_CONTROL_MODULE_PATH, diff --git a/src/app/health-page/health-data.service.ts b/src/app/health-page/health-data.service.ts new file mode 100644 index 00000000000..bd905006aa9 --- /dev/null +++ b/src/app/health-page/health-data.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map, switchMap } from 'rxjs/operators'; +import { DspaceRestService } from '../core/dspace-rest/dspace-rest.service'; +import { RawRestResponse } from '../core/dspace-rest/raw-rest-response.model'; +import { HALEndpointService } from '../core/shared/hal-endpoint.service'; + +@Injectable({ + providedIn: 'root' +}) +export class HealthDataService { + constructor(protected halService: HALEndpointService, + protected restService: DspaceRestService) { + } + /** + * @returns health data + */ + getHealth(): Observable { + return this.halService.getEndpoint('/actuator').pipe( + map((restURL: string) => restURL + '/health'), + switchMap((endpoint: string) => this.restService.get(endpoint))); + } + + /** + * @returns information of server + */ + getInfo(): Observable { + return this.halService.getEndpoint('/actuator').pipe( + map((restURL: string) => restURL + '/info'), + switchMap((endpoint: string) => this.restService.get(endpoint))); + } +} diff --git a/src/app/health-page/health.module.ts b/src/app/health-page/health.module.ts index 46a66421682..8731b77f773 100644 --- a/src/app/health-page/health.module.ts +++ b/src/app/health-page/health.module.ts @@ -1,12 +1,23 @@ +import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { HealthPageRoutingModule } from './health.routing.module'; import { HealthComponent } from './health/health.component'; +import { MatExpansionModule } from '@angular/material/expansion'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateModule } from '@ngx-translate/core'; @NgModule({ + imports: [ + CommonModule, + HealthPageRoutingModule, + MatExpansionModule, + NgbModule, + TranslateModule + ], declarations: [ HealthComponent ] }) export class HealthModule { - - } \ No newline at end of file + } diff --git a/src/app/health-page/health.routing.module.ts b/src/app/health-page/health.routing.module.ts index 70ed2a0e432..a8d94d9d1f5 100644 --- a/src/app/health-page/health.routing.module.ts +++ b/src/app/health-page/health.routing.module.ts @@ -2,12 +2,15 @@ import { RouterModule } from '@angular/router'; import { NgModule } from '@angular/core'; import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; import { HealthComponent } from './health/health.component'; +import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; @NgModule({ imports: [ RouterModule.forChild([ { path: '', + resolve: { breadcrumb: I18nBreadcrumbResolver }, + data: { breadcrumbKey: 'health' }, canActivate: [AuthenticatedGuard], children: [ { diff --git a/src/app/health-page/health/health.component.html b/src/app/health-page/health/health.component.html index f96dc0a28f0..05f77225fbb 100644 --- a/src/app/health-page/health/health.component.html +++ b/src/app/health-page/health/health.component.html @@ -1 +1,39 @@ -

health works!

+
+ +
+
+ + + + diff --git a/src/app/health-page/health/health.component.scss b/src/app/health-page/health/health.component.scss index e69de29bb2d..c0851110794 100644 --- a/src/app/health-page/health/health.component.scss +++ b/src/app/health-page/health/health.component.scss @@ -0,0 +1,8 @@ +.mat-expansion-panel-header { + padding-left: 0px; +} + +.circle-red { + color:red; + align-items: center; +} \ No newline at end of file diff --git a/src/app/health-page/health/health.component.spec.ts b/src/app/health-page/health/health.component.spec.ts index 9423481b325..845360f0596 100644 --- a/src/app/health-page/health/health.component.spec.ts +++ b/src/app/health-page/health/health.component.spec.ts @@ -1,14 +1,138 @@ +import { CommonModule } from '@angular/common'; import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { MatExpansionModule } from '@angular/material/expansion'; +import { By } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { of } from 'rxjs'; +import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; +import { HealthDataService } from '../health-data.service'; +import { HealthPageRoutingModule } from '../health.routing.module'; import { HealthComponent } from './health.component'; -describe('HealthComponent', () => { + function getHealth() { + return of({ + 'payload':{ + 'status':'UP_WITH_ISSUES', + 'components':{ + 'db':{ + 'status':'UP', + 'components':{ + 'dataSource':{ + 'status':'UP', + 'details':{ + 'database':'PostgreSQL', + 'result':1, + 'validationQuery':'SELECT 1' + } + }, + 'dspaceDataSource':{ + 'status':'UP', + 'details':{ + 'database':'PostgreSQL', + 'result':1, + 'validationQuery':'SELECT 1' + } + } + } + }, + 'geoIp':{ + 'status':'UP_WITH_ISSUES', + 'details':{ + 'reason':'The GeoLite Database file is missing (/var/lib/GeoIP/GeoLite2-City.mmdb)! Solr Statistics cannot generate location based reports! Please see the DSpace installation instructions for instructions to install this file.' + } + }, + 'solrOaiCore':{ + 'status':'UP', + 'details':{ + 'status':0, + 'detectedPathType':'particular core' + } + }, + 'solrSearchCore':{ + 'status':'UP', + 'details':{ + 'status':0, + 'detectedPathType':'particular core' + } + }, + 'solrStatisticsCore':{ + 'status':'UP', + 'details':{ + 'status':0, + 'detectedPathType':'particular core' + } + } + } + }, + 'statusCode':200, + 'statusText':'OK' + }); + } + + function getInfo() { + return of({ + 'payload':{ + 'app':{ + 'name':'DSpace at My University', + 'version':'7.3', + 'dir':'/Users/pratikrajkotiya/Documents/Project/FrontEnd/dspace-cris-install', + 'url':'http://localhost:8080/server', + 'db':'jdbc:postgresql://localhost:5432/4science', + 'solr':{ + 'server':'http://localhost:8983/solr', + 'prefix':'' + }, + 'mail':{ + 'server':'smtp.example.com', + 'from-address':'dspace-noreply@myu.edu', + 'feedback-recipient':'dspace-help@myu.edu', + 'mail-admin':'dspace-help@myu.edu', + 'mail-helpdesk':'dspace-help@myu.edu', + 'alert-recipient':'dspace-help@myu.edu' + }, + 'cors':{ + 'allowed-origins':'http://localhost:4000' + }, + 'ui':{ + 'url':'http://localhost:4000' + } + } + }, + 'statusCode':200, + 'statusText':'OK' + }); + } + +function getMockHealthDataService() { + return jasmine.createSpyObj('healthDataService', { + getHealth: getHealth(), + getInfo: getInfo() + }); +} + +fdescribe('HealthComponent', () => { let component: HealthComponent; let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ HealthComponent ] + imports: [ + NgbNavModule, + CommonModule, + HealthPageRoutingModule, + MatExpansionModule, + BrowserAnimationsModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }), + ], + declarations: [ HealthComponent ], + providers:[{ provide: HealthDataService, useValue: getMockHealthDataService() }] }) .compileComponents(); }); @@ -22,4 +146,15 @@ describe('HealthComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should render health tab.', () => { + const healthTab = fixture.debugElement.query(By.css('#health')); + expect(healthTab).toBeTruthy(); + }); + + it('should render info tab.', () => { + const infoTab = fixture.debugElement.query(By.css('#info')); + expect(infoTab).toBeFalsy(); + }); + }); diff --git a/src/app/health-page/health/health.component.ts b/src/app/health-page/health/health.component.ts index 46ff73cc09d..89aa6611f65 100644 --- a/src/app/health-page/health/health.component.ts +++ b/src/app/health-page/health/health.component.ts @@ -1,26 +1,100 @@ import { Component, OnInit } from '@angular/core'; -import { DspaceRestService } from '../../core/dspace-rest/dspace-rest.service'; -import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; +import { HealthDataService } from '../health-data.service'; + +enum HealthStatus { + UP = 'UP', + UP_WITH_ISSUES = 'UP_WITH_ISSUES', + DOWN = 'DOWN' +} @Component({ selector: 'ds-health', templateUrl: './health.component.html', styleUrls: ['./health.component.scss'] }) export class HealthComponent implements OnInit { + healthArr: string[]; + serverInfoArr: string[]; + healthGlobalStatus: string; + activeId ='Health'; + constructor(private healthDataService: HealthDataService) { } + + ngOnInit(): void { + this.healthDataService.getHealth().subscribe((data) => { + this.healthArr = this.getHealth(data.payload.components); + this.healthGlobalStatus = data.payload.status; + }); + + this.healthDataService.getInfo().subscribe((data) => { + this.serverInfoArr = this.getInfo(data.payload, null, []); + }); + } + + /** + * @param obj represents a info + * @param key represents a nested key of info + * @param arr represents a key value pair or only key + * @returns {{arr}} of key value pair or only key + */ + getInfo(obj, key, arr) { + if (typeof obj === 'object' && key !== null) { + arr.push({style: {'font-weight': 'bold' ,'font-size.px': key === 'app' ? '30' : '20' }, value: key}); + } + if (typeof obj !== 'object') { + arr.push({style: {'font-size.px': '15'}, value: `${key} = ${obj}`}); + return obj; + } + // tslint:disable-next-line: forin + for (const objKey in obj) { + this.getInfo(obj[objKey], objKey, arr); + } + return arr; + } - constructor(protected halService: HALEndpointService, - protected restService: DspaceRestService) { + /** + * @param subCompObj represent nested sub component + * @param superCompkey represents a key of super component + * @returns linear components array + */ + getHealthSubComponents(subCompObj, superCompkey) { + const subCompArr = []; + // tslint:disable-next-line: forin + for (const key in subCompObj) { + subCompArr.push({ ...subCompObj[key], components: superCompkey + '.' + key }); } + return subCompArr; + } - ngOnInit(): void { - this.halService.getRootHref(); - console.log('this.halService.getRootHref()',); - this.restService.get(this.halService.getRootHref() + '/actuator' + '/health').subscribe((data)=>{ - console.log(data); - - }) - + /** + * @param componentsObj represent health data + * @returns linear components array + */ + getHealth(componentsObj) { + let componentsArr = []; + for (const key in componentsObj) { + if (componentsObj[key].hasOwnProperty('components')) { + componentsArr.push({ ...componentsObj[key], components: key }); + // tslint:disable-next-line: no-string-literal + componentsArr = [...componentsArr, ...this.getHealthSubComponents(componentsObj[key]['components'], key)]; + } else { + componentsArr.push({ ...componentsObj[key], components: key }); + } + } + return componentsArr; + } + + /** + * @param status of perticular block + * @returns {{ string }} class respective status + */ + getHealthIconClass(status: string): string { + if (status === HealthStatus.UP) { + return 'fa fa-check-circle text-success ml-2 mt-1'; + } else if (status === HealthStatus.UP_WITH_ISSUES) { + return 'fa fa-exclamation-triangle text-warning ml-2 mt-1'; + } else { + return 'fa fa-times-circle circle-red ml-2 mt-1'; + } } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index ba0508bdb57..5326c2f84e7 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2909,7 +2909,13 @@ "profile.title": "Update Profile", + "health.breadcrumbs": "Health", + "health-page.health" : "Health", + + "health-page.info" : "Info", + + "health-page.status" : "Status", "project.listelement.badge": "Research Project", diff --git a/yarn.lock b/yarn.lock index 420ff76478c..593dd53d365 100644 --- a/yarn.lock +++ b/yarn.lock @@ -397,6 +397,11 @@ glob "7.1.2" yargs "^16.2.0" +"@angular/material@9.2.0": + version "9.2.0" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-9.2.0.tgz#1b6f0a2e115f93885d7fc2dc4b258d8c9cf6821f" + integrity sha512-KKzEIVh6/m56m+Ao8p4PK0SyEr0574l3VP2swj1qPag3u+FYgemmXCGTaChrKdDsez+zeTCPXImBGXzE6NQ80Q== + "@angular/platform-browser-dynamic@~11.2.14": version "11.2.14" resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-11.2.14.tgz#3c7fff1a1daacba5390acf033d28c377ec281166" From d7c3a20f2a29244a0059dacd1a275256587e3b45 Mon Sep 17 00:00:00 2001 From: Pratik Rajkotiya <“pratik.rajkotiya@4science.com”> Date: Tue, 5 Apr 2022 18:52:40 +0530 Subject: [PATCH 018/409] [CST-5535] remove fdescibe. --- src/app/health-page/health/health.component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/health-page/health/health.component.spec.ts b/src/app/health-page/health/health.component.spec.ts index 845360f0596..4515aef2cb9 100644 --- a/src/app/health-page/health/health.component.spec.ts +++ b/src/app/health-page/health/health.component.spec.ts @@ -112,7 +112,7 @@ function getMockHealthDataService() { }); } -fdescribe('HealthComponent', () => { +describe('HealthComponent', () => { let component: HealthComponent; let fixture: ComponentFixture; From 53c67ac878c37c435f853cbf575dbfb2f0f57cc3 Mon Sep 17 00:00:00 2001 From: lotte Date: Tue, 5 Apr 2022 16:35:24 +0200 Subject: [PATCH 019/409] fixed after merge --- .../submission-accesses-config.service.ts | 2 +- src/app/core/data/entity-type.service.ts | 2 +- .../core/data/item-request-data.service.ts | 5 +- .../core/data/version-data.service.spec.ts | 4 +- .../core/data/version-history-data.service.ts | 8 +-- .../feedback/feedback-data.service.spec.ts | 2 +- src/app/core/shared/item-request.model.ts | 2 +- .../search-configuration.service.spec.ts | 2 +- .../search/search-configuration.service.ts | 12 ++--- src/app/core/shared/search/search.service.ts | 3 -- .../workflowitem-data.service.spec.ts | 4 +- .../submission/workflowitem-data.service.ts | 3 +- .../workspaceitem-data.service.spec.ts | 4 +- .../submission/workspaceitem-data.service.ts | 2 +- .../correlation-id/correlation-id.reducer.ts | 9 +--- .../correlation-id/correlation-id.selector.ts | 3 ++ .../correlation-id/correlation-id.service.ts | 2 +- .../collections/collections.component.spec.ts | 2 +- .../collections/collections.component.ts | 2 +- .../version-page/version-page.component.ts | 5 +- ...-dspace-new-external-dropdown.component.ts | 2 +- ...space-new-submission-dropdown.component.ts | 2 +- src/app/register-page/registration.guard.ts | 4 +- .../deny-request-copy.component.ts | 4 +- .../grant-deny-request-copy.component.ts | 4 +- .../grant-request-copy.component.ts | 4 +- .../collection-dropdown.component.ts | 2 +- ...uthorized-collection-selector.component.ts | 2 +- .../entity-dropdown.component.ts | 2 +- .../methods/oidc/log-in-oidc.component.ts | 2 +- .../models/facet-config-response.model.ts | 3 +- .../models/search-filter-config.model.ts | 2 +- .../shared/search/search.component.spec.ts | 51 ++++++++++--------- src/app/shared/search/search.component.ts | 2 +- 34 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/app/core/config/submission-accesses-config.service.ts b/src/app/core/config/submission-accesses-config.service.ts index de9afc66eab..7c2d2046d9c 100644 --- a/src/app/core/config/submission-accesses-config.service.ts +++ b/src/app/core/config/submission-accesses-config.service.ts @@ -7,7 +7,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { SUBMISSION_ACCESSES_TYPE } from './models/config-type'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; @@ -16,6 +15,7 @@ import { SubmissionAccessesModel } from './models/config-submission-accesses.mod import { RemoteData } from '../data/remote-data'; import { Observable } from 'rxjs'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { CoreState } from '../core-state.model'; /** * Provides methods to retrieve, from REST server, bitstream access conditions configurations applicable during the submission process. diff --git a/src/app/core/data/entity-type.service.ts b/src/app/core/data/entity-type.service.ts index aeeb9a7ac9e..d08e6d28e79 100644 --- a/src/app/core/data/entity-type.service.ts +++ b/src/app/core/data/entity-type.service.ts @@ -9,7 +9,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { Injectable } from '@angular/core'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { filter, map, switchMap, take } from 'rxjs/operators'; import { RemoteData } from './remote-data'; @@ -19,6 +18,7 @@ import { ItemType } from '../shared/item-relationships/item-type.model'; import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../shared/operators'; import { RelationshipTypeService } from './relationship-type.service'; import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * Service handling all ItemType requests diff --git a/src/app/core/data/item-request-data.service.ts b/src/app/core/data/item-request-data.service.ts index 41ad19211a7..2bab0b304fa 100644 --- a/src/app/core/data/item-request-data.service.ts +++ b/src/app/core/data/item-request-data.service.ts @@ -3,7 +3,7 @@ import { Observable } from 'rxjs'; import { distinctUntilChanged, filter, find, map } from 'rxjs/operators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { getFirstCompletedRemoteData, sendRequest } from '../shared/operators'; +import { getFirstCompletedRemoteData } from '../shared/operators'; import { RemoteData } from './remote-data'; import { PostRequest, PutRequest } from './request.models'; import { RequestService } from './request.service'; @@ -11,13 +11,14 @@ import { ItemRequest } from '../shared/item-request.model'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { DataService } from './data.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { RequestCopyEmail } from '../../request-copy/email-request-copy/request-copy-email.model'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; +import { CoreState } from '../core-state.model'; +import { sendRequest } from '../shared/request.operators'; /** * A service responsible for fetching/sending data from/to the REST API on the itemrequests endpoint diff --git a/src/app/core/data/version-data.service.spec.ts b/src/app/core/data/version-data.service.spec.ts index 5a8caf31be4..29de3389d73 100644 --- a/src/app/core/data/version-data.service.spec.ts +++ b/src/app/core/data/version-data.service.spec.ts @@ -9,12 +9,10 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RequestService } from './request.service'; import { PageInfo } from '../shared/page-info.model'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; -import { RequestEntry } from './request.reducer'; import { HrefOnlyDataService } from './href-only-data.service'; import { getMockHrefOnlyDataService } from '../../shared/mocks/href-only-data.service.mock'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { RestResponse } from '../cache/response.models'; import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { Item } from '../shared/item.model'; @@ -22,6 +20,8 @@ import { VersionDataService } from './version-data.service'; import { Version } from '../shared/version.model'; import { VersionHistory } from '../shared/version-history.model'; import { followLink } from '../../shared/utils/follow-link-config.model'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; describe('VersionDataService test', () => { diff --git a/src/app/core/data/version-history-data.service.ts b/src/app/core/data/version-history-data.service.ts index 9bdfc3ec6a0..2769e267704 100644 --- a/src/app/core/data/version-history-data.service.ts +++ b/src/app/core/data/version-history-data.service.ts @@ -9,7 +9,7 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; -import { PostRequest, RestRequest } from './request.models'; +import { PostRequest } from './request.models'; import { Observable, of } from 'rxjs'; import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; import { RemoteData } from './remote-data'; @@ -25,13 +25,15 @@ import { getAllSucceededRemoteData, getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload, - getRemoteDataPayload, - sendRequest + getRemoteDataPayload } from '../shared/operators'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { hasValueOperator } from '../../shared/empty.util'; import { Item } from '../shared/item.model'; import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; +import { sendRequest } from '../shared/request.operators'; +import { RestRequest } from './rest-request.model'; /** * Service responsible for handling requests related to the VersionHistory object diff --git a/src/app/core/feedback/feedback-data.service.spec.ts b/src/app/core/feedback/feedback-data.service.spec.ts index 4bb5e642c20..1462a795876 100644 --- a/src/app/core/feedback/feedback-data.service.spec.ts +++ b/src/app/core/feedback/feedback-data.service.spec.ts @@ -7,9 +7,9 @@ import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { Feedback } from './models/feedback.model'; +import { CoreState } from '../core-state.model'; describe('FeedbackDataService', () => { let service: FeedbackDataService; diff --git a/src/app/core/shared/item-request.model.ts b/src/app/core/shared/item-request.model.ts index 08b65abebfa..35dacc67c41 100644 --- a/src/app/core/shared/item-request.model.ts +++ b/src/app/core/shared/item-request.model.ts @@ -3,8 +3,8 @@ import { typedObject } from '../cache/builders/build-decorators'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { ResourceType } from './resource-type'; import { ITEM_REQUEST } from './item-request.resource-type'; -import { CacheableObject } from '../cache/object-cache.reducer'; import { HALLink } from './hal-link.model'; +import { CacheableObject } from '../cache/cacheable-object.model'; /** * Model class for an ItemRequest diff --git a/src/app/core/shared/search/search-configuration.service.spec.ts b/src/app/core/shared/search/search-configuration.service.spec.ts index caca1b417a3..b21692fb5cb 100644 --- a/src/app/core/shared/search/search-configuration.service.spec.ts +++ b/src/app/core/shared/search/search-configuration.service.spec.ts @@ -9,9 +9,9 @@ import { PaginationServiceStub } from '../../../shared/testing/pagination-servic import { map } from 'rxjs/operators'; import { RemoteData } from '../../data/remote-data'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; -import { SearchObjects } from '../../../shared/search/search-objects.model'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; import { RequestEntry } from '../../data/request-entry.model'; +import { SearchObjects } from '../../../shared/search/models/search-objects.model'; describe('SearchConfigurationService', () => { let service: SearchConfigurationService; diff --git a/src/app/core/shared/search/search-configuration.service.ts b/src/app/core/shared/search/search-configuration.service.ts index 3f6334f7705..eed93ae201c 100644 --- a/src/app/core/shared/search/search-configuration.service.ts +++ b/src/app/core/shared/search/search-configuration.service.ts @@ -2,7 +2,7 @@ import { Injectable, OnDestroy } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; import { BehaviorSubject, combineLatest as observableCombineLatest, merge as observableMerge, Observable, Subscription } from 'rxjs'; -import { filter, map, startWith } from 'rxjs/operators'; +import { filter, map, startWith, take } from 'rxjs/operators'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SearchOptions } from '../../../shared/search/models/search-options.model'; import { PaginatedSearchOptions } from '../../../shared/search/models/paginated-search-options.model'; @@ -15,7 +15,6 @@ import { getAllSucceededRemoteDataPayload, getFirstSucceededRemoteData } from '. import { hasNoValue, hasValue, isNotEmpty, isNotEmptyOperator } from '../../../shared/empty.util'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { SearchConfig, SortConfig } from './search-filters/search-config.model'; -import { SearchService } from './search.service'; import { PaginationService } from '../../pagination/pagination.service'; import { LinkService } from '../../cache/builders/link.service'; import { HALEndpointService } from '../hal-endpoint.service'; @@ -23,12 +22,12 @@ import { RequestService } from '../../data/request.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { GetRequest } from '../../data/request.models'; import { URLCombiner } from '../../url-combiner/url-combiner'; -import { SearchFilterConfig } from '../../../shared/search/search-filter-config.model'; import { GenericConstructor } from '../generic-constructor'; import { ResponseParsingService } from '../../data/parsing.service'; import { FacetConfigResponseParsingService } from '../../data/facet-config-response-parsing.service'; -import { FacetConfigResponse } from '../../../shared/search/facet-config-response.model'; import { ViewMode } from '../view-mode.model'; +import { SearchFilterConfig } from '../../../shared/search/models/search-filter-config.model'; +import { FacetConfigResponse } from '../../../shared/search/models/facet-config-response.model'; /** * Service that performs all actions that have to do with the current search configuration @@ -232,11 +231,10 @@ export class SearchConfigurationService implements OnDestroy { /** * Creates an observable of SearchConfig every time the configuration stream emits. * @param configuration The search configuration - * @param service The search service to use * @param scope The search scope if exists */ - getConfigurationSearchConfig(configuration: string, service: SearchService, scope?: string): Observable { - return service.getSearchConfigurationFor(scope, configuration).pipe( + getConfigurationSearchConfig(configuration: string, scope?: string): Observable { + return this.getSearchConfigurationFor(scope, configuration).pipe( getAllSucceededRemoteDataPayload() ); } diff --git a/src/app/core/shared/search/search.service.ts b/src/app/core/shared/search/search.service.ts index 5ba31c4f8d4..01eabf78975 100644 --- a/src/app/core/shared/search/search.service.ts +++ b/src/app/core/shared/search/search.service.ts @@ -19,7 +19,6 @@ import { SearchFilterConfig } from '../../../shared/search/models/search-filter- import { SearchResponseParsingService } from '../../data/search-response-parsing.service'; import { SearchObjects } from '../../../shared/search/models/search-objects.model'; import { FacetValueResponseParsingService } from '../../data/facet-value-response-parsing.service'; -import { FacetConfigResponseParsingService } from '../../data/facet-config-response-parsing.service'; import { PaginatedSearchOptions } from '../../../shared/search/models/paginated-search-options.model'; import { CommunityDataService } from '../../data/community-data.service'; import { ViewMode } from '../view-mode.model'; @@ -30,9 +29,7 @@ import { RouteService } from '../../services/route.service'; import { SearchResult } from '../../../shared/search/models/search-result.model'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; import { getSearchResultFor } from '../../../shared/search/search-result-element-decorator'; -import { FacetConfigResponse } from '../../../shared/search/models/facet-config-response.model'; import { FacetValues } from '../../../shared/search/models/facet-values.model'; -import { SearchConfig } from './search-filters/search-config.model'; import { PaginationService } from '../../pagination/pagination.service'; import { SearchConfigurationService } from './search-configuration.service'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; diff --git a/src/app/core/submission/workflowitem-data.service.spec.ts b/src/app/core/submission/workflowitem-data.service.spec.ts index 8a5177118da..fb974a9db32 100644 --- a/src/app/core/submission/workflowitem-data.service.spec.ts +++ b/src/app/core/submission/workflowitem-data.service.spec.ts @@ -9,16 +9,16 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RequestService } from '../data/request.service'; import { PageInfo } from '../shared/page-info.model'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; -import { RequestEntry } from '../data/request.reducer'; import { HrefOnlyDataService } from '../data/href-only-data.service'; import { getMockHrefOnlyDataService } from '../../shared/mocks/href-only-data.service.mock'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { RestResponse } from '../cache/response.models'; import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { Item } from '../shared/item.model'; import { WorkflowItemDataService } from './workflowitem-data.service'; import { WorkflowItem } from './models/workflowitem.model'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from '../data/request-entry.model'; describe('WorkflowItemDataService test', () => { let scheduler: TestScheduler; diff --git a/src/app/core/submission/workflowitem-data.service.ts b/src/app/core/submission/workflowitem-data.service.ts index 60fd66ccef7..cc9ceab36c5 100644 --- a/src/app/core/submission/workflowitem-data.service.ts +++ b/src/app/core/submission/workflowitem-data.service.ts @@ -8,7 +8,7 @@ import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; import { WorkflowItem } from './models/workflowitem.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { DeleteByIDRequest, FindListOptions } from '../data/request.models'; +import { DeleteByIDRequest } from '../data/request.models'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; @@ -22,6 +22,7 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { WorkspaceItem } from './models/workspaceitem.model'; import { RequestParam } from '../cache/models/request-param.model'; import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /** * A service that provides methods to make REST requests with workflow items endpoint. diff --git a/src/app/core/submission/workspaceitem-data.service.spec.ts b/src/app/core/submission/workspaceitem-data.service.spec.ts index da7edccda7a..6c2fa15e7c5 100644 --- a/src/app/core/submission/workspaceitem-data.service.spec.ts +++ b/src/app/core/submission/workspaceitem-data.service.spec.ts @@ -9,16 +9,16 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RequestService } from '../data/request.service'; import { PageInfo } from '../shared/page-info.model'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; -import { RequestEntry } from '../data/request.reducer'; import { HrefOnlyDataService } from '../data/href-only-data.service'; import { getMockHrefOnlyDataService } from '../../shared/mocks/href-only-data.service.mock'; import { WorkspaceitemDataService } from './workspaceitem-data.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { RestResponse } from '../cache/response.models'; import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { Item } from '../shared/item.model'; import { WorkspaceItem } from './models/workspaceitem.model'; +import { RequestEntry } from '../data/request-entry.model'; +import { CoreState } from '../core-state.model'; describe('WorkspaceitemDataService test', () => { let scheduler: TestScheduler; diff --git a/src/app/core/submission/workspaceitem-data.service.ts b/src/app/core/submission/workspaceitem-data.service.ts index 516f22e8fd6..1b9782834c0 100644 --- a/src/app/core/submission/workspaceitem-data.service.ts +++ b/src/app/core/submission/workspaceitem-data.service.ts @@ -13,10 +13,10 @@ import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { WorkspaceItem } from './models/workspaceitem.model'; import { Observable } from 'rxjs'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions } from '../data/request.models'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { RequestParam } from '../cache/models/request-param.model'; import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /** * A service that provides methods to make REST requests with workspaceitems endpoint. diff --git a/src/app/correlation-id/correlation-id.reducer.ts b/src/app/correlation-id/correlation-id.reducer.ts index b7525b0b1c4..d18c7bc83e6 100644 --- a/src/app/correlation-id/correlation-id.reducer.ts +++ b/src/app/correlation-id/correlation-id.reducer.ts @@ -1,14 +1,7 @@ -import { - CorrelationIdAction, - CorrelationIDActionTypes, - SetCorrelationIdAction -} from './correlation-id.actions'; -import { AppState } from '../app.reducer'; +import { CorrelationIdAction, CorrelationIDActionTypes, SetCorrelationIdAction } from './correlation-id.actions'; const initialState = null; -export const correlationIdSelector = (state: AppState) => state.correlationId; - /** * Reducer that handles actions to update the correlation ID * @param {string} state the previous correlation ID (null if unset) diff --git a/src/app/correlation-id/correlation-id.selector.ts b/src/app/correlation-id/correlation-id.selector.ts index e69de29bb2d..5dc7fcd4608 100644 --- a/src/app/correlation-id/correlation-id.selector.ts +++ b/src/app/correlation-id/correlation-id.selector.ts @@ -0,0 +1,3 @@ +import { AppState } from '../app.reducer'; + +export const correlationIdSelector = (state: AppState) => state.correlationId; diff --git a/src/app/correlation-id/correlation-id.service.ts b/src/app/correlation-id/correlation-id.service.ts index 6f4b2a53414..b14ea803fea 100644 --- a/src/app/correlation-id/correlation-id.service.ts +++ b/src/app/correlation-id/correlation-id.service.ts @@ -3,10 +3,10 @@ import { UUIDService } from '../core/shared/uuid.service'; import { Store, select } from '@ngrx/store'; import { AppState } from '../app.reducer'; import { isEmpty } from '../shared/empty.util'; -import { correlationIdSelector } from './correlation-id.reducer'; import { take } from 'rxjs/operators'; import { SetCorrelationIdAction } from './correlation-id.actions'; import { Injectable } from '@angular/core'; +import { correlationIdSelector } from './correlation-id.selector'; /** * Service to manage the correlation id, an id used to give context to server side logs diff --git a/src/app/item-page/field-components/collections/collections.component.spec.ts b/src/app/item-page/field-components/collections/collections.component.spec.ts index d5278706da1..c293109ba6f 100644 --- a/src/app/item-page/field-components/collections/collections.component.spec.ts +++ b/src/app/item-page/field-components/collections/collections.component.spec.ts @@ -9,9 +9,9 @@ import { Item } from '../../../core/shared/item.model'; import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { CollectionsComponent } from './collections.component'; -import { FindListOptions } from '../../../core/data/request.models'; import { buildPaginatedList, PaginatedList } from '../../../core/data/paginated-list.model'; import { PageInfo } from '../../../core/shared/page-info.model'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; const createMockCollection = (id: string) => Object.assign(new Collection(), { id: id, diff --git a/src/app/item-page/field-components/collections/collections.component.ts b/src/app/item-page/field-components/collections/collections.component.ts index 23aff801600..5267d176a6f 100644 --- a/src/app/item-page/field-components/collections/collections.component.ts +++ b/src/app/item-page/field-components/collections/collections.component.ts @@ -7,13 +7,13 @@ import { PaginatedList } from '../../../core/data/paginated-list.model'; import { Collection } from '../../../core/shared/collection.model'; import { Item } from '../../../core/shared/item.model'; import { hasValue } from '../../../shared/empty.util'; -import { FindListOptions } from '../../../core/data/request.models'; import { getAllCompletedRemoteData, getAllSucceededRemoteDataPayload, getFirstSucceededRemoteDataPayload, getPaginatedListPayload, } from '../../../core/shared/operators'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; /** * This component renders the parent collections section of the item diff --git a/src/app/item-page/version-page/version-page/version-page.component.ts b/src/app/item-page/version-page/version-page/version-page.component.ts index 0a2021e06d0..7f250343512 100644 --- a/src/app/item-page/version-page/version-page/version-page.component.ts +++ b/src/app/item-page/version-page/version-page/version-page.component.ts @@ -4,12 +4,13 @@ import { RemoteData } from '../../../core/data/remote-data'; import { ActivatedRoute, Router } from '@angular/router'; import { AuthService } from '../../../core/auth/auth.service'; import { map, switchMap } from 'rxjs/operators'; -import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload, redirectOn4xx } from '../../../core/shared/operators'; +import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators'; import { VersionDataService } from '../../../core/data/version-data.service'; import { Version } from '../../../core/shared/version.model'; import { Item } from '../../../core/shared/item.model'; import { getItemPageRoute } from '../../item-page-routing-paths'; import { getPageNotFoundRoute } from '../../../app-routing-paths'; +import { redirectOn4xx } from '../../../core/shared/authorized.operators'; @Component({ selector: 'ds-version-page', @@ -42,7 +43,7 @@ export class VersionPageComponent implements OnInit { switchMap((version) => version.item), redirectOn4xx(this.router, this.authService), getFirstCompletedRemoteData(), - ).subscribe((itemRD) => { + ).subscribe((itemRD: RemoteData) => { if (itemRD.hasNoContent) { this.router.navigateByUrl(getPageNotFoundRoute(), { skipLocationChange: true }); } else { diff --git a/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-external-dropdown/my-dspace-new-external-dropdown.component.ts b/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-external-dropdown/my-dspace-new-external-dropdown.component.ts index 651178e7a1c..012ed22970c 100644 --- a/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-external-dropdown/my-dspace-new-external-dropdown.component.ts +++ b/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-external-dropdown/my-dspace-new-external-dropdown.component.ts @@ -6,10 +6,10 @@ import { map, mergeMap, take } from 'rxjs/operators'; import { EntityTypeService } from '../../../core/data/entity-type.service'; import { ItemType } from '../../../core/shared/item-relationships/item-type.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { hasValue } from '../../../shared/empty.util'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; /** * This component represents the 'Import metadata from external source' dropdown menu diff --git a/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission-dropdown/my-dspace-new-submission-dropdown.component.ts b/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission-dropdown/my-dspace-new-submission-dropdown.component.ts index 0ff363b1644..884970bdf3d 100644 --- a/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission-dropdown/my-dspace-new-submission-dropdown.component.ts +++ b/src/app/my-dspace-page/my-dspace-new-submission/my-dspace-new-submission-dropdown/my-dspace-new-submission-dropdown.component.ts @@ -6,11 +6,11 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { EntityTypeService } from '../../../core/data/entity-type.service'; import { ItemType } from '../../../core/shared/item-relationships/item-type.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { hasValue } from '../../../shared/empty.util'; import { CreateItemParentSelectorComponent } from '../../../shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; /** * This component represents the new submission dropdown diff --git a/src/app/register-page/registration.guard.ts b/src/app/register-page/registration.guard.ts index 36bbfa42520..a0f07d2fbe3 100644 --- a/src/app/register-page/registration.guard.ts +++ b/src/app/register-page/registration.guard.ts @@ -4,8 +4,8 @@ import { Observable } from 'rxjs/internal/Observable'; import { EpersonRegistrationService } from '../core/data/eperson-registration.service'; import { AuthService } from '../core/auth/auth.service'; import { map } from 'rxjs/operators'; -import { getFirstCompletedRemoteData, redirectOn4xx } from '../core/shared/operators'; -import { Location } from '@angular/common'; +import { getFirstCompletedRemoteData } from '../core/shared/operators'; +import { redirectOn4xx } from '../core/shared/authorized.operators'; @Injectable({ providedIn: 'root' diff --git a/src/app/request-copy/deny-request-copy/deny-request-copy.component.ts b/src/app/request-copy/deny-request-copy/deny-request-copy.component.ts index 763319947a6..06c7e2a2f95 100644 --- a/src/app/request-copy/deny-request-copy/deny-request-copy.component.ts +++ b/src/app/request-copy/deny-request-copy/deny-request-copy.component.ts @@ -4,8 +4,7 @@ import { map, switchMap } from 'rxjs/operators'; import { ItemRequest } from '../../core/shared/item-request.model'; import { Observable } from 'rxjs'; import { - getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload, - redirectOn4xx + getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; import { RemoteData } from '../../core/data/remote-data'; import { AuthService } from '../../core/auth/auth.service'; @@ -19,6 +18,7 @@ import { isNotEmpty } from '../../shared/empty.util'; import { ItemRequestDataService } from '../../core/data/item-request-data.service'; import { RequestCopyEmail } from '../email-request-copy/request-copy-email.model'; import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { redirectOn4xx } from '../../core/shared/authorized.operators'; @Component({ selector: 'ds-deny-request-copy', diff --git a/src/app/request-copy/grant-deny-request-copy/grant-deny-request-copy.component.ts b/src/app/request-copy/grant-deny-request-copy/grant-deny-request-copy.component.ts index f9eff05c982..b130c23abed 100644 --- a/src/app/request-copy/grant-deny-request-copy/grant-deny-request-copy.component.ts +++ b/src/app/request-copy/grant-deny-request-copy/grant-deny-request-copy.component.ts @@ -5,8 +5,7 @@ import { ItemRequest } from '../../core/shared/item-request.model'; import { Observable } from 'rxjs'; import { getFirstCompletedRemoteData, - getFirstSucceededRemoteDataPayload, - redirectOn4xx + getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; import { RemoteData } from '../../core/data/remote-data'; import { AuthService } from '../../core/auth/auth.service'; @@ -15,6 +14,7 @@ import { Item } from '../../core/shared/item.model'; import { ItemDataService } from '../../core/data/item-data.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { getItemPageRoute } from '../../item-page/item-page-routing-paths'; +import { redirectOn4xx } from '../../core/shared/authorized.operators'; @Component({ selector: 'ds-grant-deny-request-copy', diff --git a/src/app/request-copy/grant-request-copy/grant-request-copy.component.ts b/src/app/request-copy/grant-request-copy/grant-request-copy.component.ts index 3b8ec8f7350..ee2e5f08cc4 100644 --- a/src/app/request-copy/grant-request-copy/grant-request-copy.component.ts +++ b/src/app/request-copy/grant-request-copy/grant-request-copy.component.ts @@ -4,8 +4,7 @@ import { map, switchMap } from 'rxjs/operators'; import { ItemRequest } from '../../core/shared/item-request.model'; import { Observable } from 'rxjs'; import { - getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload, - redirectOn4xx + getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; import { RemoteData } from '../../core/data/remote-data'; import { AuthService } from '../../core/auth/auth.service'; @@ -19,6 +18,7 @@ import { isNotEmpty } from '../../shared/empty.util'; import { ItemRequestDataService } from '../../core/data/item-request-data.service'; import { RequestCopyEmail } from '../email-request-copy/request-copy-email.model'; import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { redirectOn4xx } from '../../core/shared/authorized.operators'; @Component({ selector: 'ds-grant-request-copy', diff --git a/src/app/shared/collection-dropdown/collection-dropdown.component.ts b/src/app/shared/collection-dropdown/collection-dropdown.component.ts index 192ae196a9f..85cd1820688 100644 --- a/src/app/shared/collection-dropdown/collection-dropdown.component.ts +++ b/src/app/shared/collection-dropdown/collection-dropdown.component.ts @@ -22,7 +22,7 @@ import { CollectionDataService } from '../../core/data/collection-data.service'; import { Collection } from '../../core/shared/collection.model'; import { followLink } from '../utils/follow-link-config.model'; import { - getFirstCompletedRemoteData, + getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload, getFirstSucceededRemoteWithNotEmptyData } from '../../core/shared/operators'; import { FindListOptions } from '../../core/data/find-list-options.model'; diff --git a/src/app/shared/dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component.ts b/src/app/shared/dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component.ts index 44ac27515d2..ab48d058ca6 100644 --- a/src/app/shared/dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component.ts @@ -15,8 +15,8 @@ import { hasValue } from '../../../empty.util'; import { NotificationsService } from '../../../notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { Collection } from '../../../../core/shared/collection.model'; -import { FindListOptions } from '../../../../core/data/request.models'; import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; @Component({ selector: 'ds-authorized-collection-selector', diff --git a/src/app/shared/entity-dropdown/entity-dropdown.component.ts b/src/app/shared/entity-dropdown/entity-dropdown.component.ts index 13d50a8b79e..f4068b1abc6 100644 --- a/src/app/shared/entity-dropdown/entity-dropdown.component.ts +++ b/src/app/shared/entity-dropdown/entity-dropdown.component.ts @@ -13,11 +13,11 @@ import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { hasValue } from '../empty.util'; import { reduce, startWith, switchMap } from 'rxjs/operators'; import { RemoteData } from '../../core/data/remote-data'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { EntityTypeService } from '../../core/data/entity-type.service'; import { ItemType } from '../../core/shared/item-relationships/item-type.model'; import { getFirstSucceededRemoteWithNotEmptyData } from '../../core/shared/operators'; +import { FindListOptions } from '../../core/data/find-list-options.model'; @Component({ selector: 'ds-entity-dropdown', diff --git a/src/app/shared/log-in/methods/oidc/log-in-oidc.component.ts b/src/app/shared/log-in/methods/oidc/log-in-oidc.component.ts index 8253a1aabfa..38cedf91ec1 100644 --- a/src/app/shared/log-in/methods/oidc/log-in-oidc.component.ts +++ b/src/app/shared/log-in/methods/oidc/log-in-oidc.component.ts @@ -7,7 +7,6 @@ import { renderAuthMethodFor } from '../log-in.methods-decorator'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; import { AuthMethod } from '../../../../core/auth/models/auth.method'; -import { CoreState } from '../../../../core/core.reducers'; import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors'; import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service'; import { isNotNull, isEmpty } from '../../../empty.util'; @@ -15,6 +14,7 @@ import { AuthService } from '../../../../core/auth/auth.service'; import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; import { take } from 'rxjs/operators'; import { URLCombiner } from '../../../../core/url-combiner/url-combiner'; +import { CoreState } from '../../../../core/core-state.model'; @Component({ selector: 'ds-log-in-oidc', diff --git a/src/app/shared/search/models/facet-config-response.model.ts b/src/app/shared/search/models/facet-config-response.model.ts index 15a318a98d2..deb86def225 100644 --- a/src/app/shared/search/models/facet-config-response.model.ts +++ b/src/app/shared/search/models/facet-config-response.model.ts @@ -1,11 +1,10 @@ -import { CacheableObject } from '../../../core/cache/object-cache.reducer'; import { typedObject } from '../../../core/cache/builders/build-decorators'; import { FACET_CONFIG_RESPONSE } from './types/facet-config-response.resouce-type'; import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; import { SearchFilterConfig } from './search-filter-config.model'; import { deserialize } from 'cerialize'; import { HALLink } from '../../../core/shared/hal-link.model'; -import { CacheableObject } from '../../core/cache/cacheable-object.model'; +import { CacheableObject } from '../../../core/cache/cacheable-object.model'; /** * The response from the discover/facets endpoint diff --git a/src/app/shared/search/models/search-filter-config.model.ts b/src/app/shared/search/models/search-filter-config.model.ts index 129259985ab..59512ee29da 100644 --- a/src/app/shared/search/models/search-filter-config.model.ts +++ b/src/app/shared/search/models/search-filter-config.model.ts @@ -2,9 +2,9 @@ import { FilterType } from './filter-type.model'; import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; import { HALLink } from '../../../core/shared/hal-link.model'; import { typedObject } from '../../../core/cache/builders/build-decorators'; -import { CacheableObject } from '../../../core/cache/object-cache.reducer'; import { excludeFromEquals } from '../../../core/utilities/equals.decorators'; import { SEARCH_FILTER_CONFIG } from './types/search-filter-config.resource-type'; +import { CacheableObject } from '../../../core/cache/cacheable-object.model'; /** * The configuration for a search filter diff --git a/src/app/shared/search/search.component.spec.ts b/src/app/shared/search/search.component.spec.ts index 11b0293e6ca..d4561b7c584 100644 --- a/src/app/shared/search/search.component.spec.ts +++ b/src/app/shared/search/search.component.spec.ts @@ -147,18 +147,28 @@ const routeServiceStub = { } }; - -const searchConfigurationServiceStub = jasmine.createSpyObj('SearchConfigurationService', { - getConfigurationSortOptions: jasmine.createSpy('getConfigurationSortOptions'), - getConfigurationSearchConfig: jasmine.createSpy('getConfigurationSearchConfig'), - getCurrentConfiguration: jasmine.createSpy('getCurrentConfiguration'), - getCurrentScope: jasmine.createSpy('getCurrentScope'), - getCurrentSort: jasmine.createSpy('getCurrentSort'), - updateFixedFilter: jasmine.createSpy('updateFixedFilter'), - setPaginationId: jasmine.createSpy('setPaginationId') -}, ['paginatedSearchOptions']); +let searchConfigurationServiceStub; export function configureSearchComponentTestingModule(compType, additionalDeclarations: any[] = []) { + searchConfigurationServiceStub = jasmine.createSpyObj('SearchConfigurationService', { + getConfigurationSortOptions: sortOptionsList, + getConfigurationSearchConfig: observableOf(searchConfig), + getCurrentConfiguration: observableOf('default'), + getCurrentScope: observableOf('test-id'), + getCurrentSort: observableOf(sortOptionsList[0]), + updateFixedFilter: jasmine.createSpy('updateFixedFilter'), + setPaginationId: jasmine.createSpy('setPaginationId') + }); + + searchConfigurationServiceStub.setPaginationId.and.callFake((pageId) => { + paginatedSearchOptions$.next(Object.assign(paginatedSearchOptions$.value, { + pagination: Object.assign(new PaginationComponentOptions(), { + id: pageId + }) + })); + }); + searchConfigurationServiceStub.paginatedSearchOptions = new BehaviorSubject(new PaginatedSearchOptions({pagination: {id: 'default'} as any})); + TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule, NgbCollapseModule], declarations: [compType, ...additionalDeclarations], @@ -196,7 +206,14 @@ export function configureSearchComponentTestingModule(compType, additionalDeclar ], schemas: [NO_ERRORS_SCHEMA] }).overrideComponent(compType, { - set: { changeDetection: ChangeDetectionStrategy.Default } + set: { + changeDetection: ChangeDetectionStrategy.Default, + providers: [{ + provide: SearchConfigurationService, + useValue: searchConfigurationServiceStub + }] + }, + }).compileComponents(); } @@ -211,18 +228,6 @@ describe('SearchComponent', () => { comp.inPlaceSearch = false; comp.paginationId = paginationId; - searchConfigurationServiceStub.getConfigurationSearchConfig.and.returnValue(observableOf(searchConfig)); - searchConfigurationServiceStub.getConfigurationSortOptions.and.returnValue(sortOptionsList); - searchConfigurationServiceStub.getCurrentConfiguration.and.returnValue(observableOf('default')); - searchConfigurationServiceStub.getCurrentScope.and.returnValue(observableOf('test-id')); - searchConfigurationServiceStub.getCurrentSort.and.returnValue(observableOf(sortOptionsList[0])); - searchConfigurationServiceStub.setPaginationId.and.callFake((pageId) => { - paginatedSearchOptions$.next(Object.assign(paginatedSearchOptions$.value, { - pagination: Object.assign(new PaginationComponentOptions(), { - id: pageId - }) - })); - }); spyOn((comp as any), 'getSearchOptions').and.returnValue(paginatedSearchOptions$.asObservable()); searchServiceObject = TestBed.inject(SearchService); diff --git a/src/app/shared/search/search.component.ts b/src/app/shared/search/search.component.ts index 0fd59346f8e..e660b4bd3cb 100644 --- a/src/app/shared/search/search.component.ts +++ b/src/app/shared/search/search.component.ts @@ -254,7 +254,7 @@ export class SearchComponent implements OnInit { .getCurrentConfiguration(this.configuration).pipe(distinctUntilChanged()); const searchSortOptions$: Observable = configuration$.pipe( switchMap((configuration: string) => this.searchConfigService - .getConfigurationSearchConfig(configuration, this.service)), + .getConfigurationSearchConfig(configuration)), map((searchConfig: SearchConfig) => this.searchConfigService.getConfigurationSortOptions(searchConfig)), distinctUntilChanged() ); From 6d3ef58ecc0044a5b05034746bc30a3ae65d812d Mon Sep 17 00:00:00 2001 From: lotte Date: Tue, 5 Apr 2022 17:27:45 +0200 Subject: [PATCH 020/409] Removed unused imports --- src/app/core/data/request.effects.ts | 1 - .../collection-dropdown/collection-dropdown.component.ts | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index b297ca6692a..99f3a0391ad 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -19,7 +19,6 @@ import { import { RequestService } from './request.service'; import { ParsedResponse } from '../cache/response.models'; import { RequestError } from './request-error.model'; -import { RestRequest } from './rest-request.model'; import { RestRequestWithResponseParser } from './rest-request-with-response-parser.model'; import { RequestEntry } from './request-entry.model'; diff --git a/src/app/shared/collection-dropdown/collection-dropdown.component.ts b/src/app/shared/collection-dropdown/collection-dropdown.component.ts index 85cd1820688..10a673c7f29 100644 --- a/src/app/shared/collection-dropdown/collection-dropdown.component.ts +++ b/src/app/shared/collection-dropdown/collection-dropdown.component.ts @@ -22,8 +22,7 @@ import { CollectionDataService } from '../../core/data/collection-data.service'; import { Collection } from '../../core/shared/collection.model'; import { followLink } from '../utils/follow-link-config.model'; import { - getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload, - getFirstSucceededRemoteWithNotEmptyData + getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; import { FindListOptions } from '../../core/data/find-list-options.model'; From 06f1cc2d82dfc1abd87ccdcbb5f5a4172f02025d Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 7 Apr 2022 13:59:40 +0300 Subject: [PATCH 021/409] 88300: Fix wrong message key --- src/app/shared/pagination/pagination.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/pagination/pagination.component.html b/src/app/shared/pagination/pagination.component.html index 60e63a9c6f8..f5f329c6fd7 100644 --- a/src/app/shared/pagination/pagination.component.html +++ b/src/app/shared/pagination/pagination.component.html @@ -44,7 +44,7 @@ From ddca6701ac7c71d4d0aaa1360bad25e8d825690e Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 7 Apr 2022 15:02:41 +0300 Subject: [PATCH 022/409] Update messages for different browse options --- .../browse-by-metadata-page.component.html | 8 +- .../browse-by-metadata-page.component.ts | 1 + src/assets/config.json | 223 ++++++++++++++++++ src/assets/i18n/en.json5 | 8 +- 4 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 src/assets/config.json diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html index 2321da02041..fdc7678bcc2 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html @@ -24,7 +24,13 @@
diff --git a/src/app/item-page/full/full-item-page.component.ts b/src/app/item-page/full/full-item-page.component.ts index 99cf083bc5d..369769c77d1 100644 --- a/src/app/item-page/full/full-item-page.component.ts +++ b/src/app/item-page/full/full-item-page.component.ts @@ -16,10 +16,6 @@ import { hasValue } from '../../shared/empty.util'; import { AuthService } from '../../core/auth/auth.service'; import { Location } from '@angular/common'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; -import { TranslateService } from '@ngx-translate/core'; -import { NotificationsService } from '../../shared/notifications/notifications.service'; -import { ResearcherProfileService } from '../../core/profile/researcher-profile.service'; -import { CollectionDataService } from '../../core/data/collection-data.service'; /** @@ -52,11 +48,8 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit, items: ItemDataService, authService: AuthService, authorizationService: AuthorizationDataService, - translate: TranslateService, - notificationsService: NotificationsService, - researcherProfileService: ResearcherProfileService, private _location: Location) { - super(route, router, items, authService, authorizationService, translate, notificationsService, researcherProfileService); + super(route, router, items, authService, authorizationService); } /*** AoT inheritance fix, will hopefully be resolved in the near future **/ diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index 34a059246d6..b3660eb9d76 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -64,24 +64,13 @@ export class ItemPageComponent implements OnInit { itemUrl: string; - public claimable$: BehaviorSubject = new BehaviorSubject(false); - public isProcessing$: BehaviorSubject = new BehaviorSubject(false); - constructor( protected route: ActivatedRoute, private router: Router, private items: ItemDataService, private authService: AuthService, - private authorizationService: AuthorizationDataService, - private translate: TranslateService, - private notificationsService: NotificationsService, - private researcherProfileService: ResearcherProfileService + private authorizationService: AuthorizationDataService ) { - this.route.data.pipe( - map((data) => data.dso as RemoteData) - ).subscribe((data: RemoteData) => { - this.itemUrl = data?.payload?.self; - }); } /** @@ -99,55 +88,5 @@ export class ItemPageComponent implements OnInit { this.isAdmin$ = this.authorizationService.isAuthorized(FeatureID.AdministratorOf); - this.authorizationService.isAuthorized(FeatureID.ShowClaimItem, this.itemUrl).pipe( - take(1) - ).subscribe((isAuthorized: boolean) => { - this.claimable$.next(isAuthorized); - }); - } - - claim() { - this.isProcessing$.next(true); - - this.authorizationService.isAuthorized(FeatureID.CanClaimItem, this.itemUrl).pipe( - take(1) - ).subscribe((isAuthorized: boolean) => { - if (!isAuthorized) { - this.notificationsService.warning(this.translate.get('researcherprofile.claim.not-authorized')); - this.isProcessing$.next(false); - } else { - this.createFromExternalSource(); - } - }); - - } - - createFromExternalSource() { - this.researcherProfileService.createFromExternalSource(this.itemUrl).pipe( - tap((rd: any) => { - if (!rd.hasSucceeded) { - this.isProcessing$.next(false); - } - }), - getFirstSucceededRemoteData(), - mergeMap((rd: RemoteData) => { - return this.researcherProfileService.findRelatedItemId(rd.payload); - })) - .subscribe((id: string) => { - if (isNotUndefined(id)) { - this.notificationsService.success(this.translate.get('researcherprofile.success.claim.title'), - this.translate.get('researcherprofile.success.claim.body')); - this.claimable$.next(false); - this.isProcessing$.next(false); - } else { - this.notificationsService.error( - this.translate.get('researcherprofile.error.claim.title'), - this.translate.get('researcherprofile.error.claim.body')); - } - }); - } - - isClaimable(): Observable { - return this.claimable$; } } diff --git a/src/app/item-page/simple/item-types/shared/item.component.spec.ts b/src/app/item-page/simple/item-types/shared/item.component.spec.ts index fc07f60b28d..6f7684b8965 100644 --- a/src/app/item-page/simple/item-types/shared/item.component.spec.ts +++ b/src/app/item-page/simple/item-types/shared/item.component.spec.ts @@ -4,7 +4,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { Store } from '@ngrx/store'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; +import {Observable, of as observableOf} from 'rxjs'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../../../../core/cache/object-cache.service'; import { BitstreamDataService } from '../../../../core/data/bitstream-data.service'; @@ -32,6 +32,8 @@ import { ItemComponent } from './item.component'; import { createPaginatedList } from '../../../../shared/testing/utils.test'; import { RouteService } from '../../../../core/services/route.service'; import { MetadataValue } from '../../../../core/shared/metadata.models'; +import {AuthorizationDataService} from '../../../../core/data/feature-authorization/authorization-data.service'; +import {ResearcherProfileService} from '../../../../core/profile/researcher-profile.service'; export const iiifEnabled = Object.assign(new MetadataValue(),{ 'value': 'true', @@ -69,6 +71,11 @@ export function getItemPageFieldsTest(mockItem: Item, component) { return createSuccessfulRemoteDataObject$(new Bitstream()); } }; + + const authorizationService = jasmine.createSpyObj('authorizationService', { + isAuthorized: observableOf(true) + }); + TestBed.configureTestingModule({ imports: [TranslateModule.forRoot({ loader: { @@ -92,7 +99,9 @@ export function getItemPageFieldsTest(mockItem: Item, component) { { provide: NotificationsService, useValue: {} }, { provide: DefaultChangeAnalyzer, useValue: {} }, { provide: BitstreamDataService, useValue: mockBitstreamDataService }, - { provide: RouteService, useValue: {} } + { provide: RouteService, useValue: {} }, + { provide: AuthorizationDataService, useValue: authorizationService }, + { provide: ResearcherProfileService, useValue: {} } ], schemas: [NO_ERRORS_SCHEMA] 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 b2d53ea0e3c..bb554187446 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 @@ -9,7 +9,7 @@

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

- - diff --git a/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts b/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts index 355d328f3f8..5238482770d 100644 --- a/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts +++ b/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts @@ -17,6 +17,7 @@ import { storeModuleConfig } from '../../../../app.reducer'; import { AuthMethod } from '../../../../core/auth/models/auth.method'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; +import { BrowserOnlyMockPipe } from '../../../testing/browser-only-mock.pipe'; describe('LogInPasswordComponent', () => { @@ -57,7 +58,8 @@ describe('LogInPasswordComponent', () => { TranslateModule.forRoot() ], declarations: [ - LogInPasswordComponent + LogInPasswordComponent, + BrowserOnlyMockPipe, ], providers: [ { provide: AuthService, useClass: AuthServiceStub }, diff --git a/src/app/shared/log-out/log-out.component.html b/src/app/shared/log-out/log-out.component.html index 9151cb0c2d1..83e58b3841b 100644 --- a/src/app/shared/log-out/log-out.component.html +++ b/src/app/shared/log-out/log-out.component.html @@ -2,5 +2,5 @@ - +
diff --git a/src/app/shared/log-out/log-out.component.spec.ts b/src/app/shared/log-out/log-out.component.spec.ts index f15203ed8b7..028738a019c 100644 --- a/src/app/shared/log-out/log-out.component.spec.ts +++ b/src/app/shared/log-out/log-out.component.spec.ts @@ -12,6 +12,7 @@ import { Router } from '@angular/router'; import { AppState } from '../../app.reducer'; import { LogOutComponent } from './log-out.component'; import { RouterStub } from '../testing/router.stub'; +import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe'; describe('LogOutComponent', () => { @@ -46,7 +47,8 @@ describe('LogOutComponent', () => { TranslateModule.forRoot() ], declarations: [ - LogOutComponent + LogOutComponent, + BrowserOnlyMockPipe, ], providers: [ { provide: Router, useValue: routerStub }, diff --git a/src/app/shared/object-grid/object-grid.component.html b/src/app/shared/object-grid/object-grid.component.html index 07dbcec8059..c988e768032 100644 --- a/src/app/shared/object-grid/object-grid.component.html +++ b/src/app/shared/object-grid/object-grid.component.html @@ -18,7 +18,7 @@ >
-
+
diff --git a/src/app/shared/object-list/object-list.component.html b/src/app/shared/object-list/object-list.component.html index 492cb4cf077..927f2b9d2ae 100644 --- a/src/app/shared/object-list/object-list.component.html +++ b/src/app/shared/object-list/object-list.component.html @@ -17,7 +17,7 @@ (next)="goNext()" >
    -
  • +
- - +
diff --git a/src/app/shared/search-form/search-form.component.spec.ts b/src/app/shared/search-form/search-form.component.spec.ts index 934f00b10ce..84c61f569b8 100644 --- a/src/app/shared/search-form/search-form.component.spec.ts +++ b/src/app/shared/search-form/search-form.component.spec.ts @@ -14,6 +14,7 @@ import { PaginationServiceStub } from '../testing/pagination-service.stub'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe'; describe('SearchFormComponent', () => { let comp: SearchFormComponent; @@ -37,7 +38,10 @@ describe('SearchFormComponent', () => { { provide: SearchConfigurationService, useValue: searchConfigService }, { provide: DSpaceObjectDataService, useValue: { findById: () => createSuccessfulRemoteDataObject$(undefined)} } ], - declarations: [SearchFormComponent] + declarations: [ + SearchFormComponent, + BrowserOnlyMockPipe, + ] }).compileComponents(); })); 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 230f0727724..452433e165f 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 @@ -4,6 +4,7 @@ class="filter-name d-flex" [attr.aria-controls]="regionId" [id]="toggleId" [attr.aria-expanded]="false" [attr.aria-label]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate" + [attr.data-test]="'filter-toggle' | dsBrowserOnly" >
{{'search.filters.filter.' + filter.name + '.head'| translate}} diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts index 662b380ce88..7abe45ca8c7 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts @@ -13,6 +13,7 @@ import { FilterType } from '../../models/filter-type.model'; import { SearchConfigurationServiceStub } from '../../../testing/search-configuration-service.stub'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { SequenceService } from '../../../../core/shared/sequence.service'; +import { BrowserOnlyMockPipe } from '../../../testing/browser-only-mock.pipe'; describe('SearchFilterComponent', () => { let comp: SearchFilterComponent; @@ -62,7 +63,10 @@ describe('SearchFilterComponent', () => { TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule], - declarations: [SearchFilterComponent], + declarations: [ + SearchFilterComponent, + BrowserOnlyMockPipe, + ], providers: [ { provide: SearchService, useValue: searchServiceStub }, { diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 37f4fafb1ee..2388c2f13e2 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -173,7 +173,7 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component'; - +import { BrowserOnlyPipe } from './utils/browser-only.pipe'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here CommonModule, @@ -215,7 +215,8 @@ const PIPES = [ ObjectKeysPipe, ObjectValuesPipe, ConsolePipe, - ObjNgFor + ObjNgFor, + BrowserOnlyPipe, ]; const COMPONENTS = [ diff --git a/src/app/shared/sidebar/filter/sidebar-filter.component.html b/src/app/shared/sidebar/filter/sidebar-filter.component.html index bd392aa715d..79afaa7583c 100644 --- a/src/app/shared/sidebar/filter/sidebar-filter.component.html +++ b/src/app/shared/sidebar/filter/sidebar-filter.component.html @@ -1,5 +1,5 @@
-
+
{{ label | translate }}
diff --git a/src/app/shared/testing/browser-only-mock.pipe.ts b/src/app/shared/testing/browser-only-mock.pipe.ts new file mode 100644 index 00000000000..12e5a7b2d74 --- /dev/null +++ b/src/app/shared/testing/browser-only-mock.pipe.ts @@ -0,0 +1,13 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +/** + * Support dsBrowserOnly in unit tests. + */ +@Pipe({ + name: 'dsBrowserOnly' +}) +export class BrowserOnlyMockPipe implements PipeTransform { + transform(value: string): string | undefined { + return value; + } +} diff --git a/src/app/shared/testing/test-module.ts b/src/app/shared/testing/test-module.ts index b43adde8ae7..7d45dd41f33 100644 --- a/src/app/shared/testing/test-module.ts +++ b/src/app/shared/testing/test-module.ts @@ -5,6 +5,7 @@ import { SharedModule } from '../shared.module'; import { NgComponentOutletDirectiveStub } from './ng-component-outlet-directive.stub'; import { QueryParamsDirectiveStub } from './query-params-directive.stub'; import { RouterLinkDirectiveStub } from './router-link-directive.stub'; +import { BrowserOnlyMockPipe } from './browser-only-mock.pipe'; /** * This module isn't used. It serves to prevent the AoT compiler @@ -21,7 +22,8 @@ import { RouterLinkDirectiveStub } from './router-link-directive.stub'; QueryParamsDirectiveStub, MySimpleItemActionComponent, RouterLinkDirectiveStub, - NgComponentOutletDirectiveStub + NgComponentOutletDirectiveStub, + BrowserOnlyMockPipe, ], exports: [ QueryParamsDirectiveStub diff --git a/src/app/shared/utils/browser-only.pipe.ts b/src/app/shared/utils/browser-only.pipe.ts new file mode 100644 index 00000000000..fc95bfda22e --- /dev/null +++ b/src/app/shared/utils/browser-only.pipe.ts @@ -0,0 +1,24 @@ +import { Inject, Pipe, PipeTransform, PLATFORM_ID } from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; + +/** + * A pipe that only returns its intput when run in the browser. + * Used to distinguish client-side rendered content from server-side rendered content. + */ +@Pipe({ + name: 'dsBrowserOnly' +}) +export class BrowserOnlyPipe implements PipeTransform { + constructor( + @Inject(PLATFORM_ID) private platformID: any, + ) { + } + + transform(value: string): string | undefined { + if (isPlatformBrowser((this.platformID))) { + return value; + } else { + return undefined; + } + } +} diff --git a/src/app/shared/view-mode-switch/view-mode-switch.component.html b/src/app/shared/view-mode-switch/view-mode-switch.component.html index 2863a4832b2..5f70bc699ce 100644 --- a/src/app/shared/view-mode-switch/view-mode-switch.component.html +++ b/src/app/shared/view-mode-switch/view-mode-switch.component.html @@ -7,7 +7,7 @@ routerLinkActive="active" [class.active]="currentMode === viewModeEnum.ListElement" class="btn btn-secondary" - data-test="list-view"> + [attr.data-test]="'list-view' | dsBrowserOnly"> + [attr.data-test]="'grid-view' | dsBrowserOnly"> + [attr.data-test]="'detail-view' | dsBrowserOnly">
diff --git a/src/app/shared/view-mode-switch/view-mode-switch.component.spec.ts b/src/app/shared/view-mode-switch/view-mode-switch.component.spec.ts index d3618574137..5780ea5cf36 100644 --- a/src/app/shared/view-mode-switch/view-mode-switch.component.spec.ts +++ b/src/app/shared/view-mode-switch/view-mode-switch.component.spec.ts @@ -9,6 +9,7 @@ import { SearchService } from '../../core/shared/search/search.service'; import { ViewModeSwitchComponent } from './view-mode-switch.component'; import { SearchServiceStub } from '../testing/search-service.stub'; import { ViewMode } from '../../core/shared/view-mode.model'; +import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe'; @Component({ template: '' }) class DummyComponent { @@ -36,7 +37,8 @@ describe('ViewModeSwitchComponent', () => { ], declarations: [ ViewModeSwitchComponent, - DummyComponent + DummyComponent, + BrowserOnlyMockPipe, ], providers: [ { provide: SearchService, useValue: searchService }, 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 7013c556676..e898e1c2207 100644 --- a/src/app/submission/form/footer/submission-form-footer.component.html +++ b/src/app/submission/form/footer/submission-form-footer.component.html @@ -3,6 +3,7 @@ +
+
+ + + +
+ +
+
+
+
+ +
- diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.scss b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.scss new file mode 100644 index 00000000000..c3694e67847 --- /dev/null +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.scss @@ -0,0 +1,4 @@ +.auth-bitstream-container { + margin-top: -1em; + margin-bottom: 1.5em; +} diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index 76597a135bb..f3313d4cef3 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -1,3 +1,5 @@ +import { isEqual } from 'lodash'; +import { DSONameService } from './../../../core/breadcrumbs/dso-name.service'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @@ -25,7 +27,8 @@ interface BundleBitstreamsMapEntry { @Component({ selector: 'ds-item-authorizations', - templateUrl: './item-authorizations.component.html' + templateUrl: './item-authorizations.component.html', + styleUrls:['./item-authorizations.component.scss'] }) /** * Component that handles the item Authorizations @@ -36,14 +39,20 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * A map that contains all bitstream of the item's bundles * @type {Observable>>>} */ - public bundleBitstreamsMap: Map>> = new Map>>(); + public bundleBitstreamsMap: Map = new Map(); /** - * The list of bundle for the item + * The list of all bundles for the item * @type {Observable>} */ private bundles$: BehaviorSubject = new BehaviorSubject([]); + /** + * The list of bundles to be displayed in the template + * @type {BehaviorSubject} + */ + bundlesToShow$: BehaviorSubject = new BehaviorSubject([]); + /** * The target editing item * @type {Observable} @@ -56,6 +65,37 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { */ private subs: Subscription[] = []; + /** + * The size of the bundles to be loaded on demand + * @type {number} + */ + bunblesPerPage = 6; + + /** + * The number of current page + * @type {number} + */ + bunblesPageSize = 1; + + /** + * The flag to show or not the 'Load more' button + * based on the condition if all the bundles are loaded or not + * @type {boolean} + */ + allBundlesLoaded = false; + + /** + * Initial size of loaded bitstreams + * The size of incrementation used in bitstream pagination + */ + bitstreamSize = 4; + + /** + * The size of the loaded bitstremas at a certain moment + * @private + */ + private bitstreamPageSize = 4; + /** * Initialize instance variables * @@ -64,7 +104,8 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { */ constructor( private linkService: LinkService, - private route: ActivatedRoute + private route: ActivatedRoute, + private nameService: DSONameService ) { } @@ -72,16 +113,53 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * Initialize the component, setting up the bundle and bitstream within the item */ ngOnInit(): void { + this.getBundlesPerItem(); + } + + /** + * Return the item's UUID + */ + getItemUUID(): Observable { + return this.item$.pipe( + map((item: Item) => item.id), + first((UUID: string) => isNotEmpty(UUID)) + ); + } + + /** + * Return the item's name + */ + getItemName(): Observable { + return this.item$.pipe( + map((item: Item) => this.nameService.getName(item)) + ); + } + + /** + * Return all item's bundles + * + * @return an observable that emits all item's bundles + */ + getItemBundles(): Observable { + return this.bundles$.asObservable(); + } + + /** + * Get all bundles per item + * and all the bitstreams per bundle + * @param page number of current page + */ + getBundlesPerItem(page: number = 1) { this.item$ = this.route.data.pipe( map((data) => data.dso), getFirstSucceededRemoteDataWithNotEmptyPayload(), map((item: Item) => this.linkService.resolveLink( item, - followLink('bundles', {}, followLink('bitstreams')) + followLink('bundles', {findListOptions: {currentPage : page, elementsPerPage: this.bunblesPerPage}}, followLink('bitstreams')) )) ) as Observable; - const bundles$: Observable> = this.item$.pipe( + const bundles$: Observable> = this.item$.pipe( filter((item: Item) => isNotEmpty(item.bundles)), mergeMap((item: Item) => item.bundles), getFirstSucceededRemoteDataWithNotEmptyPayload(), @@ -96,37 +174,40 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { take(1), map((list: PaginatedList) => list.page) ).subscribe((bundles: Bundle[]) => { - this.bundles$.next(bundles); + if (isEqual(bundles.length,0) || bundles.length < this.bunblesPerPage) { + this.allBundlesLoaded = true; + } + if (isEqual(page, 1)) { + this.bundles$.next(bundles); + this.bundlesToShow$.next(bundles); + } else { + this.bundlesToShow$.next(this.bundles$.getValue().concat(bundles)); + this.bundles$.next(this.bundles$.getValue().concat(bundles)); + } }), bundles$.pipe( take(1), mergeMap((list: PaginatedList) => list.page), map((bundle: Bundle) => ({ id: bundle.id, bitstreams: this.getBundleBitstreams(bundle) })) ).subscribe((entry: BundleBitstreamsMapEntry) => { - this.bundleBitstreamsMap.set(entry.id, entry.bitstreams); + let bitstreamMapValues: BitstreamMapValue = { + isCollapsed: true, + allBitstreamsLoaded: false, + bitstreams: null + }; + let bits = entry.bitstreams.pipe( + map((b: PaginatedList) => { + bitstreamMapValues.allBitstreamsLoaded = b?.page.length < this.bitstreamSize ; + let firstLoaded = [...b.page.slice(0, this.bitstreamSize)]; + return firstLoaded; + }) + ); + bitstreamMapValues.bitstreams = bits; + this.bundleBitstreamsMap.set(entry.id, bitstreamMapValues); }) ); } - /** - * Return the item's UUID - */ - getItemUUID(): Observable { - return this.item$.pipe( - map((item: Item) => item.id), - first((UUID: string) => isNotEmpty(UUID)) - ); - } - - /** - * Return all item's bundles - * - * @return an observable that emits all item's bundles - */ - getItemBundles(): Observable { - return this.bundles$.asObservable(); - } - /** * Return all bundle's bitstreams * @@ -142,6 +223,48 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { ); } + /** + * Changes the collapsible state of the area that contains the bitstream list + * @param bundleId Id of bundle responsible for the requested bitstreams + */ + collapseArea(bundleId: string) { + this.bundleBitstreamsMap.get(bundleId).isCollapsed = !this.bundleBitstreamsMap.get(bundleId).isCollapsed; + } + + /** + * Loads as much bundles as initial value of bundleSize to be displayed + */ + onBunbleLoad(){ + this.bunblesPageSize ++; + this.getBundlesPerItem(this.bunblesPageSize); + } + + /** + * Calculates the bitstreams that are going to be loaded on demand, + * based on the number configured on this.bitstreamSize. + * @param bundle parent of bitstreams that are requested to be shown + * @returns Subscription + */ + onBitstreamsLoad(bundle: Bundle) { + return this.getBundleBitstreams(bundle).pipe( + map((res: PaginatedList) => { + let nextBitstreams = res?.page.slice(this.bitstreamPageSize, this.bitstreamPageSize + this.bitstreamSize); + let bitstreamsToShow = this.bundleBitstreamsMap.get(bundle.id).bitstreams.pipe( + map((existingBits: Bitstream[])=> { + return [... existingBits, ...nextBitstreams]; + }) + ); + this.bitstreamPageSize = this.bitstreamPageSize + this.bitstreamSize; + let bitstreamMapValues: BitstreamMapValue = { + bitstreams: bitstreamsToShow , + isCollapsed: this.bundleBitstreamsMap.get(bundle.id).isCollapsed, + allBitstreamsLoaded: res?.page.length <= this.bitstreamPageSize + }; + this.bundleBitstreamsMap.set(bundle.id, bitstreamMapValues); + }) + ).subscribe(); + } + /** * Unsubscribe from all subscriptions */ @@ -151,3 +274,9 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { .forEach((subscription) => subscription.unsubscribe()); } } + +export interface BitstreamMapValue { + bitstreams: Observable; + isCollapsed: boolean; + allBitstreamsLoaded: boolean; +} diff --git a/src/app/shared/resource-policies/resource-policies.component.html b/src/app/shared/resource-policies/resource-policies.component.html index 0a1ccf79524..5d11ac81f2f 100644 --- a/src/app/shared/resource-policies/resource-policies.component.html +++ b/src/app/shared/resource-policies/resource-policies.component.html @@ -4,9 +4,16 @@
- {{ 'resource-policies.table.headers.title.for.' + resourceType | translate }} {{resourceUUID}} + + {{ 'resource-policies.table.headers.title.for.' + resourceType | translate }} + + {{resourceName}} + + ({{resourceUUID}}) + +
- -
@@ -21,13 +21,13 @@ [resourceName]="bitstream.name">
- +
- +
diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index f3313d4cef3..a833b90b208 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -45,13 +45,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * The list of all bundles for the item * @type {Observable>} */ - private bundles$: BehaviorSubject = new BehaviorSubject([]); - - /** - * The list of bundles to be displayed in the template - * @type {BehaviorSubject} - */ - bundlesToShow$: BehaviorSubject = new BehaviorSubject([]); + bundles$: BehaviorSubject = new BehaviorSubject([]); /** * The target editing item @@ -69,13 +63,13 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * The size of the bundles to be loaded on demand * @type {number} */ - bunblesPerPage = 6; + bunblesPerPage = 1; /** * The number of current page * @type {number} */ - bunblesPageSize = 1; + bunblesPageSize = 6; /** * The flag to show or not the 'Load more' button @@ -179,9 +173,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { } if (isEqual(page, 1)) { this.bundles$.next(bundles); - this.bundlesToShow$.next(bundles); } else { - this.bundlesToShow$.next(this.bundles$.getValue().concat(bundles)); this.bundles$.next(this.bundles$.getValue().concat(bundles)); } }), diff --git a/src/app/shared/resource-policies/resource-policies.component.html b/src/app/shared/resource-policies/resource-policies.component.html index 5d11ac81f2f..d1fd9266b13 100644 --- a/src/app/shared/resource-policies/resource-policies.component.html +++ b/src/app/shared/resource-policies/resource-policies.component.html @@ -6,7 +6,6 @@
{{ 'resource-policies.table.headers.title.for.' + resourceType | translate }} - {{resourceName}} ({{resourceUUID}}) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 76f4f538ea5..cef52fde9ca 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -848,6 +848,12 @@ "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", + "collection.edit.item.authorizations.load-bundle-button": "Load more bundles", + + "collection.edit.item.authorizations.load-more-button": "Load more", + + "collection.edit.item.authorizations.show-bitstreams-button": "Show all Bitstreams' Policies for Bundle", + "collection.edit.tabs.metadata.head": "Edit Metadata", "collection.edit.tabs.metadata.title": "Collection Edit - Metadata", From 6cd41be3b80278fd086ffbf6ad7ad023a5aa3e67 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Mon, 9 May 2022 12:01:46 +0200 Subject: [PATCH 194/409] [CST-5677] Changed bunblesPerPage value --- .../item-authorizations/item-authorizations.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index a833b90b208..f018d1c6425 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -63,7 +63,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * The size of the bundles to be loaded on demand * @type {number} */ - bunblesPerPage = 1; + bunblesPerPage = 6; /** * The number of current page From 32d7fca27af3d92eda08c998414a2927fb4ad2c3 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Mon, 9 May 2022 12:02:50 +0200 Subject: [PATCH 195/409] [CST-5677] Changed bunblesPageSize value --- .../item-authorizations/item-authorizations.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index f018d1c6425..3a7a7d95f27 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -69,7 +69,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * The number of current page * @type {number} */ - bunblesPageSize = 6; + bunblesPageSize = 1; /** * The flag to show or not the 'Load more' button From 51058daf27f0d63aecdc3f28a981ddc23b108ef7 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 10 May 2022 09:25:59 +1200 Subject: [PATCH 196/409] [TLC-254] tidy imports in type bind service --- .../ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts index f8a7376c3e8..5dd4a6627d0 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts @@ -15,7 +15,7 @@ import { OR_OPERATOR } from '@ng-dynamic-forms/core'; -import {hasNoValue, hasValue, isEmpty} from '../../../empty.util'; +import {hasNoValue, hasValue} from '../../../empty.util'; import { FormBuilderService } from '../form-builder.service'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-constants'; From 0b664431afb6306a67034e70261b406081b805f0 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Tue, 10 May 2022 18:10:50 +0200 Subject: [PATCH 197/409] [CST-5307] Create a standalone component for person claim button --- .../item-pages/person/person.component.html | 14 +- .../person/person.component.spec.ts | 52 +++- .../item-pages/person/person.component.ts | 81 +------ .../person-page-claim-button.component.html | 1 + .../person-page-claim-button.component.scss | 0 ...person-page-claim-button.component.spec.ts | 186 ++++++++++++++ .../person-page-claim-button.component.ts | 85 +++++++ src/app/shared/shared.module.ts | 229 +++++++++++++----- src/assets/i18n/en.json5 | 2 + 9 files changed, 501 insertions(+), 149 deletions(-) create mode 100644 src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.html create mode 100644 src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.scss create mode 100644 src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.spec.ts create mode 100644 src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.ts diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.html b/src/app/entity-groups/research-entities/item-pages/person/person.component.html index 7505a31327a..96cfdbfacd7 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.html +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.html @@ -4,7 +4,7 @@

- +
@@ -20,18 +20,10 @@

[fields]="['person.email']" [label]="'person.page.email'"> - - - - - - - -

[fields]="['person.givenName']" [label]="'person.page.firstname'"> + +
{{"item.page.link.full" | translate}} diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts b/src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts index 93b3cf208d7..efbc48a2090 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts @@ -17,24 +17,12 @@ const mockItem: Item = Object.assign(new Item(), { value: 'fake@email.com' } ], - // 'person.identifier.orcid': [ - // { - // language: 'en_US', - // value: 'ORCID-1' - // } - // ], 'person.birthDate': [ { language: 'en_US', value: '1993' } ], - // 'person.identifier.staffid': [ - // { - // language: 'en_US', - // value: '1' - // } - // ], 'person.jobTitle': [ { language: 'en_US', @@ -62,4 +50,42 @@ const mockItem: Item = Object.assign(new Item(), { } }); -describe('PersonComponent', getItemPageFieldsTest(mockItem, PersonComponent)); +const mockItemWithTitle: Item = Object.assign(new Item(), { + bundles: createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [])), + metadata: { + 'person.email': [ + { + language: 'en_US', + value: 'fake@email.com' + } + ], + 'person.birthDate': [ + { + language: 'en_US', + value: '1993' + } + ], + 'person.jobTitle': [ + { + language: 'en_US', + value: 'Developer' + } + ], + 'dc.title': [ + { + language: 'en_US', + value: 'Doe, John' + } + ] + }, + relationships: createRelationshipsObservable(), + _links: { + self : { + href: 'item-href' + } + } +}); + +describe('PersonComponent with family and given names', getItemPageFieldsTest(mockItem, PersonComponent)); + +describe('PersonComponent with dc.title', getItemPageFieldsTest(mockItemWithTitle, PersonComponent)); diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts index 33db18681fb..27fdd2ab158 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts @@ -1,20 +1,10 @@ -import {Component, OnInit} from '@angular/core'; +import { Component } from '@angular/core'; import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; -import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; -import {MetadataValue} from '../../../../core/shared/metadata.models'; -import {FeatureID} from '../../../../core/data/feature-authorization/feature-id'; -import {mergeMap, take} from 'rxjs/operators'; -import {getFirstSucceededRemoteData} from '../../../../core/shared/operators'; -import {RemoteData} from '../../../../core/data/remote-data'; -import {ResearcherProfile} from '../../../../core/profile/model/researcher-profile.model'; -import {isNotUndefined} from '../../../../shared/empty.util'; -import {BehaviorSubject, Observable} from 'rxjs'; -import {RouteService} from '../../../../core/services/route.service'; -import {AuthorizationDataService} from '../../../../core/data/feature-authorization/authorization-data.service'; -import {ResearcherProfileService} from '../../../../core/profile/researcher-profile.service'; -import {NotificationsService} from '../../../../shared/notifications/notifications.service'; -import {TranslateService} from '@ngx-translate/core'; +import { + listableObjectComponent +} from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { MetadataValue } from '../../../../core/shared/metadata.models'; @listableObjectComponent('Person', ViewMode.StandalonePage) @Component({ @@ -25,76 +15,25 @@ import {TranslateService} from '@ngx-translate/core'; /** * The component for displaying metadata and relations of an item of the type Person */ -export class PersonComponent extends ItemComponent implements OnInit { - - claimable$: BehaviorSubject = new BehaviorSubject(false); - - constructor(protected routeService: RouteService, - protected authorizationService: AuthorizationDataService, - protected notificationsService: NotificationsService, - protected translate: TranslateService, - protected researcherProfileService: ResearcherProfileService) { - super(routeService); - } - - ngOnInit(): void { - super.ngOnInit(); - - this.authorizationService.isAuthorized(FeatureID.CanClaimItem, this.object._links.self.href).pipe( - take(1) - ).subscribe((isAuthorized: boolean) => { - this.claimable$.next(isAuthorized); - }); - - } - - /** - * Create a new researcher profile claiming the current item. - */ - claim() { - this.researcherProfileService.createFromExternalSource(this.object._links.self.href).pipe( - getFirstSucceededRemoteData(), - mergeMap((rd: RemoteData) => { - return this.researcherProfileService.findRelatedItemId(rd.payload); - })) - .subscribe((id: string) => { - if (isNotUndefined(id)) { - this.notificationsService.success(this.translate.get('researcherprofile.success.claim.title'), - this.translate.get('researcherprofile.success.claim.body')); - this.claimable$.next(false); - } else { - this.notificationsService.error( - this.translate.get('researcherprofile.error.claim.title'), - this.translate.get('researcherprofile.error.claim.body')); - } - }); - } - - /** - * Returns true if the item is claimable, false otherwise. - */ - isClaimable(): Observable { - return this.claimable$; - } +export class PersonComponent extends ItemComponent { /** * Returns the metadata values to be used for the page title. */ - getTitleMetadataValues(): MetadataValue[]{ + getTitleMetadataValues(): MetadataValue[] { const metadataValues = []; const familyName = this.object?.firstMetadata('person.familyName'); const givenName = this.object?.firstMetadata('person.givenName'); const title = this.object?.firstMetadata('dc.title'); - if (familyName){ + if (familyName) { metadataValues.push(familyName); } - if (givenName){ + if (givenName) { metadataValues.push(givenName); } - if (metadataValues.length === 0 && title){ + if (metadataValues.length === 0 && title) { metadataValues.push(title); } return metadataValues; } - } diff --git a/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.html b/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.html new file mode 100644 index 00000000000..12d5d2b47d1 --- /dev/null +++ b/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.html @@ -0,0 +1 @@ + diff --git a/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.scss b/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.spec.ts b/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.spec.ts new file mode 100644 index 00000000000..168517b47af --- /dev/null +++ b/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.spec.ts @@ -0,0 +1,186 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { of as observableOf } from 'rxjs'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; + +import { PersonPageClaimButtonComponent } from './person-page-claim-button.component'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { NotificationsService } from '../../notifications/notifications.service'; +import { NotificationsServiceStub } from '../../testing/notifications-service.stub'; +import { TranslateLoaderMock } from '../../mocks/translate-loader.mock'; +import { ResearcherProfileService } from '../../../core/profile/researcher-profile.service'; +import { RouteService } from '../../../core/services/route.service'; +import { routeServiceStub } from '../../testing/route-service.stub'; +import { Item } from '../../../core/shared/item.model'; +import { ResearcherProfile } from '../../../core/profile/model/researcher-profile.model'; +import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../remote-data.utils'; +import { getTestScheduler } from 'jasmine-marbles'; +import { TestScheduler } from 'rxjs/testing'; + +describe('PersonPageClaimButtonComponent', () => { + let scheduler: TestScheduler; + let component: PersonPageClaimButtonComponent; + let fixture: ComponentFixture; + + const mockItem: Item = Object.assign(new Item(), { + metadata: { + 'person.email': [ + { + language: 'en_US', + value: 'fake@email.com' + } + ], + 'person.birthDate': [ + { + language: 'en_US', + value: '1993' + } + ], + 'person.jobTitle': [ + { + language: 'en_US', + value: 'Developer' + } + ], + 'person.familyName': [ + { + language: 'en_US', + value: 'Doe' + } + ], + 'person.givenName': [ + { + language: 'en_US', + value: 'John' + } + ] + }, + _links: { + self: { + href: 'item-href' + } + } + }); + + const mockResearcherProfile: ResearcherProfile = Object.assign(new ResearcherProfile(), { + id: 'test-id', + visible: true, + type: 'profile', + _links: { + item: { + href: 'https://rest.api/rest/api/profiles/test-id/item' + }, + self: { + href: 'https://rest.api/rest/api/profiles/test-id' + }, + } + }); + + const notificationsService = new NotificationsServiceStub(); + + const authorizationDataService = jasmine.createSpyObj('authorizationDataService', { + isAuthorized: jasmine.createSpy('isAuthorized') + }); + + const researcherProfileService = jasmine.createSpyObj('researcherProfileService', { + createFromExternalSource: jasmine.createSpy('createFromExternalSource'), + findRelatedItemId: jasmine.createSpy('findRelatedItemId'), + }); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) + ], + declarations: [PersonPageClaimButtonComponent], + providers: [ + { provide: AuthorizationDataService, useValue: authorizationDataService }, + { provide: NotificationsService, useValue: notificationsService }, + { provide: ResearcherProfileService, useValue: researcherProfileService }, + { provide: RouteService, useValue: routeServiceStub }, + ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PersonPageClaimButtonComponent); + component = fixture.componentInstance; + component.object = mockItem; + }); + + describe('when item can be claimed', () => { + beforeEach(() => { + authorizationDataService.isAuthorized.and.returnValue(observableOf(true)); + researcherProfileService.createFromExternalSource.calls.reset(); + researcherProfileService.findRelatedItemId.calls.reset(); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should create claim button', () => { + const btn = fixture.debugElement.query(By.css('[data-test="item-claim"]')); + expect(btn).toBeTruthy(); + }); + + describe('claim', () => { + describe('when successfully', () => { + beforeEach(() => { + scheduler = getTestScheduler(); + researcherProfileService.createFromExternalSource.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile)); + researcherProfileService.findRelatedItemId.and.returnValue(observableOf('test-id')); + }); + + it('should display success notification', () => { + scheduler.schedule(() => component.claim()); + scheduler.flush(); + + expect(researcherProfileService.findRelatedItemId).toHaveBeenCalled(); + expect(notificationsService.success).toHaveBeenCalled(); + }); + }); + + describe('when not successfully', () => { + beforeEach(() => { + scheduler = getTestScheduler(); + researcherProfileService.createFromExternalSource.and.returnValue(createFailedRemoteDataObject$()); + }); + + it('should display success notification', () => { + scheduler.schedule(() => component.claim()); + scheduler.flush(); + + expect(researcherProfileService.findRelatedItemId).not.toHaveBeenCalled(); + expect(notificationsService.error).toHaveBeenCalled(); + }); + }); + }); + + }); + + describe('when item cannot be claimed', () => { + beforeEach(() => { + authorizationDataService.isAuthorized.and.returnValue(observableOf(false)); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should create claim button', () => { + const btn = fixture.debugElement.query(By.css('[data-test="item-claim"]')); + expect(btn).toBeFalsy(); + }); + + }); +}); diff --git a/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.ts b/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.ts new file mode 100644 index 00000000000..d2e8e888e13 --- /dev/null +++ b/src/app/shared/dso-page/person-page-claim-button/person-page-claim-button.component.ts @@ -0,0 +1,85 @@ +import { Component, Input, OnInit } from '@angular/core'; + +import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; +import { mergeMap, take } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; + +import { RouteService } from '../../../core/services/route.service'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { NotificationsService } from '../../notifications/notifications.service'; +import { ResearcherProfileService } from '../../../core/profile/researcher-profile.service'; +import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { RemoteData } from '../../../core/data/remote-data'; +import { ResearcherProfile } from '../../../core/profile/model/researcher-profile.model'; +import { isNotEmpty } from '../../empty.util'; +import { DSpaceObject } from '../../../core/shared/dspace-object.model'; + +@Component({ + selector: 'ds-person-page-claim-button', + templateUrl: './person-page-claim-button.component.html', + styleUrls: ['./person-page-claim-button.component.scss'] +}) +export class PersonPageClaimButtonComponent implements OnInit { + + /** + * The target person item to claim + */ + @Input() object: DSpaceObject; + + /** + * A boolean representing if item can be claimed or not + */ + claimable$: BehaviorSubject = new BehaviorSubject(false); + + constructor(protected routeService: RouteService, + protected authorizationService: AuthorizationDataService, + protected notificationsService: NotificationsService, + protected translate: TranslateService, + protected researcherProfileService: ResearcherProfileService) { + } + + ngOnInit(): void { + this.authorizationService.isAuthorized(FeatureID.CanClaimItem, this.object._links.self.href).pipe( + take(1) + ).subscribe((isAuthorized: boolean) => { + this.claimable$.next(isAuthorized); + }); + + } + + /** + * Create a new researcher profile claiming the current item. + */ + claim() { + this.researcherProfileService.createFromExternalSource(this.object._links.self.href).pipe( + getFirstCompletedRemoteData(), + mergeMap((rd: RemoteData) => { + console.log(rd); + if (rd.hasSucceeded) { + return this.researcherProfileService.findRelatedItemId(rd.payload); + } else { + return observableOf(null); + } + })) + .subscribe((id: string) => { + if (isNotEmpty(id)) { + this.notificationsService.success(this.translate.get('researcherprofile.success.claim.title'), + this.translate.get('researcherprofile.success.claim.body')); + this.claimable$.next(false); + } else { + this.notificationsService.error( + this.translate.get('researcherprofile.error.claim.title'), + this.translate.get('researcherprofile.error.claim.body')); + } + }); + } + + /** + * Returns true if the item is claimable, false otherwise. + */ + isClaimable(): Observable { + return this.claimable$; + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 847b3910e0e..b2a36285bbc 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -7,7 +7,12 @@ import { DragDropModule } from '@angular/cdk/drag-drop'; import { NouisliderModule } from 'ng2-nouislider'; import { - NgbDatepickerModule, NgbDropdownModule, NgbNavModule, NgbPaginationModule, NgbTimepickerModule, NgbTooltipModule, + NgbDatepickerModule, + NgbDropdownModule, + NgbNavModule, + NgbPaginationModule, + NgbTimepickerModule, + NgbTooltipModule, NgbTypeaheadModule, } from '@ng-bootstrap/ng-bootstrap'; import { MissingTranslationHandler, TranslateModule } from '@ngx-translate/core'; @@ -16,7 +21,9 @@ import { FileUploadModule } from 'ng2-file-upload'; import { InfiniteScrollModule } from 'ngx-infinite-scroll'; import { MomentModule } from 'ngx-moment'; import { ConfirmationModalComponent } from './confirmation-modal/confirmation-modal.component'; -import { ExportMetadataSelectorComponent } from './dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component'; +import { + ExportMetadataSelectorComponent +} from './dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component'; import { FileDropzoneNoUploaderComponent } from './file-dropzone-no-uploader/file-dropzone-no-uploader.component'; import { ItemListElementComponent } from './object-list/item-list-element/item-types/item/item-list-element.component'; import { EnumKeysPipe } from './utils/enum-keys-pipe'; @@ -24,13 +31,21 @@ import { FileSizePipe } from './utils/file-size-pipe'; import { MetadataFieldValidator } from './utils/metadatafield-validator.directive'; import { SafeUrlPipe } from './utils/safe-url-pipe'; import { ConsolePipe } from './utils/console.pipe'; -import { CollectionListElementComponent } from './object-list/collection-list-element/collection-list-element.component'; +import { + CollectionListElementComponent +} from './object-list/collection-list-element/collection-list-element.component'; import { CommunityListElementComponent } from './object-list/community-list-element/community-list-element.component'; -import { SearchResultListElementComponent } from './object-list/search-result-list-element/search-result-list-element.component'; +import { + SearchResultListElementComponent +} from './object-list/search-result-list-element/search-result-list-element.component'; import { ObjectListComponent } from './object-list/object-list.component'; -import { CollectionGridElementComponent } from './object-grid/collection-grid-element/collection-grid-element.component'; +import { + CollectionGridElementComponent +} from './object-grid/collection-grid-element/collection-grid-element.component'; import { CommunityGridElementComponent } from './object-grid/community-grid-element/community-grid-element.component'; -import { AbstractListableElementComponent } from './object-collection/shared/object-collection-element/abstract-listable-element.component'; +import { + AbstractListableElementComponent +} from './object-collection/shared/object-collection-element/abstract-listable-element.component'; import { ObjectGridComponent } from './object-grid/object-grid.component'; import { ObjectCollectionComponent } from './object-collection/object-collection.component'; import { ErrorComponent } from './error/error.component'; @@ -38,7 +53,9 @@ import { LoadingComponent } from './loading/loading.component'; import { PaginationComponent } from './pagination/pagination.component'; import { ThumbnailComponent } from '../thumbnail/thumbnail.component'; import { SearchFormComponent } from './search-form/search-form.component'; -import { SearchResultGridElementComponent } from './object-grid/search-result-grid-element/search-result-grid-element.component'; +import { + SearchResultGridElementComponent +} from './object-grid/search-result-grid-element/search-result-grid-element.component'; import { ViewModeSwitchComponent } from './view-mode-switch/view-mode-switch.component'; import { VarDirective } from './utils/var.directive'; import { AuthNavMenuComponent } from './auth-nav-menu/auth-nav-menu.component'; @@ -53,21 +70,33 @@ import { ChipsComponent } from './chips/chips.component'; import { NumberPickerComponent } from './number-picker/number-picker.component'; import { MockAdminGuard } from './mocks/admin-guard.service.mock'; import { AlertComponent } from './alert/alert.component'; -import { SearchResultDetailElementComponent } from './object-detail/my-dspace-result-detail-element/search-result-detail-element.component'; +import { + SearchResultDetailElementComponent +} from './object-detail/my-dspace-result-detail-element/search-result-detail-element.component'; import { ClaimedTaskActionsComponent } from './mydspace-actions/claimed-task/claimed-task-actions.component'; import { PoolTaskActionsComponent } from './mydspace-actions/pool-task/pool-task-actions.component'; import { ObjectDetailComponent } from './object-detail/object-detail.component'; -import { ItemDetailPreviewComponent } from './object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component'; -import { MyDSpaceItemStatusComponent } from './object-collection/shared/mydspace-item-status/my-dspace-item-status.component'; +import { + ItemDetailPreviewComponent +} from './object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component'; +import { + MyDSpaceItemStatusComponent +} from './object-collection/shared/mydspace-item-status/my-dspace-item-status.component'; import { WorkspaceitemActionsComponent } from './mydspace-actions/workspaceitem/workspaceitem-actions.component'; import { WorkflowitemActionsComponent } from './mydspace-actions/workflowitem/workflowitem-actions.component'; import { ItemSubmitterComponent } from './object-collection/shared/mydspace-item-submitter/item-submitter.component'; import { ItemActionsComponent } from './mydspace-actions/item/item-actions.component'; -import { ClaimedTaskActionsApproveComponent } from './mydspace-actions/claimed-task/approve/claimed-task-actions-approve.component'; -import { ClaimedTaskActionsRejectComponent } from './mydspace-actions/claimed-task/reject/claimed-task-actions-reject.component'; +import { + ClaimedTaskActionsApproveComponent +} from './mydspace-actions/claimed-task/approve/claimed-task-actions-approve.component'; +import { + ClaimedTaskActionsRejectComponent +} from './mydspace-actions/claimed-task/reject/claimed-task-actions-reject.component'; import { ObjNgFor } from './utils/object-ngfor.pipe'; import { BrowseByComponent } from './browse-by/browse-by.component'; -import { BrowseEntryListElementComponent } from './object-list/browse-entry-list-element/browse-entry-list-element.component'; +import { + BrowseEntryListElementComponent +} from './object-list/browse-entry-list-element/browse-entry-list-element.component'; import { DebounceDirective } from './utils/debounce.directive'; import { ClickOutsideDirective } from './utils/click-outside.directive'; import { EmphasizePipe } from './utils/emphasize.pipe'; @@ -76,53 +105,105 @@ import { CapitalizePipe } from './utils/capitalize.pipe'; import { ObjectKeysPipe } from './utils/object-keys-pipe'; import { AuthorityConfidenceStateDirective } from './authority-confidence/authority-confidence-state.directive'; import { LangSwitchComponent } from './lang-switch/lang-switch.component'; -import { PlainTextMetadataListElementComponent } from './object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component'; -import { ItemMetadataListElementComponent } from './object-list/metadata-representation-list-element/item/item-metadata-list-element.component'; -import { MetadataRepresentationListElementComponent } from './object-list/metadata-representation-list-element/metadata-representation-list-element.component'; +import { + PlainTextMetadataListElementComponent +} from './object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component'; +import { + ItemMetadataListElementComponent +} from './object-list/metadata-representation-list-element/item/item-metadata-list-element.component'; +import { + MetadataRepresentationListElementComponent +} from './object-list/metadata-representation-list-element/metadata-representation-list-element.component'; import { ObjectValuesPipe } from './utils/object-values-pipe'; import { InListValidator } from './utils/in-list-validator.directive'; import { AutoFocusDirective } from './utils/auto-focus.directive'; import { StartsWithDateComponent } from './starts-with/date/starts-with-date.component'; import { StartsWithTextComponent } from './starts-with/text/starts-with-text.component'; import { DSOSelectorComponent } from './dso-selector/dso-selector/dso-selector.component'; -import { CreateCommunityParentSelectorComponent } from './dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component'; -import { CreateItemParentSelectorComponent } from './dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component'; -import { CreateCollectionParentSelectorComponent } from './dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component'; -import { CommunitySearchResultListElementComponent } from './object-list/search-result-list-element/community-search-result/community-search-result-list-element.component'; -import { CollectionSearchResultListElementComponent } from './object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component'; -import { EditItemSelectorComponent } from './dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component'; -import { EditCommunitySelectorComponent } from './dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component'; -import { EditCollectionSelectorComponent } from './dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component'; -import { ItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component'; -import { MetadataFieldWrapperComponent } from '../item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component'; +import { + CreateCommunityParentSelectorComponent +} from './dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component'; +import { + CreateItemParentSelectorComponent +} from './dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component'; +import { + CreateCollectionParentSelectorComponent +} from './dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component'; +import { + CommunitySearchResultListElementComponent +} from './object-list/search-result-list-element/community-search-result/community-search-result-list-element.component'; +import { + CollectionSearchResultListElementComponent +} from './object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component'; +import { + EditItemSelectorComponent +} from './dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component'; +import { + EditCommunitySelectorComponent +} from './dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component'; +import { + EditCollectionSelectorComponent +} from './dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component'; +import { + ItemListPreviewComponent +} from './object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component'; +import { + MetadataFieldWrapperComponent +} from '../item-page/field-components/metadata-field-wrapper/metadata-field-wrapper.component'; import { MetadataValuesComponent } from '../item-page/field-components/metadata-values/metadata-values.component'; import { RoleDirective } from './roles/role.directive'; import { UserMenuComponent } from './auth-nav-menu/user-menu/user-menu.component'; -import { ClaimedTaskActionsReturnToPoolComponent } from './mydspace-actions/claimed-task/return-to-pool/claimed-task-actions-return-to-pool.component'; -import { ItemDetailPreviewFieldComponent } from './object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview-field/item-detail-preview-field.component'; -import { CollectionSearchResultGridElementComponent } from './object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component'; -import { CommunitySearchResultGridElementComponent } from './object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component'; +import { + ClaimedTaskActionsReturnToPoolComponent +} from './mydspace-actions/claimed-task/return-to-pool/claimed-task-actions-return-to-pool.component'; +import { + ItemDetailPreviewFieldComponent +} from './object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview-field/item-detail-preview-field.component'; +import { + CollectionSearchResultGridElementComponent +} from './object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component'; +import { + CommunitySearchResultGridElementComponent +} from './object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component'; import { PageSizeSelectorComponent } from './page-size-selector/page-size-selector.component'; import { AbstractTrackableComponent } from './trackable/abstract-trackable.component'; -import { ComcolMetadataComponent } from './comcol/comcol-forms/edit-comcol-page/comcol-metadata/comcol-metadata.component'; +import { + ComcolMetadataComponent +} from './comcol/comcol-forms/edit-comcol-page/comcol-metadata/comcol-metadata.component'; import { ItemSelectComponent } from './object-select/item-select/item-select.component'; import { CollectionSelectComponent } from './object-select/collection-select/collection-select.component'; -import { FilterInputSuggestionsComponent } from './input-suggestions/filter-suggestions/filter-input-suggestions.component'; -import { DsoInputSuggestionsComponent } from './input-suggestions/dso-input-suggestions/dso-input-suggestions.component'; +import { + FilterInputSuggestionsComponent +} from './input-suggestions/filter-suggestions/filter-input-suggestions.component'; +import { + DsoInputSuggestionsComponent +} from './input-suggestions/dso-input-suggestions/dso-input-suggestions.component'; import { ItemGridElementComponent } from './object-grid/item-grid-element/item-types/item/item-grid-element.component'; import { TypeBadgeComponent } from './object-list/type-badge/type-badge.component'; -import { MetadataRepresentationLoaderComponent } from './metadata-representation/metadata-representation-loader.component'; +import { + MetadataRepresentationLoaderComponent +} from './metadata-representation/metadata-representation-loader.component'; import { MetadataRepresentationDirective } from './metadata-representation/metadata-representation.directive'; -import { ListableObjectComponentLoaderComponent } from './object-collection/shared/listable-object/listable-object-component-loader.component'; -import { ItemSearchResultListElementComponent } from './object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component'; +import { + ListableObjectComponentLoaderComponent +} from './object-collection/shared/listable-object/listable-object-component-loader.component'; +import { + ItemSearchResultListElementComponent +} from './object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component'; import { ListableObjectDirective } from './object-collection/shared/listable-object/listable-object.directive'; -import { ItemMetadataRepresentationListElementComponent } from './object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component'; +import { + ItemMetadataRepresentationListElementComponent +} from './object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component'; import { PageWithSidebarComponent } from './sidebar/page-with-sidebar.component'; import { SidebarDropdownComponent } from './sidebar/sidebar-dropdown.component'; import { SidebarFilterComponent } from './sidebar/filter/sidebar-filter.component'; import { SidebarFilterSelectedOptionComponent } from './sidebar/filter/sidebar-filter-selected-option.component'; -import { SelectableListItemControlComponent } from './object-collection/shared/selectable-list-item-control/selectable-list-item-control.component'; -import { ImportableListItemControlComponent } from './object-collection/shared/importable-list-item-control/importable-list-item-control.component'; +import { + SelectableListItemControlComponent +} from './object-collection/shared/selectable-list-item-control/selectable-list-item-control.component'; +import { + ImportableListItemControlComponent +} from './object-collection/shared/importable-list-item-control/importable-list-item-control.component'; import { ItemVersionsComponent } from './item/item-versions/item-versions.component'; import { SortablejsModule } from 'ngx-sortablejs'; import { LogInContainerComponent } from './log-in/container/log-in-container.component'; @@ -135,10 +216,16 @@ import { ItemVersionsNoticeComponent } from './item/item-versions/notice/item-ve import { FileValidator } from './utils/require-file.validator'; import { FileValueAccessorDirective } from './utils/file-value-accessor.directive'; import { FileSectionComponent } from '../item-page/simple/field-components/file-section/file-section.component'; -import { ModifyItemOverviewComponent } from '../item-page/edit-item-page/modify-item-overview/modify-item-overview.component'; -import { ClaimedTaskActionsLoaderComponent } from './mydspace-actions/claimed-task/switcher/claimed-task-actions-loader.component'; +import { + ModifyItemOverviewComponent +} from '../item-page/edit-item-page/modify-item-overview/modify-item-overview.component'; +import { + ClaimedTaskActionsLoaderComponent +} from './mydspace-actions/claimed-task/switcher/claimed-task-actions-loader.component'; import { ClaimedTaskActionsDirective } from './mydspace-actions/claimed-task/switcher/claimed-task-actions.directive'; -import { ClaimedTaskActionsEditMetadataComponent } from './mydspace-actions/claimed-task/edit-metadata/claimed-task-actions-edit-metadata.component'; +import { + ClaimedTaskActionsEditMetadataComponent +} from './mydspace-actions/claimed-task/edit-metadata/claimed-task-actions-edit-metadata.component'; import { ImpersonateNavbarComponent } from './impersonate-navbar/impersonate-navbar.component'; import { NgForTrackByIdDirective } from './ng-for-track-by-id.directive'; import { FileDownloadLinkComponent } from './file-download-link/file-download-link.component'; @@ -146,34 +233,63 @@ import { CollectionDropdownComponent } from './collection-dropdown/collection-dr import { EntityDropdownComponent } from './entity-dropdown/entity-dropdown.component'; import { VocabularyTreeviewComponent } from './vocabulary-treeview/vocabulary-treeview.component'; import { CurationFormComponent } from '../curation-form/curation-form.component'; -import { PublicationSidebarSearchListElementComponent } from './object-list/sidebar-search-list-element/item-types/publication/publication-sidebar-search-list-element.component'; -import { SidebarSearchListElementComponent } from './object-list/sidebar-search-list-element/sidebar-search-list-element.component'; -import { CollectionSidebarSearchListElementComponent } from './object-list/sidebar-search-list-element/collection/collection-sidebar-search-list-element.component'; -import { CommunitySidebarSearchListElementComponent } from './object-list/sidebar-search-list-element/community/community-sidebar-search-list-element.component'; -import { AuthorizedCollectionSelectorComponent } from './dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component'; +import { + PublicationSidebarSearchListElementComponent +} from './object-list/sidebar-search-list-element/item-types/publication/publication-sidebar-search-list-element.component'; +import { + SidebarSearchListElementComponent +} from './object-list/sidebar-search-list-element/sidebar-search-list-element.component'; +import { + CollectionSidebarSearchListElementComponent +} from './object-list/sidebar-search-list-element/collection/collection-sidebar-search-list-element.component'; +import { + CommunitySidebarSearchListElementComponent +} from './object-list/sidebar-search-list-element/community/community-sidebar-search-list-element.component'; +import { + AuthorizedCollectionSelectorComponent +} from './dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component'; import { DsoPageEditButtonComponent } from './dso-page/dso-page-edit-button/dso-page-edit-button.component'; import { DsoPageVersionButtonComponent } from './dso-page/dso-page-version-button/dso-page-version-button.component'; import { HoverClassDirective } from './hover-class.directive'; -import { ValidationSuggestionsComponent } from './input-suggestions/validation-suggestions/validation-suggestions.component'; +import { + ValidationSuggestionsComponent +} from './input-suggestions/validation-suggestions/validation-suggestions.component'; import { ItemAlertsComponent } from './item/item-alerts/item-alerts.component'; -import { ItemSearchResultGridElementComponent } from './object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component'; +import { + ItemSearchResultGridElementComponent +} from './object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component'; import { BitstreamDownloadPageComponent } from './bitstream-download-page/bitstream-download-page.component'; -import { GenericItemPageFieldComponent } from '../item-page/simple/field-components/specific-field/generic/generic-item-page-field.component'; -import { MetadataRepresentationListComponent } from '../item-page/simple/metadata-representation-list/metadata-representation-list.component'; +import { + GenericItemPageFieldComponent +} from '../item-page/simple/field-components/specific-field/generic/generic-item-page-field.component'; +import { + MetadataRepresentationListComponent +} from '../item-page/simple/metadata-representation-list/metadata-representation-list.component'; import { RelatedItemsComponent } from '../item-page/simple/related-items/related-items-component'; import { LinkMenuItemComponent } from './menu/menu-item/link-menu-item.component'; import { OnClickMenuItemComponent } from './menu/menu-item/onclick-menu-item.component'; import { TextMenuItemComponent } from './menu/menu-item/text-menu-item.component'; import { SearchNavbarComponent } from '../search-navbar/search-navbar.component'; -import { ItemVersionsSummaryModalComponent } from './item/item-versions/item-versions-summary-modal/item-versions-summary-modal.component'; -import { ItemVersionsDeleteModalComponent } from './item/item-versions/item-versions-delete-modal/item-versions-delete-modal.component'; +import { + ItemVersionsSummaryModalComponent +} from './item/item-versions/item-versions-summary-modal/item-versions-summary-modal.component'; +import { + ItemVersionsDeleteModalComponent +} from './item/item-versions/item-versions-delete-modal/item-versions-delete-modal.component'; import { ScopeSelectorModalComponent } from './search-form/scope-selector-modal/scope-selector-modal.component'; -import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-page/bitstream-request-a-copy-page.component'; +import { + BitstreamRequestACopyPageComponent +} from './bitstream-request-a-copy-page/bitstream-request-a-copy-page.component'; import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; -import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; -import { ClaimItemSelectorComponent } from './dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component'; +import { + ThemedItemListPreviewComponent +} from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; +import { + ClaimItemSelectorComponent +} from './dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component'; import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component'; +import { PersonPageClaimButtonComponent } from './dso-page/person-page-claim-button/person-page-claim-button.component'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -410,6 +526,7 @@ const SHARED_ITEM_PAGE_COMPONENTS = [ MetadataValuesComponent, DsoPageEditButtonComponent, DsoPageVersionButtonComponent, + PersonPageClaimButtonComponent, ItemAlertsComponent, GenericItemPageFieldComponent, MetadataRepresentationListComponent, diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index e4875d153e1..868f79e4906 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2762,6 +2762,8 @@ "person.page.lastname": "Last Name", + "person.page.name": "Name", + "person.page.link.full": "Show all metadata", "person.page.orcid": "ORCID", From 853dcecfb8e5cad295ae7f15ecfaf5433ae408f1 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Tue, 10 May 2022 18:14:00 +0200 Subject: [PATCH 198/409] [CST-5307] Refactoring and adding missing unit tests --- .../core/breadcrumbs/dso-name.service.spec.ts | 31 +- .../researcher-profile.service.spec.ts | 290 ++++++++++++++++++ .../profile/researcher-profile.service.ts | 228 +++++++------- .../profile-claim.service.spec.ts | 215 +++++++++++++ .../profile-claim/profile-claim.service.ts | 59 ++-- ...ile-page-researcher-form.component.spec.ts | 7 +- .../profile-page-researcher-form.component.ts | 20 +- .../profile-page.component.spec.ts | 276 ++++++++++------- .../profile-page/profile-page.component.ts | 21 +- yarn.lock | 5 - 10 files changed, 871 insertions(+), 281 deletions(-) create mode 100644 src/app/core/profile/researcher-profile.service.spec.ts create mode 100644 src/app/profile-page/profile-claim/profile-claim.service.spec.ts diff --git a/src/app/core/breadcrumbs/dso-name.service.spec.ts b/src/app/core/breadcrumbs/dso-name.service.spec.ts index 7a399ce7483..9f2f76599af 100644 --- a/src/app/core/breadcrumbs/dso-name.service.spec.ts +++ b/src/app/core/breadcrumbs/dso-name.service.spec.ts @@ -78,15 +78,32 @@ describe(`DSONameService`, () => { }); describe(`factories.Person`, () => { - beforeEach(() => { - spyOn(mockPerson, 'firstMetadataValue').and.returnValues(...mockPersonName.split(', ')); + describe(`with person.familyName and person.givenName`, () => { + beforeEach(() => { + spyOn(mockPerson, 'firstMetadataValue').and.returnValues(...mockPersonName.split(', ')); + }); + + it(`should return 'person.familyName, person.givenName'`, () => { + const result = (service as any).factories.Person(mockPerson); + expect(result).toBe(mockPersonName); + expect(mockPerson.firstMetadataValue).toHaveBeenCalledWith('person.familyName'); + expect(mockPerson.firstMetadataValue).toHaveBeenCalledWith('person.givenName'); + expect(mockPerson.firstMetadataValue).not.toHaveBeenCalledWith('dc.title'); + }); }); - it(`should return 'person.familyName, person.givenName'`, () => { - const result = (service as any).factories.Person(mockPerson); - expect(result).toBe(mockPersonName); - expect(mockPerson.firstMetadataValue).toHaveBeenCalledWith('person.familyName'); - expect(mockPerson.firstMetadataValue).toHaveBeenCalledWith('person.givenName'); + describe(`without person.familyName and person.givenName`, () => { + beforeEach(() => { + spyOn(mockPerson, 'firstMetadataValue').and.returnValues(undefined, undefined, mockPersonName); + }); + + it(`should return dc.title`, () => { + const result = (service as any).factories.Person(mockPerson); + expect(result).toBe(mockPersonName); + expect(mockPerson.firstMetadataValue).toHaveBeenCalledWith('person.familyName'); + expect(mockPerson.firstMetadataValue).toHaveBeenCalledWith('person.givenName'); + expect(mockPerson.firstMetadataValue).toHaveBeenCalledWith('dc.title'); + }); }); }); diff --git a/src/app/core/profile/researcher-profile.service.spec.ts b/src/app/core/profile/researcher-profile.service.spec.ts new file mode 100644 index 00000000000..103bae27197 --- /dev/null +++ b/src/app/core/profile/researcher-profile.service.spec.ts @@ -0,0 +1,290 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; + +import { cold, getTestScheduler, hot } from 'jasmine-marbles'; +import { of as observableOf } from 'rxjs'; +import { TestScheduler } from 'rxjs/testing'; + +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { HALEndpointService } from '../shared/hal-endpoint.service'; +import { RequestService } from '../data/request.service'; +import { PageInfo } from '../shared/page-info.model'; +import { buildPaginatedList } from '../data/paginated-list.model'; +import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { RestResponse } from '../cache/response.models'; +import { RequestEntry } from '../data/request-entry.model'; +import { ResearcherProfileService } from './researcher-profile.service'; +import { RouterMock } from '../../shared/mocks/router.mock'; +import { ResearcherProfile } from './model/researcher-profile.model'; +import { Item } from '../shared/item.model'; +import { ReplaceOperation } from 'fast-json-patch'; +import { HttpOptions } from '../dspace-rest/dspace-rest.service'; +import { PostRequest } from '../data/request.models'; + +describe('ResearcherProfileService', () => { + let scheduler: TestScheduler; + let service: ResearcherProfileService; + let serviceAsAny: any; + let requestService: RequestService; + let rdbService: RemoteDataBuildService; + let objectCache: ObjectCacheService; + let halService: HALEndpointService; + let responseCacheEntry: RequestEntry; + + const researcherProfileId = 'beef9946-rt56-479e-8f11-b90cbe9f7241'; + const itemId = 'beef9946-rt56-479e-8f11-b90cbe9f7241'; + const researcherProfileItem: Item = Object.assign(new Item(), { + id: itemId, + _links: { + self: { + href: `https://rest.api/rest/api/items/${itemId}` + }, + } + }); + const researcherProfile: ResearcherProfile = Object.assign(new ResearcherProfile(), { + id: researcherProfileId, + visible: false, + type: 'profile', + _links: { + item: { + href: `https://rest.api/rest/api/profiles/${researcherProfileId}/item` + }, + self: { + href: `https://rest.api/rest/api/profiles/${researcherProfileId}` + }, + } + }); + + const researcherProfilePatched: ResearcherProfile = Object.assign(new ResearcherProfile(), { + id: researcherProfileId, + visible: true, + type: 'profile', + _links: { + item: { + href: `https://rest.api/rest/api/profiles/${researcherProfileId}/item` + }, + self: { + href: `https://rest.api/rest/api/profiles/${researcherProfileId}` + }, + } + }); + + const researcherProfileId2 = 'agbf9946-f4ce-479e-8f11-b90cbe9f7241'; + const anotherResearcherProfile: ResearcherProfile = Object.assign(new ResearcherProfile(), { + id: researcherProfileId2, + visible: false, + type: 'profile', + _links: { + self: { + href: `https://rest.api/rest/api/profiles/${researcherProfileId2}` + }, + } + }); + const endpointURL = `https://rest.api/rest/api/profiles`; + const sourceUri = `https://rest.api/rest/api/external-source/profile`; + const requestURL = `https://rest.api/rest/api/profiles/${researcherProfileId}`; + const requestUUID = '8b3c613a-5a4b-438b-9686-be1d5b4a1c5a'; + + const pageInfo = new PageInfo(); + const array = [researcherProfile, anotherResearcherProfile]; + const paginatedList = buildPaginatedList(pageInfo, array); + const researcherProfileRD = createSuccessfulRemoteDataObject(researcherProfile); + const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); + + beforeEach(() => { + scheduler = getTestScheduler(); + + halService = jasmine.createSpyObj('halService', { + getEndpoint: cold('a', { a: endpointURL }) + }); + + responseCacheEntry = new RequestEntry(); + responseCacheEntry.request = { href: 'https://rest.api/' } as any; + responseCacheEntry.response = new RestResponse(true, 200, 'Success'); + + requestService = jasmine.createSpyObj('requestService', { + generateRequestId: requestUUID, + send: true, + removeByHrefSubstring: {}, + getByHref: observableOf(responseCacheEntry), + getByUUID: observableOf(responseCacheEntry), + setStaleByHrefSubstring: jasmine.createSpy('setStaleByHrefSubstring') + }); + rdbService = jasmine.createSpyObj('rdbService', { + buildSingle: hot('a|', { + a: researcherProfileRD + }), + buildList: hot('a|', { + a: paginatedListRD + }), + buildFromRequestUUID: hot('a|', { + a: researcherProfileRD + }) + }); + objectCache = {} as ObjectCacheService; + const notificationsService = {} as NotificationsService; + const http = {} as HttpClient; + const comparator = {} as any; + const routerStub: any = new RouterMock(); + const itemService = jasmine.createSpyObj('ItemService', { + findByHref: jasmine.createSpy('findByHref') + }); + + service = new ResearcherProfileService( + requestService, + rdbService, + objectCache, + halService, + notificationsService, + http, + routerStub, + comparator, + itemService + ); + serviceAsAny = service; + + spyOn((service as any).dataService, 'create').and.callThrough(); + spyOn((service as any).dataService, 'delete').and.callThrough(); + spyOn((service as any).dataService, 'update').and.callThrough(); + spyOn((service as any).dataService, 'findById').and.callThrough(); + spyOn((service as any).dataService, 'findByHref').and.callThrough(); + spyOn((service as any).dataService, 'searchBy').and.callThrough(); + spyOn((service as any).dataService, 'getLinkPath').and.returnValue(observableOf(endpointURL)); + + }); + + describe('findById', () => { + it('should proxy the call to dataservice.findById with eperson UUID', () => { + scheduler.schedule(() => service.findById(researcherProfileId)); + scheduler.flush(); + + expect((service as any).dataService.findById).toHaveBeenCalledWith(researcherProfileId, true, true); + }); + + it('should return a ResearcherProfile object with the given id', () => { + const result = service.findById(researcherProfileId); + const expected = cold('a|', { + a: researcherProfileRD + }); + expect(result).toBeObservable(expected); + }); + }); + + describe('create', () => { + it('should proxy the call to dataservice.create with eperson UUID', () => { + scheduler.schedule(() => service.create()); + scheduler.flush(); + + expect((service as any).dataService.create).toHaveBeenCalled(); + }); + + it('should return the RemoteData created', () => { + const result = service.create(); + const expected = cold('a|', { + a: researcherProfileRD + }); + expect(result).toBeObservable(expected); + }); + }); + + describe('delete', () => { + it('should proxy the call to dataservice.delete', () => { + scheduler.schedule(() => service.delete(researcherProfile)); + scheduler.flush(); + + expect((service as any).dataService.delete).toHaveBeenCalledWith(researcherProfile.id); + }); + }); + + describe('findRelatedItemId', () => { + describe('with a related item', () => { + + beforeEach(() => { + (service as any).itemService.findByHref.and.returnValue(createSuccessfulRemoteDataObject$(researcherProfileItem)); + }); + + it('should proxy the call to dataservice.findById with eperson UUID', () => { + scheduler.schedule(() => service.findRelatedItemId(researcherProfile)); + scheduler.flush(); + + expect((service as any).itemService.findByHref).toHaveBeenCalledWith(researcherProfile._links.item.href, false); + }); + + it('should return a ResearcherProfile object with the given id', () => { + const result = service.findRelatedItemId(researcherProfile); + const expected = cold('(a|)', { + a: itemId + }); + expect(result).toBeObservable(expected); + }); + }); + + describe('without a related item', () => { + + beforeEach(() => { + (service as any).itemService.findByHref.and.returnValue(createSuccessfulRemoteDataObject$(null)); + }); + + it('should proxy the call to dataservice.findById with eperson UUID', () => { + scheduler.schedule(() => service.findRelatedItemId(researcherProfile)); + scheduler.flush(); + + expect((service as any).itemService.findByHref).toHaveBeenCalledWith(researcherProfile._links.item.href, false); + }); + + it('should return a ResearcherProfile object with the given id', () => { + const result = service.findRelatedItemId(researcherProfile); + const expected = cold('(a|)', { + a: undefined + }); + expect(result).toBeObservable(expected); + }); + }); + }); + + describe('setVisibility', () => { + let patchSpy; + beforeEach(() => { + spyOn((service as any), 'patch').and.returnValue(createSuccessfulRemoteDataObject$(researcherProfilePatched)); + spyOn((service as any), 'findById').and.returnValue(createSuccessfulRemoteDataObject$(researcherProfilePatched)); + }); + + it('should proxy the call to dataservice.patch', () => { + const replaceOperation: ReplaceOperation = { + path: '/visible', + op: 'replace', + value: true + }; + + scheduler.schedule(() => service.setVisibility(researcherProfile, true)); + scheduler.flush(); + + expect((service as any).patch).toHaveBeenCalledWith(researcherProfile, [replaceOperation]); + }); + }); + + describe('createFromExternalSource', () => { + let patchSpy; + beforeEach(() => { + spyOn((service as any), 'patch').and.returnValue(createSuccessfulRemoteDataObject$(researcherProfilePatched)); + spyOn((service as any), 'findById').and.returnValue(createSuccessfulRemoteDataObject$(researcherProfilePatched)); + }); + + it('should proxy the call to dataservice.patch', () => { + const options: HttpOptions = Object.create({}); + let headers = new HttpHeaders(); + headers = headers.append('Content-Type', 'text/uri-list'); + options.headers = headers; + const request = new PostRequest(requestUUID, endpointURL, sourceUri, options); + + scheduler.schedule(() => service.createFromExternalSource(sourceUri)); + scheduler.flush(); + + expect((service as any).requestService.send).toHaveBeenCalledWith(request); + expect((service as any).rdbService.buildFromRequestUUID).toHaveBeenCalledWith(requestUUID); + + }); + }); + +}); diff --git a/src/app/core/profile/researcher-profile.service.ts b/src/app/core/profile/researcher-profile.service.ts index 0220afb964f..eab6ea3d483 100644 --- a/src/app/core/profile/researcher-profile.service.ts +++ b/src/app/core/profile/researcher-profile.service.ts @@ -2,27 +2,25 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; + import { Store } from '@ngrx/store'; -import { Operation, RemoveOperation, ReplaceOperation } from 'fast-json-patch'; -import { combineLatest, Observable, of as observableOf } from 'rxjs'; +import { Operation, ReplaceOperation } from 'fast-json-patch'; +import { Observable, of as observableOf } from 'rxjs'; import { catchError, find, map, switchMap, tap } from 'rxjs/operators'; -import { environment } from '../../../environments/environment'; + import { NotificationsService } from '../../shared/notifications/notifications.service'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { ConfigurationDataService } from '../data/configuration-data.service'; import { DataService } from '../data/data.service'; import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; import { ItemDataService } from '../data/item-data.service'; import { RemoteData } from '../data/remote-data'; import { RequestService } from '../data/request.service'; -import { ConfigurationProperty } from '../shared/configuration-property.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { Item } from '../shared/item.model'; import { NoContent } from '../shared/NoContent.model'; import { - getFinishedRemoteData, + getAllCompletedRemoteData, getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../shared/operators'; @@ -31,25 +29,26 @@ import { RESEARCHER_PROFILE } from './model/researcher-profile.resource-type'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { PostRequest } from '../data/request.models'; import { hasValue } from '../../shared/empty.util'; -import {CoreState} from '../core-state.model'; +import { CoreState } from '../core-state.model'; +import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; /** * A private DataService implementation to delegate specific methods to. */ class ResearcherProfileServiceImpl extends DataService { - protected linkPath = 'profiles'; - - constructor( - protected requestService: RequestService, - protected rdbService: RemoteDataBuildService, - protected store: Store, - protected objectCache: ObjectCacheService, - protected halService: HALEndpointService, - protected notificationsService: NotificationsService, - protected http: HttpClient, - protected comparator: DefaultChangeAnalyzer) { - super(); - } + protected linkPath = 'profiles'; + + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected store: Store, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + protected http: HttpClient, + protected comparator: DefaultChangeAnalyzer) { + super(); + } } @@ -60,100 +59,102 @@ class ResearcherProfileServiceImpl extends DataService { @dataService(RESEARCHER_PROFILE) export class ResearcherProfileService { - dataService: ResearcherProfileServiceImpl; - - responseMsToLive: number = 10 * 1000; - - constructor( - protected requestService: RequestService, - protected rdbService: RemoteDataBuildService, - protected store: Store, - protected objectCache: ObjectCacheService, - protected halService: HALEndpointService, - protected notificationsService: NotificationsService, - protected http: HttpClient, - protected router: Router, - protected comparator: DefaultChangeAnalyzer, - protected itemService: ItemDataService, - protected configurationService: ConfigurationDataService ) { - - this.dataService = new ResearcherProfileServiceImpl(requestService, rdbService, store, objectCache, halService, - notificationsService, http, comparator); - - } - - /** - * Find the researcher profile with the given uuid. - * - * @param uuid the profile uuid - */ - findById(uuid: string): Observable { - return this.dataService.findById(uuid, false) - .pipe ( getFinishedRemoteData(), - map((remoteData) => remoteData.payload)); - } - - /** - * Create a new researcher profile for the current user. - */ - create(): Observable> { - return this.dataService.create( new ResearcherProfile()); - } - - /** - * Delete a researcher profile. - * - * @param researcherProfile the profile to delete - */ - delete(researcherProfile: ResearcherProfile): Observable { - return this.dataService.delete(researcherProfile.id).pipe( - getFirstCompletedRemoteData(), - tap((response: RemoteData) => { - if (response.isSuccess) { - this.requestService.setStaleByHrefSubstring(researcherProfile._links.self.href); - } + dataService: ResearcherProfileServiceImpl; + + responseMsToLive: number = 10 * 1000; + + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + protected http: HttpClient, + protected router: Router, + protected comparator: DefaultChangeAnalyzer, + protected itemService: ItemDataService) { + + this.dataService = new ResearcherProfileServiceImpl(requestService, rdbService, null, objectCache, halService, + notificationsService, http, comparator); + + } + + /** + * Find the researcher profile with the given uuid. + * + * @param uuid the profile uuid + * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's + * no valid cached version. Defaults to true + * @param reRequestOnStale Whether or not the request should automatically be re- + * requested after the response becomes stale + * @param linksToFollow List of {@link FollowLinkConfig} that indicate which + * {@link HALLink}s should be automatically resolved + */ + public findById(uuid: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { + return this.dataService.findById(uuid, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow).pipe( + getAllCompletedRemoteData(), + ); + } + + /** + * Create a new researcher profile for the current user. + */ + public create(): Observable> { + return this.dataService.create(new ResearcherProfile()); + } + + /** + * Delete a researcher profile. + * + * @param researcherProfile the profile to delete + */ + public delete(researcherProfile: ResearcherProfile): Observable { + return this.dataService.delete(researcherProfile.id).pipe( + getFirstCompletedRemoteData(), + tap((response: RemoteData) => { + if (response.isSuccess) { + this.requestService.setStaleByHrefSubstring(researcherProfile._links.self.href); + } + }), + map((response: RemoteData) => response.isSuccess) + ); + } + + /** + * Find the item id related to the given researcher profile. + * + * @param researcherProfile the profile to find for + */ + public findRelatedItemId(researcherProfile: ResearcherProfile): Observable { + return this.itemService.findByHref(researcherProfile._links.item.href, false) + .pipe(getFirstSucceededRemoteDataPayload(), + catchError((error) => { + console.debug(error); + return observableOf(null); }), - map((response: RemoteData) => response.isSuccess) - ); - } - - /** - * Find the item id related to the given researcher profile. - * - * @param researcherProfile the profile to find for - */ - findRelatedItemId( researcherProfile: ResearcherProfile ): Observable { - return this.itemService.findByHref(researcherProfile._links.item.href, false) - .pipe (getFirstSucceededRemoteDataPayload(), - catchError((error) => { - console.debug(error); - return observableOf(null); - }), - map((item) => item != null ? item.id : null )); - } - - /** - * Change the visibility of the given researcher profile setting the given value. - * - * @param researcherProfile the profile to update - * @param visible the visibility value to set - */ - setVisibility(researcherProfile: ResearcherProfile, visible: boolean): Observable { - - const replaceOperation: ReplaceOperation = { - path: '/visible', - op: 'replace', - value: visible - }; - - return this.patch(researcherProfile, [replaceOperation]).pipe ( - switchMap( ( ) => this.findById(researcherProfile.id)) + map((item) => item?.id) ); - } + } - patch(researcherProfile: ResearcherProfile, operations: Operation[]): Observable> { - return this.dataService.patch(researcherProfile, operations); - } + /** + * Change the visibility of the given researcher profile setting the given value. + * + * @param researcherProfile the profile to update + * @param visible the visibility value to set + */ + public setVisibility(researcherProfile: ResearcherProfile, visible: boolean): Observable { + + const replaceOperation: ReplaceOperation = { + path: '/visible', + op: 'replace', + value: visible + }; + + return this.patch(researcherProfile, [replaceOperation]).pipe( + switchMap(() => this.findById(researcherProfile.id)), + getFirstSucceededRemoteDataPayload() + ); + } /** * Creates a researcher profile starting from an external source URI @@ -179,4 +180,7 @@ export class ResearcherProfileService { return this.rdbService.buildFromRequestUUID(requestId); } + private patch(researcherProfile: ResearcherProfile, operations: Operation[]): Observable> { + return this.dataService.patch(researcherProfile, operations); + } } diff --git a/src/app/profile-page/profile-claim/profile-claim.service.spec.ts b/src/app/profile-page/profile-claim/profile-claim.service.spec.ts new file mode 100644 index 00000000000..4030c7900c9 --- /dev/null +++ b/src/app/profile-page/profile-claim/profile-claim.service.spec.ts @@ -0,0 +1,215 @@ +import { cold, getTestScheduler } from 'jasmine-marbles'; + +import { of as observableOf } from 'rxjs'; +import { TestScheduler } from 'rxjs/testing'; + +import { ProfileClaimService } from './profile-claim.service'; +import { SearchService } from '../../core/shared/search/search.service'; +import { ItemSearchResult } from '../../shared/object-collection/shared/item-search-result.model'; +import { SearchObjects } from '../../shared/search/models/search-objects.model'; +import { Item } from '../../core/shared/item.model'; +import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; +import { EPerson } from '../../core/eperson/models/eperson.model'; + +describe('ProfileClaimService', () => { + let scheduler: TestScheduler; + let service: ProfileClaimService; + let serviceAsAny: any; + let searchService: jasmine.SpyObj; + + const eperson: EPerson = Object.assign(new EPerson(), { + id: 'id', + metadata: { + 'eperson.firstname': [ + { + value: 'John' + } + ], + 'eperson.lastname': [ + { + value: 'Doe' + }, + ], + }, + email: 'fake@email.com' + }); + const item1: Item = Object.assign(new Item(), { + uuid: 'e1c51c69-896d-42dc-8221-1d5f2ad5516e', + metadata: { + 'person.email': [ + { + value: 'fake@email.com' + } + ], + 'person.familyName': [ + { + value: 'Doe' + } + ], + 'person.givenName': [ + { + value: 'John' + } + ] + }, + _links: { + self: { + href: 'item-href' + } + } + }); + const item2: Item = Object.assign(new Item(), { + uuid: 'c8279647-1acc-41ae-b036-951d5f65649b', + metadata: { + 'person.email': [ + { + value: 'fake2@email.com' + } + ], + 'dc.title': [ + { + value: 'John, Doe' + } + ] + }, + _links: { + self: { + href: 'item-href' + } + } + }); + const item3: Item = Object.assign(new Item(), { + uuid: 'c8279647-1acc-41ae-b036-951d5f65649b', + metadata: { + 'person.email': [ + { + value: 'fake3@email.com' + } + ], + 'dc.title': [ + { + value: 'John, Doe' + } + ] + }, + _links: { + self: { + href: 'item-href' + } + } + }); + + const searchResult1 = Object.assign(new ItemSearchResult(), { indexableObject: item1 }); + const searchResult2 = Object.assign(new ItemSearchResult(), { indexableObject: item2 }); + const searchResult3 = Object.assign(new ItemSearchResult(), { indexableObject: item3 }); + + const searchResult = Object.assign(new SearchObjects(), { + page: [searchResult1, searchResult2, searchResult3] + }); + const emptySearchResult = Object.assign(new SearchObjects(), { + page: [] + }); + const searchResultRD = createSuccessfulRemoteDataObject(searchResult); + const emptyRearchResultRD = createSuccessfulRemoteDataObject(emptySearchResult); + + beforeEach(() => { + scheduler = getTestScheduler(); + + searchService = jasmine.createSpyObj('SearchService', { + search: jasmine.createSpy('search') + }); + + service = new ProfileClaimService(searchService); + serviceAsAny = service; + }); + + describe('hasProfilesToSuggest', () => { + + describe('when has suggestions', () => { + beforeEach(() => { + spyOn(service, 'search').and.returnValue(observableOf(searchResultRD)); + }); + + it('should return true', () => { + const result = service.hasProfilesToSuggest(eperson); + const expected = cold('(a|)', { + a: true + }); + expect(result).toBeObservable(expected); + }); + + }); + + describe('when has not suggestions', () => { + beforeEach(() => { + spyOn(service, 'search').and.returnValue(observableOf(emptyRearchResultRD)); + }); + + it('should return false', () => { + const result = service.hasProfilesToSuggest(eperson); + const expected = cold('(a|)', { + a: false + }); + expect(result).toBeObservable(expected); + }); + + }); + + describe('when has not valid eperson', () => { + it('should return false', () => { + const result = service.hasProfilesToSuggest(null); + const expected = cold('(a|)', { + a: false + }); + expect(result).toBeObservable(expected); + }); + + }); + + }); + + describe('search', () => { + + describe('when has search results', () => { + beforeEach(() => { + searchService.search.and.returnValue(observableOf(searchResultRD)); + }); + + it('should return the proper search object', () => { + const result = service.search(eperson); + const expected = cold('(a|)', { + a: searchResultRD + }); + expect(result).toBeObservable(expected); + }); + + }); + + describe('when has not suggestions', () => { + beforeEach(() => { + searchService.search.and.returnValue(observableOf(emptyRearchResultRD)); + }); + + it('should return null', () => { + const result = service.search(eperson); + const expected = cold('(a|)', { + a: emptyRearchResultRD + }); + expect(result).toBeObservable(expected); + }); + + }); + + describe('when has not valid eperson', () => { + it('should return null', () => { + const result = service.search(null); + const expected = cold('(a|)', { + a: null + }); + expect(result).toBeObservable(expected); + }); + + }); + + }); +}); diff --git a/src/app/profile-page/profile-claim/profile-claim.service.ts b/src/app/profile-page/profile-claim/profile-claim.service.ts index 9ee24627788..a61404540b1 100644 --- a/src/app/profile-page/profile-claim/profile-claim.service.ts +++ b/src/app/profile-page/profile-claim/profile-claim.service.ts @@ -1,16 +1,16 @@ import { Injectable } from '@angular/core'; + import { Observable, of } from 'rxjs'; -import { mergeMap, take } from 'rxjs/operators'; -import { ConfigurationDataService } from '../../core/data/configuration-data.service'; -import { PaginatedList } from '../../core/data/paginated-list.model'; +import { map } from 'rxjs/operators'; + import { RemoteData } from '../../core/data/remote-data'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { SearchService } from '../../core/shared/search/search.service'; -import { hasValue } from '../../shared/empty.util'; +import { isEmpty, isNotEmpty } from '../../shared/empty.util'; import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; -import { SearchResult } from '../../shared/search/models/search-result.model'; -import { getFirstSucceededRemoteData } from './../../core/shared/operators'; +import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { SearchObjects } from '../../shared/search/models/search-objects.model'; /** * Service that handle profiles claim. @@ -18,8 +18,7 @@ import { getFirstSucceededRemoteData } from './../../core/shared/operators'; @Injectable() export class ProfileClaimService { - constructor(private searchService: SearchService, - private configurationService: ConfigurationDataService) { + constructor(private searchService: SearchService) { } /** @@ -27,27 +26,21 @@ export class ProfileClaimService { * * @param eperson the eperson */ - canClaimProfiles(eperson: EPerson): Observable { - - const query = this.personQueryData(eperson); - - if (!hasValue(query) || query.length === 0) { - return of(false); - } - - return this.lookup(query).pipe( - mergeMap((rd: RemoteData>>) => of(rd.payload.totalElements > 0)) + hasProfilesToSuggest(eperson: EPerson): Observable { + return this.search(eperson).pipe( + map((rd: RemoteData>) => { + return isNotEmpty(rd) && rd.hasSucceeded && rd.payload?.page?.length > 0; + }) ); - } /** * Returns profiles that could be associated with the given user. * @param eperson the user */ - search(eperson: EPerson): Observable>>> { + search(eperson: EPerson): Observable>> { const query = this.personQueryData(eperson); - if (!hasValue(query) || query.length === 0) { + if (isEmpty(query)) { return of(null); } return this.lookup(query); @@ -57,21 +50,31 @@ export class ProfileClaimService { * Search object by the given query. * @param query the query for the search */ - private lookup(query: string): Observable>>> { - if (!hasValue(query)) { + private lookup(query: string): Observable>> { + if (isEmpty(query)) { return of(null); } return this.searchService.search(new PaginatedSearchOptions({ configuration: 'eperson_claims', query: query - })) - .pipe( - getFirstSucceededRemoteData(), - take(1)); + })).pipe( + getFirstCompletedRemoteData() + ); } + /** + * Return the search query for person lookup, from the given eperson + * + * @param eperson The eperson to use for the lookup + */ private personQueryData(eperson: EPerson): string { - return 'dc.title:' + eperson.name; + if (eperson) { + const firstname = eperson.firstMetadataValue('eperson.firstname'); + const lastname = eperson.firstMetadataValue('eperson.lastname'); + return 'dc.title:' + eperson.name + ' OR (person.familyName:' + lastname + ' AND person.givenName:' + firstname + ')'; + } else { + return null; + } } } diff --git a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.spec.ts b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.spec.ts index d12c445ce4e..b928b20eefc 100644 --- a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.spec.ts +++ b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.spec.ts @@ -16,6 +16,7 @@ import { ProfilePageResearcherFormComponent } from './profile-page-researcher-fo import { ProfileClaimService } from '../profile-claim/profile-claim.service'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { AuthService } from 'src/app/core/auth/auth.service'; +import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; describe('ProfilePageResearcherFormComponent', () => { @@ -51,7 +52,7 @@ describe('ProfilePageResearcherFormComponent', () => { }); researcherProfileService = jasmine.createSpyObj('researcherProfileService', { - findById: observableOf(profile), + findById: createSuccessfulRemoteDataObject$(profile), create: observableOf(profile), setVisibility: observableOf(profile), delete: observableOf(true), @@ -61,7 +62,7 @@ describe('ProfilePageResearcherFormComponent', () => { notificationsServiceStub = new NotificationsServiceStub(); profileClaimService = jasmine.createSpyObj('profileClaimService', { - canClaimProfiles: observableOf(false), + hasProfilesToSuggest: observableOf(false), }); } @@ -91,7 +92,7 @@ describe('ProfilePageResearcherFormComponent', () => { }); it('should search the researcher profile for the current user', () => { - expect(researcherProfileService.findById).toHaveBeenCalledWith(user.id); + expect(researcherProfileService.findById).toHaveBeenCalledWith(user.id, false); }); describe('createProfile', () => { 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 9bb3028ff4e..a1887f8b319 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 @@ -4,17 +4,18 @@ import { Router } from '@angular/router'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, Observable } from 'rxjs'; -import { filter, mergeMap, switchMap, take, tap } from 'rxjs/operators'; +import { mergeMap, switchMap, take, tap } from 'rxjs/operators'; -import { getFirstCompletedRemoteData } from '../../core/shared/operators'; -import { ClaimItemSelectorComponent } from '../../shared/dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component'; +import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; +import { + ClaimItemSelectorComponent +} from '../../shared/dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { AuthService } from '../../core/auth/auth.service'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { ResearcherProfile } from '../../core/profile/model/researcher-profile.model'; import { ResearcherProfileService } from '../../core/profile/researcher-profile.service'; import { ProfileClaimService } from '../profile-claim/profile-claim.service'; -import { isNotEmpty } from '../../shared/empty.util'; @Component({ selector: 'ds-profile-page-researcher-form', @@ -77,10 +78,10 @@ export class ProfilePageResearcherFormComponent implements OnInit { this.processingCreate$.next(true); this.authService.getAuthenticatedUserFromStore().pipe( - switchMap((currentUser) => this.profileClaimService.canClaimProfiles(currentUser))) - .subscribe((canClaimProfiles) => { + switchMap((currentUser) => this.profileClaimService.hasProfilesToSuggest(currentUser))) + .subscribe((hasProfilesToSuggest) => { - if (canClaimProfiles) { + if (hasProfilesToSuggest) { this.processingCreate$.next(false); const modal = this.modalService.open(ClaimItemSelectorComponent); modal.componentInstance.dso = this.user; @@ -174,9 +175,8 @@ export class ProfilePageResearcherFormComponent implements OnInit { * Initializes the researcherProfile and researcherProfileItemId attributes using the profile of the current user. */ private initResearchProfile(): void { - this.researcherProfileService.findById(this.user.id).pipe( - take(1), - filter((researcherProfile) => isNotEmpty(researcherProfile)), + this.researcherProfileService.findById(this.user.id, false).pipe( + getFirstSucceededRemoteDataPayload(), tap((researcherProfile) => this.researcherProfile$.next(researcherProfile)), mergeMap((researcherProfile) => this.researcherProfileService.findRelatedItemId(researcherProfile)), ).subscribe((itemId: string) => { diff --git a/src/app/profile-page/profile-page.component.spec.ts b/src/app/profile-page/profile-page.component.spec.ts index 84aec0c0f11..fcbd4d9e4a0 100644 --- a/src/app/profile-page/profile-page.component.spec.ts +++ b/src/app/profile-page/profile-page.component.spec.ts @@ -11,17 +11,17 @@ import { AuthTokenInfo } from '../core/auth/models/auth-token-info.model'; import { EPersonDataService } from '../core/eperson/eperson-data.service'; import { NotificationsService } from '../shared/notifications/notifications.service'; import { authReducer } from '../core/auth/auth.reducer'; -import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils'; +import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils'; import { createPaginatedList } from '../shared/testing/utils.test'; import { BehaviorSubject, of as observableOf } from 'rxjs'; import { AuthService } from '../core/auth/auth.service'; import { RestResponse } from '../core/cache/response.models'; import { provideMockStore } from '@ngrx/store/testing'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; -import { getTestScheduler } from 'jasmine-marbles'; +import { cold, getTestScheduler } from 'jasmine-marbles'; import { By } from '@angular/platform-browser'; -import {ConfigurationDataService} from '../core/data/configuration-data.service'; -import {ConfigurationProperty} from '../core/shared/configuration-property.model'; +import { ConfigurationDataService } from '../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../core/shared/configuration-property.model'; describe('ProfilePageComponent', () => { let component: ProfilePageComponent; @@ -30,16 +30,28 @@ describe('ProfilePageComponent', () => { let initialState: any; let authService; + let authorizationService; let epersonService; let notificationsService; + let configurationService; const canChangePassword = new BehaviorSubject(true); + const validConfiguration = Object.assign(new ConfigurationProperty(), { + name: 'researcher-profile.entity-type', + values: [ + 'Person' + ] + }); + const emptyConfiguration = Object.assign(new ConfigurationProperty(), { + name: 'researcher-profile.entity-type', + values: [] + }); function init() { user = Object.assign(new EPerson(), { id: 'userId', groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: {self: {href: 'test.com/uuid/1234567654321'}} + _links: { self: { href: 'test.com/uuid/1234567654321' } } }); initialState = { core: { @@ -54,7 +66,7 @@ describe('ProfilePageComponent', () => { } } }; - + authorizationService = jasmine.createSpyObj('authorizationService', { isAuthorized: canChangePassword }); authService = jasmine.createSpyObj('authService', { getAuthenticatedUserFromStore: observableOf(user) }); @@ -67,6 +79,9 @@ describe('ProfilePageComponent', () => { error: {}, warning: {} }); + configurationService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: jasmine.createSpy('findByPropertyName') + }); } beforeEach(waitForAsync(() => { @@ -82,15 +97,8 @@ describe('ProfilePageComponent', () => { { provide: EPersonDataService, useValue: epersonService }, { provide: NotificationsService, useValue: notificationsService }, { provide: AuthService, useValue: authService }, - { provide: ConfigurationDataService, useValue: jasmine.createSpyObj('configurationDataService', { - findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { - name: 'researcher-profile.entity-type', - values: [ - 'Person' - ] - })) - })}, - { provide: AuthorizationDataService, useValue: jasmine.createSpyObj('authorizationService', { isAuthorized: canChangePassword }) }, + { provide: ConfigurationDataService, useValue: configurationService }, + { provide: AuthorizationDataService, useValue: authorizationService }, provideMockStore({ initialState }), ], schemas: [NO_ERRORS_SCHEMA] @@ -100,148 +108,206 @@ describe('ProfilePageComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ProfilePageComponent); component = fixture.componentInstance; - fixture.detectChanges(); }); - describe('updateProfile', () => { - describe('when the metadata form returns false and the security form returns true', () => { - beforeEach(() => { - component.metadataForm = jasmine.createSpyObj('metadataForm', { - updateProfile: false - }); - spyOn(component, 'updateSecurity').and.returnValue(true); - component.updateProfile(); - }); + describe('', () => { - it('should not display a warning', () => { - expect(notificationsService.warning).not.toHaveBeenCalled(); - }); + beforeEach(() => { + configurationService.findByPropertyName.and.returnValue(createSuccessfulRemoteDataObject$(validConfiguration)); + fixture.detectChanges(); }); - describe('when the metadata form returns true and the security form returns false', () => { - beforeEach(() => { - component.metadataForm = jasmine.createSpyObj('metadataForm', { - updateProfile: true + describe('updateProfile', () => { + describe('when the metadata form returns false and the security form returns true', () => { + beforeEach(() => { + component.metadataForm = jasmine.createSpyObj('metadataForm', { + updateProfile: false + }); + spyOn(component, 'updateSecurity').and.returnValue(true); + component.updateProfile(); }); - component.updateProfile(); - }); - it('should not display a warning', () => { - expect(notificationsService.warning).not.toHaveBeenCalled(); + it('should not display a warning', () => { + expect(notificationsService.warning).not.toHaveBeenCalled(); + }); }); - }); - describe('when the metadata form returns true and the security form returns true', () => { - beforeEach(() => { - component.metadataForm = jasmine.createSpyObj('metadataForm', { - updateProfile: true + describe('when the metadata form returns true and the security form returns false', () => { + beforeEach(() => { + component.metadataForm = jasmine.createSpyObj('metadataForm', { + updateProfile: true + }); + component.updateProfile(); }); - component.updateProfile(); - }); - it('should not display a warning', () => { - expect(notificationsService.warning).not.toHaveBeenCalled(); + it('should not display a warning', () => { + expect(notificationsService.warning).not.toHaveBeenCalled(); + }); }); - }); - describe('when the metadata form returns false and the security form returns false', () => { - beforeEach(() => { - component.metadataForm = jasmine.createSpyObj('metadataForm', { - updateProfile: false + describe('when the metadata form returns true and the security form returns true', () => { + beforeEach(() => { + component.metadataForm = jasmine.createSpyObj('metadataForm', { + updateProfile: true + }); + component.updateProfile(); + }); + + it('should not display a warning', () => { + expect(notificationsService.warning).not.toHaveBeenCalled(); }); - component.updateProfile(); }); - it('should display a warning', () => { - expect(notificationsService.warning).toHaveBeenCalled(); + describe('when the metadata form returns false and the security form returns false', () => { + beforeEach(() => { + component.metadataForm = jasmine.createSpyObj('metadataForm', { + updateProfile: false + }); + component.updateProfile(); + }); + + it('should display a warning', () => { + expect(notificationsService.warning).toHaveBeenCalled(); + }); }); }); - }); - describe('updateSecurity', () => { - describe('when no password value present', () => { - let result; + describe('updateSecurity', () => { + describe('when no password value present', () => { + let result; - beforeEach(() => { - component.setPasswordValue(''); + beforeEach(() => { + component.setPasswordValue(''); - result = component.updateSecurity(); - }); + result = component.updateSecurity(); + }); - it('should return false', () => { - expect(result).toEqual(false); - }); + it('should return false', () => { + expect(result).toEqual(false); + }); - it('should not call epersonService.patch', () => { - expect(epersonService.patch).not.toHaveBeenCalled(); + it('should not call epersonService.patch', () => { + expect(epersonService.patch).not.toHaveBeenCalled(); + }); }); - }); - describe('when password is filled in, but the password is invalid', () => { - let result; + describe('when password is filled in, but the password is invalid', () => { + let result; - beforeEach(() => { - component.setPasswordValue('test'); - component.setInvalid(true); - result = component.updateSecurity(); + beforeEach(() => { + component.setPasswordValue('test'); + component.setInvalid(true); + result = component.updateSecurity(); + }); + + it('should return true', () => { + expect(result).toEqual(true); + expect(epersonService.patch).not.toHaveBeenCalled(); + }); }); - it('should return true', () => { - expect(result).toEqual(true); - expect(epersonService.patch).not.toHaveBeenCalled(); + describe('when password is filled in, and is valid', () => { + let result; + let operations; + + beforeEach(() => { + component.setPasswordValue('testest'); + component.setInvalid(false); + + operations = [{ op: 'add', path: '/password', value: 'testest' }]; + result = component.updateSecurity(); + }); + + it('should return true', () => { + expect(result).toEqual(true); + }); + + it('should return call epersonService.patch', () => { + expect(epersonService.patch).toHaveBeenCalledWith(user, operations); + }); }); }); - describe('when password is filled in, and is valid', () => { - let result; - let operations; + describe('canChangePassword$', () => { + describe('when the user is allowed to change their password', () => { + beforeEach(() => { + canChangePassword.next(true); + }); - beforeEach(() => { - component.setPasswordValue('testest'); - component.setInvalid(false); + it('should contain true', () => { + getTestScheduler().expectObservable(component.canChangePassword$).toBe('(a)', { a: true }); + }); - operations = [{ op: 'add', path: '/password', value: 'testest' }]; - result = component.updateSecurity(); + it('should show the security section on the page', () => { + fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('.security-section'))).not.toBeNull(); + }); }); - it('should return true', () => { - expect(result).toEqual(true); - }); + describe('when the user is not allowed to change their password', () => { + beforeEach(() => { + canChangePassword.next(false); + }); - it('should return call epersonService.patch', () => { - expect(epersonService.patch).toHaveBeenCalledWith(user, operations); + it('should contain false', () => { + getTestScheduler().expectObservable(component.canChangePassword$).toBe('(a)', { a: false }); + }); + + it('should not show the security section on the page', () => { + fixture.detectChanges(); + expect(fixture.debugElement.query(By.css('.security-section'))).toBeNull(); + }); }); }); }); - describe('canChangePassword$', () => { - describe('when the user is allowed to change their password', () => { - beforeEach(() => { - canChangePassword.next(true); - }); + describe('isResearcherProfileEnabled', () => { - it('should contain true', () => { - getTestScheduler().expectObservable(component.canChangePassword$).toBe('(a)', { a: true }); - }); + describe('when configuration service return values', () => { - it('should show the security section on the page', () => { + beforeEach(() => { + configurationService.findByPropertyName.and.returnValue(createSuccessfulRemoteDataObject$(validConfiguration)); fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('.security-section'))).not.toBeNull(); + }); + + it('should return true', () => { + const result = component.isResearcherProfileEnabled(); + const expected = cold('a', { + a: true + }); + expect(result).toBeObservable(expected); }); }); - describe('when the user is not allowed to change their password', () => { + describe('when configuration service return no values', () => { + beforeEach(() => { - canChangePassword.next(false); + configurationService.findByPropertyName.and.returnValue(createSuccessfulRemoteDataObject$(emptyConfiguration)); + fixture.detectChanges(); }); - it('should contain false', () => { - getTestScheduler().expectObservable(component.canChangePassword$).toBe('(a)', { a: false }); + it('should return false', () => { + const result = component.isResearcherProfileEnabled(); + const expected = cold('a', { + a: false + }); + expect(result).toBeObservable(expected); }); + }); - it('should not show the security section on the page', () => { + describe('when configuration service return an error', () => { + + beforeEach(() => { + configurationService.findByPropertyName.and.returnValue(createFailedRemoteDataObject$()); fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('.security-section'))).toBeNull(); + }); + + it('should return false', () => { + const result = component.isResearcherProfileEnabled(); + const expected = cold('a', { + a: false + }); + expect(result).toBeObservable(expected); }); }); }); diff --git a/src/app/profile-page/profile-page.component.ts b/src/app/profile-page/profile-page.component.ts index 9c22c8c950d..374fa5220b4 100644 --- a/src/app/profile-page/profile-page.component.ts +++ b/src/app/profile-page/profile-page.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, ViewChild } from '@angular/core'; -import {BehaviorSubject, Observable} from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; import { EPerson } from '../core/eperson/models/eperson.model'; import { ProfilePageMetadataFormComponent } from './profile-page-metadata-form/profile-page-metadata-form.component'; import { NotificationsService } from '../shared/notifications/notifications.service'; @@ -9,18 +9,15 @@ import { RemoteData } from '../core/data/remote-data'; import { PaginatedList } from '../core/data/paginated-list.model'; import { filter, switchMap, tap } from 'rxjs/operators'; import { EPersonDataService } from '../core/eperson/eperson-data.service'; -import { - getAllSucceededRemoteData, - getRemoteDataPayload, - getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload -} from '../core/shared/operators'; +import { getAllSucceededRemoteData, getFirstCompletedRemoteData, getRemoteDataPayload } from '../core/shared/operators'; import { hasValue, isNotEmpty } from '../shared/empty.util'; import { followLink } from '../shared/utils/follow-link-config.model'; import { AuthService } from '../core/auth/auth.service'; import { Operation } from 'fast-json-patch'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../core/data/feature-authorization/feature-id'; -import {ConfigurationDataService} from '../core/data/configuration-data.service'; +import { ConfigurationDataService } from '../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../core/shared/configuration-property.model'; @Component({ selector: 'ds-profile-page', @@ -94,8 +91,10 @@ export class ProfilePageComponent implements OnInit { this.canChangePassword$ = this.user$.pipe(switchMap((user: EPerson) => this.authorizationService.isAuthorized(FeatureID.CanChangePassword, user._links.self.href))); this.configurationService.findByPropertyName('researcher-profile.entity-type').pipe( - getFirstSucceededRemoteDataPayload() - ).subscribe(() => this.isResearcherProfileEnabled$.next(true)); + getFirstCompletedRemoteData() + ).subscribe((configRD: RemoteData) => { + this.isResearcherProfileEnabled$.next(configRD.hasSucceeded && configRD.payload.values.length > 0); + }); } /** @@ -175,8 +174,8 @@ export class ProfilePageComponent implements OnInit { /** * Returns true if the researcher profile feature is enabled, false otherwise. */ - isResearcherProfileEnabled(){ - return this.isResearcherProfileEnabled$; + isResearcherProfileEnabled(): Observable { + return this.isResearcherProfileEnabled$.asObservable(); } } diff --git a/yarn.lock b/yarn.lock index c06853e625e..65c1a61abac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8884,11 +8884,6 @@ ngx-ui-switch@^11.0.1: resolved "https://registry.yarnpkg.com/ngx-ui-switch/-/ngx-ui-switch-11.0.1.tgz#c7f1e97ebe698f827a26f49951b50492b22c7839" integrity sha512-N8QYT/wW+xJdyh/aeebTSLPA6Sgrwp69H6KAcW0XZueg/LF+FKiqyG6Po/gFHq2gDhLikwyJEMpny8sudTI08w== -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - nice-napi@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nice-napi/-/nice-napi-1.0.2.tgz#dc0ab5a1eac20ce548802fc5686eaa6bc654927b" From 1e9d393edf1e5ccb5c5849c1e4d9dfe4e8dfc5c6 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 11 May 2022 11:59:38 +0200 Subject: [PATCH 199/409] [CST-5307] Move profile-claim-item-modal.component to profile page module and add unit tests --- .../profile-claim-item-modal.component.html} | 4 +- ...profile-claim-item-modal.component.spec.ts | 223 ++++++++++++++++++ .../profile-claim-item-modal.component.ts | 105 +++++++++ src/app/profile-page/profile-page.module.ts | 6 +- .../claim-item-selector.component.spec.ts | 45 ---- .../claim-item-selector.component.ts | 69 ------ src/app/shared/shared.module.ts | 8 +- 7 files changed, 336 insertions(+), 124 deletions(-) rename src/app/{shared/dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component.html => profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html} (93%) create mode 100644 src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.spec.ts create mode 100644 src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.ts delete mode 100644 src/app/shared/dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component.spec.ts delete mode 100644 src/app/shared/dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component.ts diff --git a/src/app/shared/dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component.html b/src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html similarity index 93% rename from src/app/shared/dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component.html rename to src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html index 9df49ba24b4..eec9f437f1e 100644 --- a/src/app/shared/dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component.html +++ b/src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html @@ -14,7 +14,7 @@
@@ -26,7 +26,7 @@
diff --git a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html index 7c8ce67b88f..6703634b6b2 100644 --- a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html +++ b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html @@ -57,12 +57,12 @@

[relationTypes]="[{ label: 'isOrgUnitOfPerson', filter: 'isOrgUnitOfPerson', - configuration: 'person' + configuration: 'person-relationships' }, { label: 'isOrgUnitOfProject', filter: 'isOrgUnitOfProject', - configuration: 'project' + configuration: 'project-relationships' }]"> diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.html b/src/app/entity-groups/research-entities/item-pages/person/person.component.html index 6e71f775d6b..4b7b3bed326 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.html +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.html @@ -68,7 +68,8 @@

From 36208d13033f1b33d1bfaf15a84c18a7a3ccb593 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 11 May 2022 12:01:35 +0200 Subject: [PATCH 201/409] [CST-5307] Fix visibility toggle and address review feedback --- .../profile/researcher-profile.service.ts | 14 ++-- .../profile-claim.service.spec.ts | 16 ++--- .../profile-claim/profile-claim.service.ts | 8 ++- ...rofile-page-researcher-form.component.html | 9 ++- ...ile-page-researcher-form.component.spec.ts | 68 ++++++++++++++----- .../profile-page-researcher-form.component.ts | 19 +++--- src/assets/i18n/en.json5 | 2 + 7 files changed, 89 insertions(+), 47 deletions(-) diff --git a/src/app/core/profile/researcher-profile.service.ts b/src/app/core/profile/researcher-profile.service.ts index eab6ea3d483..0c39396950a 100644 --- a/src/app/core/profile/researcher-profile.service.ts +++ b/src/app/core/profile/researcher-profile.service.ts @@ -6,7 +6,7 @@ import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { Operation, ReplaceOperation } from 'fast-json-patch'; import { Observable, of as observableOf } from 'rxjs'; -import { catchError, find, map, switchMap, tap } from 'rxjs/operators'; +import { catchError, find, map, tap } from 'rxjs/operators'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { dataService } from '../cache/builders/build-decorators'; @@ -142,18 +142,14 @@ export class ResearcherProfileService { * @param researcherProfile the profile to update * @param visible the visibility value to set */ - public setVisibility(researcherProfile: ResearcherProfile, visible: boolean): Observable { - + public setVisibility(researcherProfile: ResearcherProfile, visible: boolean): Observable> { const replaceOperation: ReplaceOperation = { path: '/visible', op: 'replace', value: visible }; - return this.patch(researcherProfile, [replaceOperation]).pipe( - switchMap(() => this.findById(researcherProfile.id)), - getFirstSucceededRemoteDataPayload() - ); + return this.patch(researcherProfile, [replaceOperation]); } /** @@ -181,6 +177,8 @@ export class ResearcherProfileService { } private patch(researcherProfile: ResearcherProfile, operations: Operation[]): Observable> { - return this.dataService.patch(researcherProfile, operations); + return this.dataService.patch(researcherProfile, operations).pipe( + getFirstCompletedRemoteData() + ); } } diff --git a/src/app/profile-page/profile-claim/profile-claim.service.spec.ts b/src/app/profile-page/profile-claim/profile-claim.service.spec.ts index 4030c7900c9..a06934231ba 100644 --- a/src/app/profile-page/profile-claim/profile-claim.service.spec.ts +++ b/src/app/profile-page/profile-claim/profile-claim.service.spec.ts @@ -110,7 +110,7 @@ describe('ProfileClaimService', () => { page: [] }); const searchResultRD = createSuccessfulRemoteDataObject(searchResult); - const emptyRearchResultRD = createSuccessfulRemoteDataObject(emptySearchResult); + const emptySearchResultRD = createSuccessfulRemoteDataObject(emptySearchResult); beforeEach(() => { scheduler = getTestScheduler(); @@ -127,7 +127,7 @@ describe('ProfileClaimService', () => { describe('when has suggestions', () => { beforeEach(() => { - spyOn(service, 'search').and.returnValue(observableOf(searchResultRD)); + spyOn(service, 'searchForSuggestions').and.returnValue(observableOf(searchResultRD)); }); it('should return true', () => { @@ -142,7 +142,7 @@ describe('ProfileClaimService', () => { describe('when has not suggestions', () => { beforeEach(() => { - spyOn(service, 'search').and.returnValue(observableOf(emptyRearchResultRD)); + spyOn(service, 'searchForSuggestions').and.returnValue(observableOf(emptySearchResultRD)); }); it('should return false', () => { @@ -176,7 +176,7 @@ describe('ProfileClaimService', () => { }); it('should return the proper search object', () => { - const result = service.search(eperson); + const result = service.searchForSuggestions(eperson); const expected = cold('(a|)', { a: searchResultRD }); @@ -187,13 +187,13 @@ describe('ProfileClaimService', () => { describe('when has not suggestions', () => { beforeEach(() => { - searchService.search.and.returnValue(observableOf(emptyRearchResultRD)); + searchService.search.and.returnValue(observableOf(emptySearchResultRD)); }); it('should return null', () => { - const result = service.search(eperson); + const result = service.searchForSuggestions(eperson); const expected = cold('(a|)', { - a: emptyRearchResultRD + a: emptySearchResultRD }); expect(result).toBeObservable(expected); }); @@ -202,7 +202,7 @@ describe('ProfileClaimService', () => { describe('when has not valid eperson', () => { it('should return null', () => { - const result = service.search(null); + const result = service.searchForSuggestions(null); const expected = cold('(a|)', { a: null }); diff --git a/src/app/profile-page/profile-claim/profile-claim.service.ts b/src/app/profile-page/profile-claim/profile-claim.service.ts index a61404540b1..62517c4b219 100644 --- a/src/app/profile-page/profile-claim/profile-claim.service.ts +++ b/src/app/profile-page/profile-claim/profile-claim.service.ts @@ -27,7 +27,7 @@ export class ProfileClaimService { * @param eperson the eperson */ hasProfilesToSuggest(eperson: EPerson): Observable { - return this.search(eperson).pipe( + return this.searchForSuggestions(eperson).pipe( map((rd: RemoteData>) => { return isNotEmpty(rd) && rd.hasSucceeded && rd.payload?.page?.length > 0; }) @@ -36,9 +36,10 @@ export class ProfileClaimService { /** * Returns profiles that could be associated with the given user. + * * @param eperson the user */ - search(eperson: EPerson): Observable>> { + searchForSuggestions(eperson: EPerson): Observable>> { const query = this.personQueryData(eperson); if (isEmpty(query)) { return of(null); @@ -48,6 +49,7 @@ export class ProfileClaimService { /** * Search object by the given query. + * * @param query the query for the search */ private lookup(query: string): Observable>> { @@ -71,7 +73,7 @@ export class ProfileClaimService { if (eperson) { const firstname = eperson.firstMetadataValue('eperson.firstname'); const lastname = eperson.firstMetadataValue('eperson.lastname'); - return 'dc.title:' + eperson.name + ' OR (person.familyName:' + lastname + ' AND person.givenName:' + firstname + ')'; + return '(dc.title:' + eperson.name + ') OR (person.familyName:' + lastname + ' AND person.givenName:' + firstname + ')'; } else { return null; } 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 bb554187446..2d959c1dfea 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 @@ -3,14 +3,17 @@

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

{{'researcher.profile.status' | translate}} - +

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

- + diff --git a/src/app/shared/rss-feed/rss.component.html b/src/app/shared/rss-feed/rss.component.html new file mode 100644 index 00000000000..8868539b5c0 --- /dev/null +++ b/src/app/shared/rss-feed/rss.component.html @@ -0,0 +1,5 @@ + +
+ +
+ diff --git a/src/app/shared/rss-feed/rss.component.scss b/src/app/shared/rss-feed/rss.component.scss new file mode 100644 index 00000000000..929bb453ac5 --- /dev/null +++ b/src/app/shared/rss-feed/rss.component.scss @@ -0,0 +1,12 @@ +:host { + .dropdown-toggle::after { + display: none; + } + .dropdown-item { + padding-left: 20px; + } +} + +.margin-right { + margin-right: .5em; +} \ No newline at end of file diff --git a/src/app/shared/rss-feed/rss.component.spec.ts b/src/app/shared/rss-feed/rss.component.spec.ts new file mode 100644 index 00000000000..bbfd5442b3f --- /dev/null +++ b/src/app/shared/rss-feed/rss.component.spec.ts @@ -0,0 +1,109 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { RemoteData } from '../../core/data/remote-data'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { PaginationService } from '../../core/pagination/pagination.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { Collection } from '../../core/shared/collection.model'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; +import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; +import { PaginatedSearchOptions } from '../search/paginated-search-options.model'; +import { PaginationServiceStub } from '../testing/pagination-service.stub'; +import { createPaginatedList } from '../testing/utils.test'; +import { RSSComponent } from './rss.component'; +import { of as observableOf } from 'rxjs'; + + + +describe('RssComponent', () => { + let comp: RSSComponent; + let options: SortOptions; + let fixture: ComponentFixture; + let uuid: string; + let query: string; + let groupDataService: GroupDataService; + let linkHeadService: LinkHeadService; + let configurationDataService: ConfigurationDataService; + let paginationService; + + beforeEach(waitForAsync(() => { + const mockCollection: Collection = Object.assign(new Collection(), { + id: 'ce41d451-97ed-4a9c-94a1-7de34f16a9f4', + name: 'test-collection', + _links: { + mappedItems: { + href: 'https://rest.api/collections/ce41d451-97ed-4a9c-94a1-7de34f16a9f4/mappedItems' + }, + self: { + href: 'https://rest.api/collections/ce41d451-97ed-4a9c-94a1-7de34f16a9f4' + } + } + }); + configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + const mockCollectionRD: RemoteData = createSuccessfulRemoteDataObject(mockCollection); + const mockSearchOptions = observableOf(new PaginatedSearchOptions({ + pagination: Object.assign(new PaginationComponentOptions(), { + id: 'search-page-configuration', + pageSize: 10, + currentPage: 1 + }), + sort: new SortOptions('dc.title', SortDirection.ASC), + scope: mockCollection.id + })); + groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '' + }); + paginationService = new PaginationServiceStub(); + const searchConfigService = { + paginatedSearchOptions: mockSearchOptions + }; + TestBed.configureTestingModule({ + providers: [ + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: searchConfigService}, + { provide: PaginationService, useValue: paginationService } + ], + declarations: [RSSComponent] + }).compileComponents(); + })); + + beforeEach(() => { + options = new SortOptions('dc.title', SortDirection.DESC); + uuid = '2cfcf65e-0a51-4bcb-8592-b8db7b064790'; + query = 'test'; + fixture = TestBed.createComponent(RSSComponent); + comp = fixture.componentInstance; + }); + + it('should formulate the correct url given params in url', () => { + const route = comp.formulateRoute(uuid, options, query); + expect(route).toBe('/opensearch/search?format=atom&scope=2cfcf65e-0a51-4bcb-8592-b8db7b064790&sort=dc.title&sort_direction=DESC&query=test'); + }); + + it('should skip uuid if its null', () => { + const route = comp.formulateRoute(null, options, query); + expect(route).toBe('/opensearch/search?format=atom&sort=dc.title&sort_direction=DESC&query=test'); + }); + + it('should default to query * if none provided', () => { + const route = comp.formulateRoute(null, options, null); + expect(route).toBe('/opensearch/search?format=atom&sort=dc.title&sort_direction=DESC&query=*'); + }); +}); + diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts new file mode 100644 index 00000000000..036148b368e --- /dev/null +++ b/src/app/shared/rss-feed/rss.component.ts @@ -0,0 +1,94 @@ +import { + ChangeDetectionStrategy, + Component, + OnDestroy, + OnInit, + ViewEncapsulation +} from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { environment } from '../../../../src/environments/environment'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { SortOptions } from '../../core/cache/models/sort-options.model'; +import { PaginationService } from '../../core/pagination/pagination.service'; + + +/** + * The default pagination controls component. + */ +@Component({ + exportAs: 'rssComponent', + selector: 'ds-rss', + styleUrls: ['rss.component.scss'], + templateUrl: 'rss.component.html', + changeDetection: ChangeDetectionStrategy.Default, + encapsulation: ViewEncapsulation.Emulated +}) +export class RSSComponent implements OnInit, OnDestroy { + + route$: BehaviorSubject; + + isEnabled$: BehaviorSubject = new BehaviorSubject(false); + + uuid: string; + configuration$: Observable; + sortOption$: Observable; + + constructor(private groupDataService: GroupDataService, + private linkHeadService: LinkHeadService, + private configurationService: ConfigurationDataService, + private searchConfigurationService: SearchConfigurationService, + protected paginationService: PaginationService) { + } + ngOnDestroy(): void { + this.linkHeadService.removeTag("rel='alternate'"); + } + + ngOnInit(): void { + this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); + + this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( + getFirstCompletedRemoteData(), + ).subscribe((result) => { + const enabled = Boolean(result.payload.values[0]); + this.isEnabled$.next(enabled); + }); + + this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { + this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); + this.sortOption$.subscribe((sort) => { + this.uuid = this.groupDataService.getUUIDFromString(window.location.href); + + const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, sort, query); + + this.linkHeadService.addTag({ + href: route, + type: 'application/atom+xml', + rel: 'alternate', + title: 'Sitewide Atom feed' + }); + this.route$ = new BehaviorSubject(route); + }); + }); + } + + formulateRoute(uuid: string, sort: SortOptions, query: string): string { + let route = 'search?format=atom'; + if (uuid) { + route += `&scope=${uuid}`; + } + if (sort.direction && sort.field) { + route += `&sort=${sort.field}&sort_direction=${sort.direction}`; + } + if (query) { + route += `&query=${query}`; + } else { + route += `&query=*`; + } + route = '/opensearch/' + route; + return route; + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 12b6a482dcd..c70aff61920 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -173,10 +173,9 @@ import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-p import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; -import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component'; +import { RSSComponent } from './rss-feed/rss.component'; const MODULES = [ - // Do NOT include UniversalModule, HttpModule, or JsonpModule here CommonModule, SortablejsModule, FileUploadModule, @@ -239,6 +238,7 @@ const COMPONENTS = [ AbstractListableElementComponent, ObjectCollectionComponent, PaginationComponent, + RSSComponent, SearchFormComponent, PageWithSidebarComponent, SidebarDropdownComponent, diff --git a/src/environments/environment.dev.ts b/src/environments/environment.dev.ts new file mode 100644 index 00000000000..999abd32eeb --- /dev/null +++ b/src/environments/environment.dev.ts @@ -0,0 +1,17 @@ +export const environment = { + ui: { + ssl: false, + host: 'localhost', + port: 18080, + nameSpace: '/' + }, + rest: { + ssl: false, + host: 'localhost', + port: 8080, + nameSpace: '/server' + }, + universal: { + preboot: false + } +}; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 00000000000..c31da7b791f --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,17 @@ +export const environment = { + ui: { + ssl: false, + host: 'localhost', + port: 18080, + nameSpace: '/' + }, + rest: { + ssl: false, + host: 'localhost', + port: 8080, + nameSpace: '/server' + }, + universal: { + preboot: true + } +}; From b8a96e48a7b885cc4424b720bfb9dbf012e82f23 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 10 Dec 2021 12:25:51 -0500 Subject: [PATCH 206/409] Fix test files to pass down necessary providers --- .../collection-item-mapper.component.spec.ts | 28 ++++++++++++++++- ...page-sub-collection-list.component.spec.ts | 31 +++++++++++++++++++ ...-page-sub-community-list.component.spec.ts | 30 ++++++++++++++++++ src/app/core/services/link-head.service.ts | 8 +---- ...top-level-community-list.component.spec.ts | 30 ++++++++++++++++++ .../edit-relationship-list.component.spec.ts | 29 +++++++++++++++++ .../collection-select.component.spec.ts | 31 ++++++++++++++++++- .../item-select/item-select.component.spec.ts | 30 +++++++++++++++++- src/app/shared/rss-feed/rss.component.scss | 2 +- src/app/shared/rss-feed/rss.component.spec.ts | 7 +++-- .../search-configuration-service.stub.ts | 4 +++ 11 files changed, 216 insertions(+), 14 deletions(-) diff --git a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts index 7f0e6815ed1..142604c9b24 100644 --- a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts +++ b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts @@ -43,6 +43,10 @@ import { createPaginatedList } from '../../shared/testing/utils.test'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { MyDSpacePageComponent, SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component'; import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; describe('CollectionItemMapperComponent', () => { let comp: CollectionItemMapperComponent; @@ -143,6 +147,25 @@ describe('CollectionItemMapperComponent', () => { isAuthorized: observableOf(true) }); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [CommonModule, FormsModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule], @@ -159,7 +182,10 @@ describe('CollectionItemMapperComponent', () => { { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, { provide: ObjectSelectService, useValue: new ObjectSelectServiceStub() }, { provide: RouteService, useValue: routeServiceStub }, - { provide: AuthorizationDataService, useValue: authorizationDataService } + { provide: AuthorizationDataService, useValue: authorizationDataService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, ] }).overrideComponent(CollectionItemMapperComponent, { set: { diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts index ec61fac6130..c0ce5369ff6 100644 --- a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts @@ -25,6 +25,14 @@ import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { SearchServiceStub } from '../../shared/testing/search-service.stub'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { createPaginatedList } from '../../shared/testing/utils.test'; +import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; describe('CommunityPageSubCollectionList Component', () => { let comp: CommunityPageSubCollectionListComponent; @@ -122,6 +130,25 @@ describe('CommunityPageSubCollectionList Component', () => { themeService = getMockThemeService(); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ @@ -138,6 +165,10 @@ describe('CommunityPageSubCollectionList Component', () => { { provide: PaginationService, useValue: paginationService }, { provide: SelectableListService, useValue: {} }, { provide: ThemeService, useValue: themeService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts index 2bc829a3b05..3392ada9943 100644 --- a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts +++ b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts @@ -25,6 +25,13 @@ import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { createPaginatedList } from '../../shared/testing/utils.test'; describe('CommunityPageSubCommunityListComponent Component', () => { let comp: CommunityPageSubCommunityListComponent; @@ -119,6 +126,25 @@ describe('CommunityPageSubCommunityListComponent Component', () => { } }; + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + const paginationService = new PaginationServiceStub(); themeService = getMockThemeService(); @@ -139,6 +165,10 @@ describe('CommunityPageSubCommunityListComponent Component', () => { { provide: PaginationService, useValue: paginationService }, { provide: SelectableListService, useValue: {} }, { provide: ThemeService, useValue: themeService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/core/services/link-head.service.ts b/src/app/core/services/link-head.service.ts index 29ab62ff137..12c3ff197d8 100644 --- a/src/app/core/services/link-head.service.ts +++ b/src/app/core/services/link-head.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Optional, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core'; +import { Injectable, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; @Injectable() @@ -22,7 +22,6 @@ export class LinkHeadService { const link = renderer.createElement('link'); const head = this.document.head; - const selector = this._parseSelector(tag); if (head === null) { throw new Error(' not found within DOCUMENT.'); @@ -61,11 +60,6 @@ export class LinkHeadService { } } } - - private _parseSelector(tag: LinkDefinition): string { - const attr: string = tag.rel ? 'rel' : 'hreflang'; - return `${attr}="${tag[attr]}"`; - } } export declare type LinkDefinition = { diff --git a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts index eb52ca9243e..2561770942d 100644 --- a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts +++ b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts @@ -25,6 +25,13 @@ import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { createPaginatedList } from '../../shared/testing/utils.test'; +import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; describe('TopLevelCommunityList Component', () => { let comp: TopLevelCommunityListComponent; @@ -114,6 +121,25 @@ describe('TopLevelCommunityList Component', () => { themeService = getMockThemeService(); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ @@ -130,6 +156,10 @@ describe('TopLevelCommunityList Component', () => { { provide: PaginationService, useValue: paginationService }, { provide: SelectableListService, useValue: {} }, { provide: ThemeService, useValue: themeService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); 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 b0d8046cf4f..f9e889bba59 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 @@ -23,6 +23,12 @@ import { PaginationComponent } from '../../../../shared/pagination/pagination.co import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; import { RelationshipTypeService } from '../../../../core/data/relationship-type.service'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; +import { GroupDataService } from '../../../../core/eperson/group-data.service'; +import { ConfigurationDataService } from '../../../../core/data/configuration-data.service'; +import { LinkHeadService } from '../../../../core/services/link-head.service'; +import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; +import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service.stub'; +import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model'; let comp: EditRelationshipListComponent; let fixture: ComponentFixture; @@ -174,6 +180,25 @@ describe('EditRelationshipListComponent', () => { hostWindowService = new HostWindowServiceStub(1200); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + TestBed.configureTestingModule({ imports: [SharedModule, TranslateModule.forRoot()], declarations: [EditRelationshipListComponent], @@ -185,6 +210,10 @@ describe('EditRelationshipListComponent', () => { { provide: PaginationService, useValue: paginationService }, { provide: HostWindowService, useValue: hostWindowService }, { provide: RelationshipTypeService, useValue: relationshipTypeService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [ NO_ERRORS_SCHEMA ] diff --git a/src/app/shared/object-select/collection-select/collection-select.component.spec.ts b/src/app/shared/object-select/collection-select/collection-select.component.spec.ts index 5714db23858..1b89fd32c19 100644 --- a/src/app/shared/object-select/collection-select/collection-select.component.spec.ts +++ b/src/app/shared/object-select/collection-select/collection-select.component.spec.ts @@ -17,6 +17,12 @@ import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../testing/pagination-service.stub'; import { of as observableOf } from 'rxjs'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { LinkHeadService } from '../../../core/services/link-head.service'; +import { GroupDataService } from '../../../core/eperson/group-data.service'; +import { ConfigurationDataService } from '../../../core/data/configuration-data.service'; +import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; +import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; +import { ConfigurationProperty } from '../../../core/shared/configuration-property.model'; describe('CollectionSelectComponent', () => { let comp: CollectionSelectComponent; @@ -44,6 +50,25 @@ describe('CollectionSelectComponent', () => { isAuthorized: observableOf(true) }); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + const paginationService = new PaginationServiceStub(); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -53,7 +78,11 @@ describe('CollectionSelectComponent', () => { { provide: ObjectSelectService, useValue: new ObjectSelectServiceStub([mockCollectionList[1].id]) }, { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, { provide: PaginationService, useValue: paginationService }, - { provide: AuthorizationDataService, useValue: authorizationDataService } + { provide: AuthorizationDataService, useValue: authorizationDataService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); 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 de52f1c3c25..25340ee8628 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 @@ -18,6 +18,12 @@ import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../testing/pagination-service.stub'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; +import { ConfigurationDataService } from '../../../core/data/configuration-data.service'; +import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; +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'; describe('ItemSelectComponent', () => { let comp: ItemSelectComponent; @@ -70,6 +76,24 @@ describe('ItemSelectComponent', () => { const authorizationDataService = new AuthorizationDataService(null, null, null, null, null, null, null, null, null, null); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -79,7 +103,11 @@ describe('ItemSelectComponent', () => { { provide: ObjectSelectService, useValue: new ObjectSelectServiceStub([mockItemList[1].id]) }, { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, { provide: PaginationService, useValue: paginationService }, - { provide: AuthorizationDataService, useValue: authorizationDataService } + { provide: AuthorizationDataService, useValue: authorizationDataService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/shared/rss-feed/rss.component.scss b/src/app/shared/rss-feed/rss.component.scss index 929bb453ac5..91310eddcba 100644 --- a/src/app/shared/rss-feed/rss.component.scss +++ b/src/app/shared/rss-feed/rss.component.scss @@ -9,4 +9,4 @@ .margin-right { margin-right: .5em; -} \ No newline at end of file +} diff --git a/src/app/shared/rss-feed/rss.component.spec.ts b/src/app/shared/rss-feed/rss.component.spec.ts index bbfd5442b3f..cbdc2a2d0ee 100644 --- a/src/app/shared/rss-feed/rss.component.spec.ts +++ b/src/app/shared/rss-feed/rss.component.spec.ts @@ -15,6 +15,7 @@ import { PaginationServiceStub } from '../testing/pagination-service.stub'; import { createPaginatedList } from '../testing/utils.test'; import { RSSComponent } from './rss.component'; import { of as observableOf } from 'rxjs'; +import { SearchConfigurationServiceStub } from '../testing/search-configuration-service.stub'; @@ -61,11 +62,11 @@ describe('RssComponent', () => { currentPage: 1 }), sort: new SortOptions('dc.title', SortDirection.ASC), - scope: mockCollection.id })); groupDataService = jasmine.createSpyObj('groupsDataService', { findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), - getGroupRegistryRouterLink: '' + getGroupRegistryRouterLink: '', + getUUIDFromString: '', }); paginationService = new PaginationServiceStub(); const searchConfigService = { @@ -76,7 +77,7 @@ describe('RssComponent', () => { { provide: GroupDataService, useValue: groupDataService }, { provide: LinkHeadService, useValue: linkHeadService }, { provide: ConfigurationDataService, useValue: configurationDataService }, - { provide: SearchConfigurationService, useValue: searchConfigService}, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, { provide: PaginationService, useValue: paginationService } ], declarations: [RSSComponent] diff --git a/src/app/shared/testing/search-configuration-service.stub.ts b/src/app/shared/testing/search-configuration-service.stub.ts index 80744ba59a6..78b358f0d47 100644 --- a/src/app/shared/testing/search-configuration-service.stub.ts +++ b/src/app/shared/testing/search-configuration-service.stub.ts @@ -17,6 +17,10 @@ export class SearchConfigurationServiceStub { return observableOf('test-id'); } + getCurrentQuery(a) { + return observableOf(a); + } + getCurrentConfiguration(a) { return observableOf(a); } From b5943b48b47009a7f771db99530d57d5be2fd1fc Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 25 Feb 2022 12:14:16 -0500 Subject: [PATCH 207/409] w2p-86403 fix opensearch is disabled, router issues and links --- src/app/core/services/link-head.service.ts | 3 ++ src/app/shared/rss-feed/rss.component.ts | 32 +++++++++++++++++----- src/app/shared/shared.module.ts | 4 +++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/app/core/services/link-head.service.ts b/src/app/core/services/link-head.service.ts index 12c3ff197d8..af5dddec8d6 100644 --- a/src/app/core/services/link-head.service.ts +++ b/src/app/core/services/link-head.service.ts @@ -1,6 +1,9 @@ import { Injectable, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; +/** + * LinkHead Service injects tag into the head element during runtime. + */ @Injectable() export class LinkHeadService { constructor( diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 036148b368e..11286e19e39 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -14,10 +14,11 @@ import { environment } from '../../../../src/environments/environment'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SortOptions } from '../../core/cache/models/sort-options.model'; import { PaginationService } from '../../core/pagination/pagination.service'; +import { Router } from '@angular/router'; /** - * The default pagination controls component. + * The Rss feed button componenet. */ @Component({ exportAs: 'rssComponent', @@ -41,6 +42,7 @@ export class RSSComponent implements OnInit, OnDestroy { private linkHeadService: LinkHeadService, private configurationService: ConfigurationDataService, private searchConfigurationService: SearchConfigurationService, + private router: Router, protected paginationService: PaginationService) { } ngOnDestroy(): void { @@ -53,22 +55,22 @@ export class RSSComponent implements OnInit, OnDestroy { this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( getFirstCompletedRemoteData(), ).subscribe((result) => { - const enabled = Boolean(result.payload.values[0]); + const enabled = (result.payload.values[0] === 'true'); this.isEnabled$.next(enabled); }); this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); this.sortOption$.subscribe((sort) => { - this.uuid = this.groupDataService.getUUIDFromString(window.location.href); + this.uuid = this.groupDataService.getUUIDFromString(this.router.url); const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, sort, query); - + this.addLinks(route); this.linkHeadService.addTag({ - href: route, + href: environment.rest.baseUrl + '/opensearch/service', type: 'application/atom+xml', - rel: 'alternate', - title: 'Sitewide Atom feed' + rel: 'search', + title: 'Dspace' }); this.route$ = new BehaviorSubject(route); }); @@ -91,4 +93,20 @@ export class RSSComponent implements OnInit, OnDestroy { route = '/opensearch/' + route; return route; } + + addLinks(route: string): void { + this.linkHeadService.addTag({ + href: route, + type: 'application/atom+xml', + rel: 'alternate', + title: 'Sitewide Atom feed' + }); + route = route.replace('format=atom', 'format=rss'); + this.linkHeadService.addTag({ + href: route, + type: 'application/rss+xml', + rel: 'alternate', + title: 'Sitewide RSS feed' + }); + } } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index c70aff61920..c6cc3d2bd98 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -174,6 +174,10 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { RSSComponent } from './rss-feed/rss.component'; +import { SearchObjects } from './search/models/search-objects.model'; +import { FacetConfigResponse } from './search/models/facet-config-response.model'; +import { SearchResult } from './search/models/search-result.model'; +import { FacetValues } from './search/models/facet-values.model'; const MODULES = [ CommonModule, From efb76ea88328df3d03706ad3c5f0411dcf7077a9 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 25 Feb 2022 12:35:17 -0500 Subject: [PATCH 208/409] Fix tests now that router is apart of the rss component --- .../edit-relationship-list.component.spec.ts | 3 +++ src/app/shared/rss-feed/rss.component.spec.ts | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) 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 f9e889bba59..2403d8f4430 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 @@ -29,6 +29,8 @@ import { LinkHeadService } from '../../../../core/services/link-head.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service.stub'; import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model'; +import { Router } from '@angular/router'; +import { RouterMock } from '../../../../shared/mocks/router.mock'; let comp: EditRelationshipListComponent; let fixture: ComponentFixture; @@ -211,6 +213,7 @@ describe('EditRelationshipListComponent', () => { { provide: HostWindowService, useValue: hostWindowService }, { provide: RelationshipTypeService, useValue: relationshipTypeService }, { provide: GroupDataService, useValue: groupDataService }, + { provide: Router, useValue: new RouterMock() }, { provide: LinkHeadService, useValue: linkHeadService }, { provide: ConfigurationDataService, useValue: configurationDataService }, { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, diff --git a/src/app/shared/rss-feed/rss.component.spec.ts b/src/app/shared/rss-feed/rss.component.spec.ts index cbdc2a2d0ee..b304abda833 100644 --- a/src/app/shared/rss-feed/rss.component.spec.ts +++ b/src/app/shared/rss-feed/rss.component.spec.ts @@ -10,12 +10,14 @@ import { ConfigurationProperty } from '../../core/shared/configuration-property. import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; -import { PaginatedSearchOptions } from '../search/paginated-search-options.model'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; import { createPaginatedList } from '../testing/utils.test'; import { RSSComponent } from './rss.component'; import { of as observableOf } from 'rxjs'; import { SearchConfigurationServiceStub } from '../testing/search-configuration-service.stub'; +import { PaginatedSearchOptions } from '../search/models/paginated-search-options.model'; +import { Router } from '@angular/router'; +import { RouterMock } from '../mocks/router.mock'; @@ -78,7 +80,8 @@ describe('RssComponent', () => { { provide: LinkHeadService, useValue: linkHeadService }, { provide: ConfigurationDataService, useValue: configurationDataService }, { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, - { provide: PaginationService, useValue: paginationService } + { provide: PaginationService, useValue: paginationService }, + { provide: Router, useValue: new RouterMock() } ], declarations: [RSSComponent] }).compileComponents(); From ffb34da3e74ce1354f3a29559adf36b856947344 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 25 Feb 2022 14:56:36 -0500 Subject: [PATCH 209/409] Create link head spec file --- .../core/services/link-head.service.spec.ts | 45 +++++++++++++++++++ src/app/core/services/link-head.service.ts | 17 +++++-- 2 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 src/app/core/services/link-head.service.spec.ts diff --git a/src/app/core/services/link-head.service.spec.ts b/src/app/core/services/link-head.service.spec.ts new file mode 100644 index 00000000000..017fe6af03d --- /dev/null +++ b/src/app/core/services/link-head.service.spec.ts @@ -0,0 +1,45 @@ +import { DOCUMENT } from '@angular/common'; +import { Renderer2, RendererFactory2 } from '@angular/core'; +import { TestBed, waitForAsync } from '@angular/core/testing'; +import { MockProvider } from 'ng-mocks'; +import { LinkHeadService } from './link-head.service'; + +describe('LinkHeadService', () => { + + let service: LinkHeadService; + + const renderer2: Renderer2 = { + createRenderer: jasmine.createSpy('createRenderer'), + createElement: jasmine.createSpy('createElement'), + setAttribute: jasmine.createSpy('setAttribute'), + appendChild: jasmine.createSpy('appendChild') + } as unknown as Renderer2; + + beforeEach(waitForAsync(() => { + return TestBed.configureTestingModule({ + providers: [ + MockProvider(RendererFactory2, { + createRenderer: () => renderer2 + }), + { provide: Document, useExisting: DOCUMENT }, + ] + }); + })); + + beforeEach(() => { + service = new LinkHeadService(TestBed.inject(RendererFactory2), TestBed.inject(DOCUMENT)); + }); + + describe('link', () => { + it('should create a link tag', () => { + const link = service.addTag({ + href: 'test', + type: 'application/atom+xml', + rel: 'alternate', + title: 'Sitewide Atom feed' + }); + expect(link).not.toBeUndefined(); + }); + }); + +}); diff --git a/src/app/core/services/link-head.service.ts b/src/app/core/services/link-head.service.ts index af5dddec8d6..39552a44d36 100644 --- a/src/app/core/services/link-head.service.ts +++ b/src/app/core/services/link-head.service.ts @@ -12,7 +12,13 @@ export class LinkHeadService { ) { } - addTag(tag: LinkDefinition, forceCreation?: boolean) { + + /** + * Method to create a Link tag in the HEAD of the html. + * @param tag LinkDefition is the paramaters to define a link tag. + * @returns Link tag that was created + */ + addTag(tag: LinkDefinition) { try { const renderer = this.rendererFactory.createRenderer(this.document, { @@ -23,7 +29,8 @@ export class LinkHeadService { }); const link = renderer.createElement('link'); - + console.log(tag); + console.log(link); const head = this.document.head; if (head === null) { @@ -35,12 +42,16 @@ export class LinkHeadService { }); renderer.appendChild(head, link); - + return renderer; } catch (e) { console.error('Error within linkService : ', e); } } + /** + * Removes a link tag in header based on the given attrSelector. + * @param attrSelector The attr assigned to a link tag which will be used to determine what link to remove. + */ removeTag(attrSelector: string) { if (attrSelector) { try { From 2b9383d2d59c47d6f90a2f5a43fdabd43d351d14 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Mon, 18 Apr 2022 12:33:29 -0400 Subject: [PATCH 210/409] remove unused import from rebase --- src/app/shared/shared.module.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index c6cc3d2bd98..c70aff61920 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -174,10 +174,6 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { RSSComponent } from './rss-feed/rss.component'; -import { SearchObjects } from './search/models/search-objects.model'; -import { FacetConfigResponse } from './search/models/facet-config-response.model'; -import { SearchResult } from './search/models/search-result.model'; -import { FacetValues } from './search/models/facet-values.model'; const MODULES = [ CommonModule, From 0bf0e1f2742aa253d4a442a83eebb64ea680902a Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Mon, 18 Apr 2022 13:30:35 -0400 Subject: [PATCH 211/409] add providers to browseby --- .../browse-by/browse-by.component.spec.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) 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 d71d100ca55..8bda44b11c8 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -38,6 +38,13 @@ import { HostWindowService } from '../host-window.service'; import { RouteService } from '../../core/services/route.service'; import { routeServiceStub } from '../testing/route-service.stub'; import SpyObj = jasmine.SpyObj; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { createPaginatedList } from '../testing/utils.test'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { SearchConfigurationServiceStub } from '../testing/search-configuration-service.stub'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; @listableObjectComponent(BrowseEntry, ViewMode.ListElement, DEFAULT_CONTEXT, 'custom') @Component({ @@ -73,6 +80,25 @@ describe('BrowseByComponent', () => { ]; const mockItemsRD$ = createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), mockItems)); + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + const paginationConfig = Object.assign(new PaginationComponentOptions(), { id: 'test-pagination', currentPage: 1, @@ -103,6 +129,10 @@ describe('BrowseByComponent', () => { ], declarations: [], providers: [ + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: GroupDataService, useValue: groupDataService }, { provide: PaginationService, useValue: paginationService }, { provide: MockThemedBrowseEntryListElementComponent }, { provide: ThemeService, useValue: themeService }, From be8a8f5f6bf9359eecc8034b22c522fe9ac1389f Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Wed, 27 Apr 2022 16:13:01 -0400 Subject: [PATCH 212/409] Add typedocs and websvc.opensearch.svccontext --- src/app/core/services/link-head.service.ts | 2 - src/app/shared/rss-feed/rss.component.spec.ts | 6 +-- src/app/shared/rss-feed/rss.component.ts | 53 +++++++++++++------ src/app/shared/shared.module.ts | 1 + src/environments/environment.dev.ts | 17 ------ src/environments/environment.prod.ts | 17 ------ 6 files changed, 41 insertions(+), 55 deletions(-) delete mode 100644 src/environments/environment.dev.ts delete mode 100644 src/environments/environment.prod.ts diff --git a/src/app/core/services/link-head.service.ts b/src/app/core/services/link-head.service.ts index 39552a44d36..d608618ca4d 100644 --- a/src/app/core/services/link-head.service.ts +++ b/src/app/core/services/link-head.service.ts @@ -29,8 +29,6 @@ export class LinkHeadService { }); const link = renderer.createElement('link'); - console.log(tag); - console.log(link); const head = this.document.head; if (head === null) { diff --git a/src/app/shared/rss-feed/rss.component.spec.ts b/src/app/shared/rss-feed/rss.component.spec.ts index b304abda833..fc19c65e607 100644 --- a/src/app/shared/rss-feed/rss.component.spec.ts +++ b/src/app/shared/rss-feed/rss.component.spec.ts @@ -96,17 +96,17 @@ describe('RssComponent', () => { }); it('should formulate the correct url given params in url', () => { - const route = comp.formulateRoute(uuid, options, query); + const route = comp.formulateRoute(uuid, 'opensearch', options, query); expect(route).toBe('/opensearch/search?format=atom&scope=2cfcf65e-0a51-4bcb-8592-b8db7b064790&sort=dc.title&sort_direction=DESC&query=test'); }); it('should skip uuid if its null', () => { - const route = comp.formulateRoute(null, options, query); + const route = comp.formulateRoute(null, 'opensearch', options, query); expect(route).toBe('/opensearch/search?format=atom&sort=dc.title&sort_direction=DESC&query=test'); }); it('should default to query * if none provided', () => { - const route = comp.formulateRoute(null, options, null); + const route = comp.formulateRoute(null, 'opensearch', options, null); expect(route).toBe('/opensearch/search?format=atom&sort=dc.title&sort_direction=DESC&query=*'); }); }); diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 11286e19e39..456e6279419 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -45,10 +45,17 @@ export class RSSComponent implements OnInit, OnDestroy { private router: Router, protected paginationService: PaginationService) { } + /** + * Removes the linktag created when the component gets removed from the page. + */ ngOnDestroy(): void { this.linkHeadService.removeTag("rel='alternate'"); } + + /** + * Generates the link tags and the url to opensearch when the component is loaded. + */ ngOnInit(): void { this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); @@ -58,26 +65,36 @@ export class RSSComponent implements OnInit, OnDestroy { const enabled = (result.payload.values[0] === 'true'); this.isEnabled$.next(enabled); }); - - this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { - this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); - this.sortOption$.subscribe((sort) => { - this.uuid = this.groupDataService.getUUIDFromString(this.router.url); - - const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, sort, query); - this.addLinks(route); - this.linkHeadService.addTag({ - href: environment.rest.baseUrl + '/opensearch/service', - type: 'application/atom+xml', - rel: 'search', - title: 'Dspace' + this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( + getFirstCompletedRemoteData(), + ).subscribe((url) => { + this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { + this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); + this.sortOption$.subscribe((sort) => { + this.uuid = this.groupDataService.getUUIDFromString(this.router.url); + const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, url.payload.values[0], sort, query); + this.addLinks(route); + this.linkHeadService.addTag({ + href: environment.rest.baseUrl + '/' + url.payload.values[0] + '/service', + type: 'application/atom+xml', + rel: 'search', + title: 'Dspace' + }); + this.route$ = new BehaviorSubject(route); }); - this.route$ = new BehaviorSubject(route); }); }); } - formulateRoute(uuid: string, sort: SortOptions, query: string): string { + /** + * Function created a route given the different params available to opensearch + * @param uuid The uuid if a scope is present + * @param opensearch openSearch uri + * @param sort The sort options for the opensearch request + * @param query The query string that was provided in the search + * @returns The combine URL to opensearch + */ + formulateRoute(uuid: string, opensearch: string, sort: SortOptions, query: string): string { let route = 'search?format=atom'; if (uuid) { route += `&scope=${uuid}`; @@ -90,10 +107,14 @@ export class RSSComponent implements OnInit, OnDestroy { } else { route += `&query=*`; } - route = '/opensearch/' + route; + route = '/' + opensearch +'/' + route; return route; } + /** + * Creates tags in the header of the page + * @param route The composed url to opensearch + */ addLinks(route: string): void { this.linkHeadService.addTag({ href: route, diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index c70aff61920..7c6fe6657a6 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -174,6 +174,7 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { RSSComponent } from './rss-feed/rss.component'; +import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component'; const MODULES = [ CommonModule, diff --git a/src/environments/environment.dev.ts b/src/environments/environment.dev.ts deleted file mode 100644 index 999abd32eeb..00000000000 --- a/src/environments/environment.dev.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const environment = { - ui: { - ssl: false, - host: 'localhost', - port: 18080, - nameSpace: '/' - }, - rest: { - ssl: false, - host: 'localhost', - port: 8080, - nameSpace: '/server' - }, - universal: { - preboot: false - } -}; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts deleted file mode 100644 index c31da7b791f..00000000000 --- a/src/environments/environment.prod.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const environment = { - ui: { - ssl: false, - host: 'localhost', - port: 18080, - nameSpace: '/' - }, - rest: { - ssl: false, - host: 'localhost', - port: 8080, - nameSpace: '/server' - }, - universal: { - preboot: true - } -}; From 90f1fc186c12719fe5f62f2606ef6daf29d22777 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Thu, 28 Apr 2022 09:36:09 -0400 Subject: [PATCH 213/409] Link fixes --- src/app/shared/rss-feed/rss.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 456e6279419..d3970199951 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -89,7 +89,7 @@ export class RSSComponent implements OnInit, OnDestroy { /** * Function created a route given the different params available to opensearch * @param uuid The uuid if a scope is present - * @param opensearch openSearch uri + * @param opensearch openSearch uri * @param sort The sort options for the opensearch request * @param query The query string that was provided in the search * @returns The combine URL to opensearch @@ -107,7 +107,7 @@ export class RSSComponent implements OnInit, OnDestroy { } else { route += `&query=*`; } - route = '/' + opensearch +'/' + route; + route = '/' + opensearch + '/' + route; return route; } From 8785270363a4d54ec1bc22d8c90571b7f9ba081d Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Thu, 28 Apr 2022 15:51:21 -0400 Subject: [PATCH 214/409] w2p-86403 Changed to subscribe and unsubscribe on destory --- src/app/shared/rss-feed/rss.component.ts | 53 ++++++++++++++---------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index d3970199951..56ed052a9fb 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -5,7 +5,7 @@ import { OnInit, ViewEncapsulation } from '@angular/core'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { GroupDataService } from '../../core/eperson/group-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; @@ -15,6 +15,9 @@ import { SearchConfigurationService } from '../../core/shared/search/search-conf import { SortOptions } from '../../core/cache/models/sort-options.model'; import { PaginationService } from '../../core/pagination/pagination.service'; import { Router } from '@angular/router'; +import { map, switchMap } from 'rxjs/operators'; +import { RemoteData } from '../../core/data/remote-data'; +import { PaginatedSearchOptions } from '../search/models/paginated-search-options.model'; /** @@ -32,12 +35,14 @@ export class RSSComponent implements OnInit, OnDestroy { route$: BehaviorSubject; - isEnabled$: BehaviorSubject = new BehaviorSubject(false); + isEnabled$: BehaviorSubject = new BehaviorSubject(null); uuid: string; configuration$: Observable; sortOption$: Observable; + subs: Subscription[] = []; + constructor(private groupDataService: GroupDataService, private linkHeadService: LinkHeadService, private configurationService: ConfigurationDataService, @@ -50,6 +55,9 @@ export class RSSComponent implements OnInit, OnDestroy { */ ngOnDestroy(): void { this.linkHeadService.removeTag("rel='alternate'"); + this.subs.forEach(sub => { + sub.unsubscribe(); + }); } @@ -59,31 +67,32 @@ export class RSSComponent implements OnInit, OnDestroy { ngOnInit(): void { this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); - this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( + this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( getFirstCompletedRemoteData(), ).subscribe((result) => { const enabled = (result.payload.values[0] === 'true'); this.isEnabled$.next(enabled); - }); - this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( + })); + this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( getFirstCompletedRemoteData(), - ).subscribe((url) => { - this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { - this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); - this.sortOption$.subscribe((sort) => { - this.uuid = this.groupDataService.getUUIDFromString(this.router.url); - const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, url.payload.values[0], sort, query); - this.addLinks(route); - this.linkHeadService.addTag({ - href: environment.rest.baseUrl + '/' + url.payload.values[0] + '/service', - type: 'application/atom+xml', - rel: 'search', - title: 'Dspace' - }); - this.route$ = new BehaviorSubject(route); - }); + map((response: RemoteData) => response.payload.values[0]), + switchMap((openSearchUri: string) => + this.searchConfigurationService.paginatedSearchOptions.pipe( + map((searchOptions: PaginatedSearchOptions) => ({ openSearchUri, searchOptions })) + ) + ), + ).subscribe(({ openSearchUri, searchOptions }) => { + this.uuid = this.groupDataService.getUUIDFromString(this.router.url); + const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, openSearchUri, searchOptions.sort, searchOptions.query); + this.addLinks(route); + this.linkHeadService.addTag({ + href: environment.rest.baseUrl + '/' + openSearchUri + '/service', + type: 'application/atom+xml', + rel: 'search', + title: 'Dspace' }); - }); + this.route$ = new BehaviorSubject(route); + })); } /** @@ -99,7 +108,7 @@ export class RSSComponent implements OnInit, OnDestroy { if (uuid) { route += `&scope=${uuid}`; } - if (sort.direction && sort.field) { + if (sort && sort.direction && sort.field) { route += `&sort=${sort.field}&sort_direction=${sort.direction}`; } if (query) { From 6cd22fa004b52077ad63c02cd302c1c4d4fb1342 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Wed, 4 May 2022 15:27:10 -0400 Subject: [PATCH 215/409] w2p-86403 prevent from displaying on pages where rss feed doesn't make sense --- src/app/shared/rss-feed/rss.component.html | 2 +- src/app/shared/rss-feed/rss.component.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/app/shared/rss-feed/rss.component.html b/src/app/shared/rss-feed/rss.component.html index 8868539b5c0..895a9c2f97d 100644 --- a/src/app/shared/rss-feed/rss.component.html +++ b/src/app/shared/rss-feed/rss.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 56ed052a9fb..20fb040013c 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -120,6 +120,17 @@ export class RSSComponent implements OnInit, OnDestroy { return route; } + /** + * Check if the router url contains the specified route + * + * @param {string} route + * @returns + * @memberof MyComponent + */ + hasRoute(route: string) { + return this.router.url.includes(route); + } + /** * Creates tags in the header of the page * @param route The composed url to opensearch From eacbcfd15d803ea02dede2530934458f336a0e46 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 6 May 2022 10:15:51 -0400 Subject: [PATCH 216/409] Change to withNotEmptyPayload to pass through if its empty --- src/app/shared/rss-feed/rss.component.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 20fb040013c..880ed8b558b 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -9,7 +9,7 @@ import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { GroupDataService } from '../../core/eperson/group-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; -import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../core/shared/operators'; import { environment } from '../../../../src/environments/environment'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SortOptions } from '../../core/cache/models/sort-options.model'; @@ -68,14 +68,14 @@ export class RSSComponent implements OnInit, OnDestroy { this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( - getFirstCompletedRemoteData(), + getFirstSucceededRemoteDataWithNotEmptyPayload(), ).subscribe((result) => { - const enabled = (result.payload.values[0] === 'true'); + const enabled = (result.values[0] === 'true'); this.isEnabled$.next(enabled); })); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( - getFirstCompletedRemoteData(), - map((response: RemoteData) => response.payload.values[0]), + getFirstSucceededRemoteDataWithNotEmptyPayload(), + map((result) => result.values[0]), switchMap((openSearchUri: string) => this.searchConfigurationService.paginatedSearchOptions.pipe( map((searchOptions: PaginatedSearchOptions) => ({ openSearchUri, searchOptions })) From cb1b7ceb0a8e134fc1b277de97b83c34931b2115 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 6 May 2022 10:17:30 -0400 Subject: [PATCH 217/409] remove rss feed from search --- src/app/shared/rss-feed/rss.component.html | 2 +- src/app/shared/rss-feed/rss.component.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.html b/src/app/shared/rss-feed/rss.component.html index 895a9c2f97d..e86e72d15a9 100644 --- a/src/app/shared/rss-feed/rss.component.html +++ b/src/app/shared/rss-feed/rss.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 880ed8b558b..1d76daabf11 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -9,14 +9,13 @@ import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { GroupDataService } from '../../core/eperson/group-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; -import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../core/shared/operators'; +import { getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../core/shared/operators'; import { environment } from '../../../../src/environments/environment'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SortOptions } from '../../core/cache/models/sort-options.model'; import { PaginationService } from '../../core/pagination/pagination.service'; import { Router } from '@angular/router'; import { map, switchMap } from 'rxjs/operators'; -import { RemoteData } from '../../core/data/remote-data'; import { PaginatedSearchOptions } from '../search/models/paginated-search-options.model'; From 79bf27c659aff1fb798954ce826dcb949dcdbf69 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 6 May 2022 14:03:14 -0400 Subject: [PATCH 218/409] Revert to getFirstCompletedRemoteData but check if payload has completed --- src/app/shared/rss-feed/rss.component.ts | 25 +++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 1d76daabf11..9a101e8310f 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -9,7 +9,7 @@ import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { GroupDataService } from '../../core/eperson/group-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; -import { getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../core/shared/operators'; +import { getFirstCompletedRemoteData } from '../../core/shared/operators'; import { environment } from '../../../../src/environments/environment'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SortOptions } from '../../core/cache/models/sort-options.model'; @@ -17,6 +17,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { Router } from '@angular/router'; import { map, switchMap } from 'rxjs/operators'; import { PaginatedSearchOptions } from '../search/models/paginated-search-options.model'; +import { RemoteData } from '../../core/data/remote-data'; /** @@ -67,20 +68,30 @@ export class RSSComponent implements OnInit, OnDestroy { this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( - getFirstSucceededRemoteDataWithNotEmptyPayload(), + getFirstCompletedRemoteData(), ).subscribe((result) => { - const enabled = (result.values[0] === 'true'); - this.isEnabled$.next(enabled); + if (result.hasSucceeded) { + const enabled = (result.payload.values[0] === 'true'); + this.isEnabled$.next(enabled); + } })); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( - getFirstSucceededRemoteDataWithNotEmptyPayload(), - map((result) => result.values[0]), - switchMap((openSearchUri: string) => + getFirstCompletedRemoteData(), + map((result: RemoteData) => { + if (result.hasSucceeded) { + return result.payload.values[0]; + } + return null; + }), + switchMap((openSearchUri: string) => this.searchConfigurationService.paginatedSearchOptions.pipe( map((searchOptions: PaginatedSearchOptions) => ({ openSearchUri, searchOptions })) ) ), ).subscribe(({ openSearchUri, searchOptions }) => { + if (!openSearchUri) { + return null; + } this.uuid = this.groupDataService.getUUIDFromString(this.router.url); const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, openSearchUri, searchOptions.sort, searchOptions.query); this.addLinks(route); From 0791287cf9265ff9d329085f5dd9172335c75ca6 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 6 May 2022 14:09:08 -0400 Subject: [PATCH 219/409] lint fixes --- src/app/core/core.module.ts | 3 --- src/app/shared/rss-feed/rss.component.ts | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index f6cde902532..27e23268183 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -164,12 +164,9 @@ import { SequenceService } from './shared/sequence.service'; import { CoreState } from './core-state.model'; import { GroupDataService } from './eperson/group-data.service'; import { SubmissionAccessesModel } from './config/models/config-submission-accesses.model'; -<<<<<<< HEAD import { AccessStatusObject } from '../shared/object-list/access-status-badge/access-status.model'; import { AccessStatusDataService } from './data/access-status-data.service'; -======= import { LinkHeadService } from './services/link-head.service'; ->>>>>>> 354768d98 (w2p-85140 ds-rss component now adds a button to all search pages and community and collection, link-head service adds the rss to the head element) /** * When not in production, endpoint responses can be mocked for testing purposes diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 9a101e8310f..b694280e3cb 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -77,13 +77,13 @@ export class RSSComponent implements OnInit, OnDestroy { })); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( getFirstCompletedRemoteData(), - map((result: RemoteData) => { + map((result: RemoteData) => { if (result.hasSucceeded) { return result.payload.values[0]; } return null; }), - switchMap((openSearchUri: string) => + switchMap((openSearchUri: string) => this.searchConfigurationService.paginatedSearchOptions.pipe( map((searchOptions: PaginatedSearchOptions) => ({ openSearchUri, searchOptions })) ) From 42c459a51d5ebcf2eff3423fe239968e24dfcd9c Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 12 May 2022 16:13:43 +0200 Subject: [PATCH 220/409] [CST-5303] added labels into i18n --- src/assets/i18n/en.json5 | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 9bdf41346dd..bb2bcf8ebc6 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2158,6 +2158,22 @@ "item.preview.dc.title": "Title:", + "item.preview.dc.type": "Type:", + + "item.preview.oaire.citation.issue" : "Issue", + + "item.preview.oaire.citation.volume" : "Volume", + + "item.preview.dc.relation.issn" : "ISSN", + + "item.preview.dc.identifier.isbn" : "ISBN", + + "item.preview.dc.identifier": "Identifier:", + + "item.preview.dc.relation.ispartof" : "Journal or Serie", + + "item.preview.dc.identifier.doi" : "DOI", + "item.preview.person.familyName": "Surname:", "item.preview.person.givenName": "Name:", @@ -3568,6 +3584,22 @@ "submission.import-external.source.arxiv": "arXiv", + "submission.import-external.source.ads": "NASA/ADS", + + "submission.import-external.source.cinii": "CiNii", + + "submission.import-external.source.crossref": "CrossRef", + + "submission.import-external.source.scielo": "SciELO", + + "submission.import-external.source.scopus": "Scopus", + + "submission.import-external.source.vufind": "VuFind", + + "submission.import-external.source.wos": "Web Of Science", + + "submission.import-external.source.epo": "European Patent Office (EPO)", + "submission.import-external.source.loading": "Loading ...", "submission.import-external.source.sherpaJournal": "SHERPA Journals", @@ -3582,10 +3614,14 @@ "submission.import-external.source.pubmed": "Pubmed", + "submission.import-external.source.pubmedeu": "Pubmed Europe", + "submission.import-external.source.lcname": "Library of Congress Names", "submission.import-external.preview.title": "Item Preview", + "submission.import-external.preview.title.Publication": "Publication Preview", + "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.button.import": "Start submission", @@ -3824,6 +3860,18 @@ "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.crossref": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title.epo": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title.scopus": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title.scielo": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title.wos": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title": "Search Results", + "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.confirm": "Save a new name variant", From c1f64ff1ef9a6846b9926968ccfd0d8ec2d548f5 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Thu, 12 May 2022 18:50:25 +0200 Subject: [PATCH 221/409] [CST-5329] Add help text to validate only checkbox --- .../metadata-import-page.component.html | 15 +++++++++++---- src/assets/i18n/en.json5 | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html index 2c710935d51..24901cc11d3 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html @@ -1,10 +1,17 @@

{{'admin.metadata-import.page.help' | translate}}

-

- - {{'admin.metadata-import.page.validateOnly' | translate}} -

+
+
+ + +
+ + {{'admin.metadata-import.page.validateOnly.hint' | translate}} + +
Date: Fri, 13 May 2022 13:32:33 -0400 Subject: [PATCH 222/409] for rss sort id should be date.accessioned so defaulted to that when its the case --- src/app/shared/rss-feed/rss.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index b694280e3cb..3fdb859bdce 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -118,7 +118,7 @@ export class RSSComponent implements OnInit, OnDestroy { if (uuid) { route += `&scope=${uuid}`; } - if (sort && sort.direction && sort.field) { + if (sort && sort.direction && sort.field && sort.field !== 'id') { route += `&sort=${sort.field}&sort_direction=${sort.direction}`; } if (query) { From 913d128e165e5ef3f3784a2e25dd0bccab26503d Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 13 May 2022 16:57:28 -0500 Subject: [PATCH 223/409] Fix accessibility issue: link has no discernible text --- src/app/shared/rss-feed/rss.component.html | 2 +- src/assets/i18n/en.json5 | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/shared/rss-feed/rss.component.html b/src/app/shared/rss-feed/rss.component.html index e86e72d15a9..91140c50c5a 100644 --- a/src/app/shared/rss-feed/rss.component.html +++ b/src/app/shared/rss-feed/rss.component.html @@ -1,5 +1,5 @@
- +
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 110b66c1768..520d38cf69c 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1401,6 +1401,9 @@ "error.validation.groupExists": "This group already exists", + "feed.description": "Syndication feed", + + "file-section.error.header": "Error obtaining files for this item", From 4c5c99d05d3a5ba0b5abd2add953f14082ebea55 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 16:44:35 +0200 Subject: [PATCH 224/409] [CST-5535] Add missing i18n label --- src/assets/i18n/en.json5 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 44d2d073056..c129187023d 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2503,13 +2503,15 @@ "menu.section.icon.find": "Find menu section", + "menu.section.icon.health": "Health check menu section", + "menu.section.icon.import": "Import menu section", "menu.section.icon.new": "New menu section", "menu.section.icon.pin": "Pin sidebar", - "menu.section.icon.processes": "Processes menu section", + "menu.section.icon.processes": "Processes Health", "menu.section.icon.registries": "Registries menu section", From 0de3c2ed48d6f5861ae008eba84757888e7860fe Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 16:45:00 +0200 Subject: [PATCH 225/409] [CST-5535] Replace icons --- .../health-info-component.component.html | 6 +++--- .../health-component/health-component.component.html | 4 ++-- .../health-page/health-panel/health-panel.component.html | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.html b/src/app/health-page/health-info/health-info-component/health-info-component.component.html index 55c1b3372f9..8ce7595980b 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.html +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.html @@ -1,13 +1,13 @@
-
+
- - + +
diff --git a/src/app/health-page/health-panel/health-component/health-component.component.html b/src/app/health-page/health-panel/health-component/health-component.component.html index 81719177674..4569d06dad3 100644 --- a/src/app/health-page/health-panel/health-component/health-component.component.html +++ b/src/app/health-page/health-panel/health-component/health-component.component.html @@ -6,8 +6,8 @@ {{ entry.key | titlecase }}
- - + +
diff --git a/src/app/health-page/health-panel/health-panel.component.html b/src/app/health-page/health-panel/health-panel.component.html index d582fb77f32..eebcfe55ec3 100644 --- a/src/app/health-page/health-panel/health-panel.component.html +++ b/src/app/health-page/health-panel/health-panel.component.html @@ -1,14 +1,14 @@

{{'health-page.status' | translate}} :

-
+
- - + +
From 80ff8a517ce95c16ab21b376d2e4b664dbe4b5d4 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 16:46:33 +0200 Subject: [PATCH 226/409] [CST-5535] Rename health-data.service --- src/app/health-page/health-page.component.spec.ts | 4 ++-- src/app/health-page/health-page.component.ts | 4 ++-- .../health-page/{health-data.service.ts => health.service.ts} | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/app/health-page/{health-data.service.ts => health.service.ts} (97%) diff --git a/src/app/health-page/health-page.component.spec.ts b/src/app/health-page/health-page.component.spec.ts index 205af8036a1..f3847ab0926 100644 --- a/src/app/health-page/health-page.component.spec.ts +++ b/src/app/health-page/health-page.component.spec.ts @@ -7,7 +7,7 @@ import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { HealthPageComponent } from './health-page.component'; -import { HealthDataService } from './health-data.service'; +import { HealthService } from './health.service'; import { HealthInfoResponseObj, HealthResponseObj } from '../shared/mocks/health-endpoint.mocks'; import { RawRestResponse } from '../core/dspace-rest/raw-rest-response.model'; import { TranslateLoaderMock } from '../shared/mocks/translate-loader.mock'; @@ -47,7 +47,7 @@ describe('HealthPageComponent', () => { ], declarations: [ HealthPageComponent ], providers: [ - { provide: HealthDataService, useValue: healthService } + { provide: HealthService, useValue: healthService } ] }) .compileComponents(); diff --git a/src/app/health-page/health-page.component.ts b/src/app/health-page/health-page.component.ts index e4f4be7a03e..eb07b63addf 100644 --- a/src/app/health-page/health-page.component.ts +++ b/src/app/health-page/health-page.component.ts @@ -3,7 +3,7 @@ import { Component, OnInit } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { take } from 'rxjs/operators'; -import { HealthDataService } from './health-data.service'; +import { HealthService } from './health.service'; import { HealthInfoResponse, HealthResponse } from './models/health-component.model'; @Component({ @@ -23,7 +23,7 @@ export class HealthPageComponent implements OnInit { */ healthResponse: BehaviorSubject = new BehaviorSubject(null); - constructor(private healthDataService: HealthDataService) { + constructor(private healthDataService: HealthService) { } /** diff --git a/src/app/health-page/health-data.service.ts b/src/app/health-page/health.service.ts similarity index 97% rename from src/app/health-page/health-data.service.ts rename to src/app/health-page/health.service.ts index bd905006aa9..7c238769a1e 100644 --- a/src/app/health-page/health-data.service.ts +++ b/src/app/health-page/health.service.ts @@ -8,7 +8,7 @@ import { HALEndpointService } from '../core/shared/hal-endpoint.service'; @Injectable({ providedIn: 'root' }) -export class HealthDataService { +export class HealthService { constructor(protected halService: HALEndpointService, protected restService: DspaceRestService) { } From 4f7e37d348dfeccca1cc7e1f8b7efeb526b11207 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 18:17:35 +0200 Subject: [PATCH 227/409] [CST-5535] Use accordion for health status components --- .../health-info-component.component.html | 38 ++++++++++++++--- .../health-info-component.component.spec.ts | 4 +- .../health-info/health-info.component.html | 30 ++++++++++++- .../health-info/health-info.component.spec.ts | 8 +++- .../health-info/health-info.component.ts | 12 +++++- .../health-component.component.html | 3 +- .../health-panel/health-panel.component.html | 42 ++++++++++--------- .../health-panel.component.spec.ts | 9 ++-- .../health-panel/health-panel.component.ts | 11 +++-- src/app/shared/mocks/health-endpoint.mocks.ts | 24 ++++++++++- 10 files changed, 139 insertions(+), 42 deletions(-) diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.html b/src/app/health-page/health-info/health-info-component/health-info-component.component.html index 8ce7595980b..b16e88564fd 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.html +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.html @@ -1,4 +1,34 @@ - +
+
+
+ +
+ + +
+
+
+
+
+ +
+
+
+
+ +

{{ entry.key | titlecase }} : {{entry.value}}

+
+
+ + + + diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts index 2297007cd5e..437d53a9536 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts @@ -46,7 +46,9 @@ describe('HealthInfoComponentComponent', () => { }); it('should display property', () => { - const components = fixture.debugElement.queryAll(By.css('[data-test="component"]')); + const properties = fixture.debugElement.queryAll(By.css('[data-test="property"]')); + expect(properties.length).toBe(14); + const components = fixture.debugElement.queryAll(By.css('[data-test="info-component"]')); expect(components.length).toBe(4); }); diff --git a/src/app/health-page/health-info/health-info.component.html b/src/app/health-page/health-info/health-info.component.html index e4d29adf548..be69df23b46 100644 --- a/src/app/health-page/health-info/health-info.component.html +++ b/src/app/health-page/health-info/health-info.component.html @@ -1,7 +1,33 @@ -
+ + + +
+ +
+ +
+ + +
+
+
+
+ + + +
+
+ + + + diff --git a/src/app/health-page/health-info/health-info.component.spec.ts b/src/app/health-page/health-info/health-info.component.spec.ts index 3af1d71db3b..a7f319b88b3 100644 --- a/src/app/health-page/health-info/health-info.component.spec.ts +++ b/src/app/health-page/health-info/health-info.component.spec.ts @@ -4,6 +4,8 @@ import { HealthInfoComponent } from './health-info.component'; import { HealthInfoResponseObj } from '../../shared/mocks/health-endpoint.mocks'; import { ObjNgFor } from '../../shared/utils/object-ngfor.pipe'; import { By } from '@angular/platform-browser'; +import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; describe('HealthInfoComponent', () => { let component: HealthInfoComponent; @@ -11,10 +13,14 @@ describe('HealthInfoComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [ + NgbAccordionModule, + ], declarations: [ HealthInfoComponent, ObjNgFor - ] + ], + schemas: [NO_ERRORS_SCHEMA] }) .compileComponents(); }); diff --git a/src/app/health-page/health-info/health-info.component.ts b/src/app/health-page/health-info/health-info.component.ts index a5fb0b282bc..9fddaeb7e43 100644 --- a/src/app/health-page/health-info/health-info.component.ts +++ b/src/app/health-page/health-info/health-info.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { HealthInfoResponse } from '../models/health-component.model'; @@ -7,8 +7,16 @@ import { HealthInfoResponse } from '../models/health-component.model'; templateUrl: './health-info.component.html', styleUrls: ['./health-info.component.scss'] }) -export class HealthInfoComponent { +export class HealthInfoComponent implements OnInit { @Input() healthInfoResponse: HealthInfoResponse; + /** + * The first active panel id + */ + activeId: string; + + ngOnInit(): void { + this.activeId = Object.keys(this.healthInfoResponse)[0]; + } } diff --git a/src/app/health-page/health-panel/health-component/health-component.component.html b/src/app/health-page/health-panel/health-component/health-component.component.html index 4569d06dad3..7089fe25c64 100644 --- a/src/app/health-page/health-panel/health-component/health-component.component.html +++ b/src/app/health-page/health-panel/health-component/health-component.component.html @@ -22,6 +22,7 @@
- {{ item.key | titlecase }} : {{item.value}} +

{{ item.key | titlecase }} : {{item.value}}

+
diff --git a/src/app/health-page/health-panel/health-panel.component.html b/src/app/health-page/health-panel/health-panel.component.html index eebcfe55ec3..d47a73d8204 100644 --- a/src/app/health-page/health-panel/health-panel.component.html +++ b/src/app/health-page/health-panel/health-panel.component.html @@ -1,21 +1,25 @@

{{'health-page.status' | translate}} :

-
-
- -
- - - -
-
-
-
-
- + + + +
+ +
+ +
+ + +
+
-
-
-
+ + + + + + + + diff --git a/src/app/health-page/health-panel/health-panel.component.spec.ts b/src/app/health-page/health-panel/health-panel.component.spec.ts index da392f7ba85..1d9c856ddbb 100644 --- a/src/app/health-page/health-panel/health-panel.component.spec.ts +++ b/src/app/health-page/health-panel/health-panel.component.spec.ts @@ -5,14 +5,14 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { NgbCollapseModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgbAccordionModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { HealthPanelComponent } from './health-panel.component'; import { HealthResponseObj } from '../../shared/mocks/health-endpoint.mocks'; import { ObjNgFor } from '../../shared/utils/object-ngfor.pipe'; -describe('HealthComponent', () => { +describe('HealthPanelComponent', () => { let component: HealthPanelComponent; let fixture: ComponentFixture; @@ -20,7 +20,7 @@ describe('HealthComponent', () => { await TestBed.configureTestingModule({ imports: [ NgbNavModule, - NgbCollapseModule, + NgbAccordionModule, CommonModule, BrowserAnimationsModule, TranslateModule.forRoot({ @@ -42,7 +42,6 @@ describe('HealthComponent', () => { fixture = TestBed.createComponent(HealthPanelComponent); component = fixture.componentInstance; component.healthResponse = HealthResponseObj; - component.isCollapsed = false; fixture.detectChanges(); }); @@ -50,7 +49,7 @@ describe('HealthComponent', () => { expect(component).toBeTruthy(); }); - it('should render a card for each component', () => { + it('should render a panel for each component', () => { const components = fixture.debugElement.queryAll(By.css('[data-test="component"]')); expect(components.length).toBe(5); }); diff --git a/src/app/health-page/health-panel/health-panel.component.ts b/src/app/health-page/health-panel/health-panel.component.ts index 549544c370a..8bb670e67f4 100644 --- a/src/app/health-page/health-panel/health-panel.component.ts +++ b/src/app/health-page/health-panel/health-panel.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { HealthResponse } from '../models/health-component.model'; @Component({ @@ -6,7 +6,7 @@ import { HealthResponse } from '../models/health-component.model'; templateUrl: './health-panel.component.html', styleUrls: ['./health-panel.component.scss'] }) -export class HealthPanelComponent { +export class HealthPanelComponent implements OnInit { /** * Health endpoint response @@ -14,8 +14,11 @@ export class HealthPanelComponent { @Input() healthResponse: HealthResponse; /** - * A boolean representing if div should start collapsed + * The first active panel id */ - public isCollapsed = true; + activeId: string; + ngOnInit(): void { + this.activeId = Object.keys(this.healthResponse.components)[0]; + } } diff --git a/src/app/shared/mocks/health-endpoint.mocks.ts b/src/app/shared/mocks/health-endpoint.mocks.ts index 9bd39561391..a9246d91a10 100644 --- a/src/app/shared/mocks/health-endpoint.mocks.ts +++ b/src/app/shared/mocks/health-endpoint.mocks.ts @@ -134,7 +134,27 @@ export const HealthInfoComponentOne: HealthInfoComponent = { 'name': 'DSpace at My University', 'dir': '/home/giuseppe/development/java/install/dspace7-review', 'url': 'http://localhost:8080/server', - 'db': 'jdbc:postgresql://localhost:5432/dspace7' + 'db': 'jdbc:postgresql://localhost:5432/dspace7', + 'solr': { + 'server': 'http://localhost:8983/solr', + 'prefix': '' + }, + 'mail': { + 'server': 'smtp.example.com', + 'from-address': 'dspace-noreply@myu.edu', + 'feedback-recipient': 'dspace-help@myu.edu', + 'mail-admin': 'dspace-help@myu.edu', + 'mail-helpdesk': 'dspace-help@myu.edu', + 'alert-recipient': 'dspace-help@myu.edu' + }, + 'cors': { + 'allowed-origins': 'http://localhost:4000' + }, + 'ui': { + 'url': 'http://localhost:4000' + } }; -export const HealthInfoComponentTwo = '7.3-SNAPSHOT'; +export const HealthInfoComponentTwo = { + 'version': '7.3-SNAPSHOT' +}; From c508e0035e46c977bb7b0fad2163eff5109c3d81 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 18:49:11 +0200 Subject: [PATCH 228/409] [CST-5535] Add tooltip for status icons --- .../health-status/health-status.component.html | 12 +++++++++--- src/assets/i18n/en.json5 | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/app/health-page/health-panel/health-status/health-status.component.html b/src/app/health-page/health-panel/health-status/health-status.component.html index fdd726cddfe..38a6f726018 100644 --- a/src/app/health-page/health-panel/health-status/health-status.component.html +++ b/src/app/health-page/health-panel/health-status/health-status.component.html @@ -1,6 +1,12 @@ - - - + + + diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index c129187023d..78661ced765 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1567,6 +1567,14 @@ + "health-page.status.ok.info": "Operational", + + "health-page.status.error.info": "Problems detected", + + "health-page.status.warning.info": "Possible issues detected", + + + "home.description": "", "home.breadcrumbs": "Home", From 73573793a0eacc52789c4df6b7a653040393f407 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 18:50:07 +0200 Subject: [PATCH 229/409] [CST-5535] Add i18n keys for section's headers --- .../health-info/health-info.component.html | 2 +- .../health-panel/health-panel.component.html | 2 +- src/assets/i18n/en.json5 | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/app/health-page/health-info/health-info.component.html b/src/app/health-page/health-info/health-info.component.html index be69df23b46..12764ead45b 100644 --- a/src/app/health-page/health-info/health-info.component.html +++ b/src/app/health-page/health-info/health-info.component.html @@ -5,7 +5,7 @@
diff --git a/src/app/health-page/health-panel/health-panel.component.html b/src/app/health-page/health-panel/health-panel.component.html index d47a73d8204..d095ce2f6d4 100644 --- a/src/app/health-page/health-panel/health-panel.component.html +++ b/src/app/health-page/health-panel/health-panel.component.html @@ -5,7 +5,7 @@
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 78661ced765..c22ec1c3ee8 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1566,6 +1566,21 @@ "grant-request-copy.success": "Successfully granted item request", + "health-page.section.db.title": "Database", + + "health-page.section.geoIp.title": "GeoIp", + + "health-page.section.solrAuthorityCore.title": "Sor: authority core", + + "health-page.section.solrOaiCore.title": "Sor: oai core", + + "health-page.section.solrSearchCore.title": "Sor: search core", + + "health-page.section.solrStatisticsCore.title": "Sor: statistics core", + + "health-page.section-info.app.title": "Application Backend", + + "health-page.section-info.java.title": "Java", "health-page.status.ok.info": "Operational", From 74b68a5e154f1285ad3e7ec9d13fcb30590378d4 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 19:19:00 +0200 Subject: [PATCH 230/409] [CST-5535] Add fallback message on rest request error --- .../health-page/health-page.component.html | 45 ++++++++++--------- src/app/health-page/health-page.component.ts | 11 +++-- src/assets/i18n/en.json5 | 2 + 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/app/health-page/health-page.component.html b/src/app/health-page/health-page.component.html index 6ec9abddcb4..0647620c733 100644 --- a/src/app/health-page/health-page.component.html +++ b/src/app/health-page/health-page.component.html @@ -1,21 +1,26 @@ -
- -
+
+ +
+ + diff --git a/src/app/health-page/health-page.component.ts b/src/app/health-page/health-page.component.ts index eb07b63addf..a92e72744bf 100644 --- a/src/app/health-page/health-page.component.ts +++ b/src/app/health-page/health-page.component.ts @@ -30,12 +30,15 @@ export class HealthPageComponent implements OnInit { * Retrieve responses from rest */ ngOnInit(): void { - this.healthDataService.getHealth().pipe(take(1)).subscribe((data: any) => { - this.healthResponse.next(data.payload); + this.healthDataService.getHealth().pipe(take(1)).subscribe({ + next: (data: any) => { this.healthResponse.next(data.payload); }, + error: () => { this.healthResponse.next(null); } }); - this.healthDataService.getInfo().pipe(take(1)).subscribe((data) => { - this.healthInfoResponse.next(data.payload); + this.healthDataService.getInfo().pipe(take(1)).subscribe({ + next: (data: any) => { this.healthInfoResponse.next(data.payload); }, + error: () => { this.healthInfoResponse.next(null); } }); + } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 4fcdbff335a..216b29fcd01 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1583,6 +1583,8 @@ "grant-request-copy.success": "Successfully granted item request", + "health-page.error.msg": "The health check service is temporarily unavailable", + "health-page.section.db.title": "Database", "health-page.section.geoIp.title": "GeoIp", From 1f9b8ba92a4fcf09e2f0c6cb8661f7b8b6fdd637 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 17 May 2022 11:16:46 +0200 Subject: [PATCH 231/409] Fix issue where you'd get stuck in an infinite redirect loop when going to the page of an item with an entity type containing certain special characters --- src/app/item-page/item-page.resolver.spec.ts | 87 ++++++++++++++++++++ src/app/item-page/item-page.resolver.ts | 10 ++- 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/app/item-page/item-page.resolver.spec.ts diff --git a/src/app/item-page/item-page.resolver.spec.ts b/src/app/item-page/item-page.resolver.spec.ts new file mode 100644 index 00000000000..533f97d0c0e --- /dev/null +++ b/src/app/item-page/item-page.resolver.spec.ts @@ -0,0 +1,87 @@ +import { ItemPageResolver } from './item-page.resolver'; +import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils'; +import { DSpaceObject } from '../core/shared/dspace-object.model'; +import { MetadataValueFilter } from '../core/shared/metadata.models'; +import { first } from 'rxjs/operators'; +import { Router } from '@angular/router'; +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; + +describe('ItemPageResolver', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule.withRoutes([{ + path: 'entities/:entity-type/:id', + component: {} as any + }])] + }); + }); + + describe('resolve', () => { + let resolver: ItemPageResolver; + let itemService: any; + let store: any; + let router: any; + + const uuid = '1234-65487-12354-1235'; + let item: DSpaceObject; + + function runTestsWithEntityType(entityType: string) { + beforeEach(() => { + router = TestBed.inject(Router); + item = Object.assign(new DSpaceObject(), { + uuid: uuid, + firstMetadataValue(_keyOrKeys: string | string[], _valueFilter?: MetadataValueFilter): string { + return entityType; + } + }); + itemService = { + findById: (_id: string) => createSuccessfulRemoteDataObject$(item) + }; + store = jasmine.createSpyObj('store', { + dispatch: {}, + }); + resolver = new ItemPageResolver(itemService, store, router); + }); + + it('should redirect to the correct route for the entity type', (done) => { + spyOn(item, 'firstMetadataValue').and.returnValue(entityType); + spyOn(router, 'navigateByUrl').and.callThrough(); + + resolver.resolve({ params: { id: uuid } } as any, { url: router.parseUrl(`/items/${uuid}`).toString() } as any) + .pipe(first()) + .subscribe( + () => { + expect(router.navigateByUrl).toHaveBeenCalledWith(router.parseUrl(`/entities/${entityType}/${uuid}`).toString()); + done(); + } + ); + }); + + it('should not redirect if we’re already on the correct route', (done) => { + spyOn(item, 'firstMetadataValue').and.returnValue(entityType); + spyOn(router, 'navigateByUrl').and.callThrough(); + + resolver.resolve({ params: { id: uuid } } as any, { url: router.parseUrl(`/entities/${entityType}/${uuid}`).toString() } as any) + .pipe(first()) + .subscribe( + () => { + expect(router.navigateByUrl).not.toHaveBeenCalled(); + done(); + } + ); + }); + } + + describe('when normal entity type is provided', () => { + runTestsWithEntityType('publication'); + }); + + describe('when entity type contains a special character', () => { + runTestsWithEntityType('alligator,loki'); + runTestsWithEntityType('🐊'); + runTestsWithEntityType(' '); + }); + + }); +}); diff --git a/src/app/item-page/item-page.resolver.ts b/src/app/item-page/item-page.resolver.ts index 7edffc53578..e9b287406e0 100644 --- a/src/app/item-page/item-page.resolver.ts +++ b/src/app/item-page/item-page.resolver.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs'; import { RemoteData } from '../core/data/remote-data'; import { ItemDataService } from '../core/data/item-data.service'; @@ -35,8 +35,14 @@ export class ItemPageResolver extends ItemResolver { return super.resolve(route, state).pipe( map((rd: RemoteData) => { if (rd.hasSucceeded && hasValue(rd.payload)) { - const itemRoute = getItemPageRoute(rd.payload); const thisRoute = state.url; + + // Angular uses a custom function for encodeURIComponent, (e.g. it doesn't encode commas + // or semicolons) and thisRoute has been encoded with that function. If we want to compare + // it with itemRoute, we have to run itemRoute through Angular's version as well to ensure + // the same characters are encoded the same way. + const itemRoute = this.router.parseUrl(getItemPageRoute(rd.payload)).toString(); + if (!thisRoute.startsWith(itemRoute)) { const itemId = rd.payload.uuid; const subRoute = thisRoute.substring(thisRoute.indexOf(itemId) + itemId.length, thisRoute.length); From 881af6449542ee174206d5b10ec27b87f0254219 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Tue, 17 May 2022 16:36:40 +0200 Subject: [PATCH 232/409] [CST-5674] POST replaced with PUT --- .../resource-policy.service.ts | 4 +-- .../form/resource-policy-form.component.html | 34 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/app/core/resource-policy/resource-policy.service.ts b/src/app/core/resource-policy/resource-policy.service.ts index ca3951109af..8411647beab 100644 --- a/src/app/core/resource-policy/resource-policy.service.ts +++ b/src/app/core/resource-policy/resource-policy.service.ts @@ -29,7 +29,7 @@ import { getFirstCompletedRemoteData } from '../shared/operators'; import { CoreState } from '../core-state.model'; import { FindListOptions } from '../data/find-list-options.model'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; -import { PostRequest } from '../data/request.models'; +import { PutRequest } from '../data/request.models'; import { GenericConstructor } from '../shared/generic-constructor'; import { ResponseParsingService } from '../data/parsing.service'; import { StatusCodeOnlyResponseParsingService } from '../data/status-code-only-response-parsing.service'; @@ -260,7 +260,7 @@ export class ResourcePolicyService { return targetEndpoint$.pipe(switchMap((targetEndpoint) => { const resourceEndpoint = resourcePolicyHref + '/' + type; - const request = new PostRequest(requestId, resourceEndpoint, targetEndpoint, options); + const request = new PutRequest(requestId, resourceEndpoint, targetEndpoint, options); Object.assign(request, { getResponseParser(): GenericConstructor { return StatusCodeOnlyResponseParsingService; diff --git a/src/app/shared/resource-policies/form/resource-policy-form.component.html b/src/app/shared/resource-policies/form/resource-policy-form.component.html index f7aad55ce8c..66c1fc400e9 100644 --- a/src/app/shared/resource-policies/form/resource-policy-form.component.html +++ b/src/app/shared/resource-policies/form/resource-policy-form.component.html @@ -8,24 +8,22 @@
- - -
-
+ +

From 618ff0ce19607900bfd165aec9ae7ef01a9b19a2 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 17 May 2022 17:45:27 +0200 Subject: [PATCH 233/409] [CST-5303] added missing labels --- src/assets/i18n/en.json5 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index bb2bcf8ebc6..5bae41d0a14 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3644,6 +3644,26 @@ "submission.sections.describe.relationship-lookup.external-source.import-button-title.isProjectOfPublication": "Project", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.none = "Import remote item", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Event": "Import remote 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.Equipment": "Import remote 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.Funding": "Import remote fund", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Person = "Import remote person", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Patent": "Import remote 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.Publication = "Import remote publication", + "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.title": "Project", From a732f1534de03fbdc89aad33af769dc50f40fb72 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 18 May 2022 09:33:08 +0200 Subject: [PATCH 234/409] [CST-5303] fix wrong format --- src/assets/i18n/en.json5 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 5bae41d0a14..dffbbd4b7ed 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3644,7 +3644,7 @@ "submission.sections.describe.relationship-lookup.external-source.import-button-title.isProjectOfPublication": "Project", - "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": "Import remote item", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Event": "Import remote event", @@ -3652,17 +3652,17 @@ "submission.sections.describe.relationship-lookup.external-source.import-button-title.Equipment": "Import remote 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": "Import remote organizational unit", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Funding": "Import remote fund", - "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": "Import remote person", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Patent": "Import remote 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": "Import remote 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": "Import remote publication", "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.added.new-entity": "New Entity Added!", From d4dc176870d46506ad72670ba391f9f041e1c495 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 18 May 2022 13:04:04 +0200 Subject: [PATCH 235/409] [CST-5535] Add Possibility to have translation also for properties --- .../health-info-component.component.html | 4 ++-- .../health-info-component.component.scss | 3 +++ .../health-info-component.component.spec.ts | 10 +++++++++- .../health-info-component.component.ts | 12 ++++++++++-- .../health-info/health-info.component.html | 4 ++-- .../health-info/health-info.component.scss | 3 +++ .../health-info/health-info.component.spec.ts | 8 ++++++++ .../health-info/health-info.component.ts | 15 +++++++++++++++ .../health-component.component.html | 4 ++-- .../health-component.component.scss | 3 +++ .../health-component.component.spec.ts | 10 +++++++++- .../health-component.component.ts | 17 ++++++++++++++++- .../health-panel/health-panel.component.html | 4 ++-- .../health-panel/health-panel.component.scss | 3 +++ .../health-panel/health-panel.component.ts | 16 ++++++++++++++++ .../health-status.component.spec.ts | 12 ++++++++++++ src/assets/i18n/en.json5 | 2 ++ 17 files changed, 117 insertions(+), 13 deletions(-) diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.html b/src/app/health-page/health-info/health-info-component/health-info-component.component.html index b16e88564fd..b607d95f45d 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.html +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.html @@ -1,6 +1,6 @@
-
+
-

{{ entry.key | titlecase }} : {{entry.value}}

+

{{ getPropertyLabel(entry.key) | titlecase }} : {{entry.value}}

diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.scss b/src/app/health-page/health-info/health-info-component/health-info-component.component.scss index e69de29bb2d..a6f0e734136 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.scss +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.scss @@ -0,0 +1,3 @@ +.collapse-toggle { + cursor: pointer; +} diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts index 437d53a9536..b4532415b89 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts @@ -8,6 +8,8 @@ import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; import { HealthInfoComponentComponent } from './health-info-component.component'; import { HealthInfoComponentOne, HealthInfoComponentTwo } from '../../../shared/mocks/health-endpoint.mocks'; import { ObjNgFor } from '../../../shared/utils/object-ngfor.pipe'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock'; describe('HealthInfoComponentComponent', () => { let component: HealthInfoComponentComponent; @@ -18,7 +20,13 @@ describe('HealthInfoComponentComponent', () => { imports: [ CommonModule, NgbCollapseModule, - NoopAnimationsModule + NoopAnimationsModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) ], declarations: [ HealthInfoComponentComponent, diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.ts b/src/app/health-page/health-info/health-info-component/health-info-component.component.ts index b6c31214c8f..159462cd6d5 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.ts +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.ts @@ -1,13 +1,14 @@ import { Component, Input } from '@angular/core'; import { HealthInfoComponent } from '../../models/health-component.model'; +import { HealthComponentComponent } from '../../health-panel/health-component/health-component.component'; @Component({ selector: 'ds-health-info-component', templateUrl: './health-info-component.component.html', styleUrls: ['./health-info-component.component.scss'] }) -export class HealthInfoComponentComponent { +export class HealthInfoComponentComponent extends HealthComponentComponent { /** * The HealthInfoComponent object to display @@ -27,9 +28,16 @@ export class HealthInfoComponentComponent { /** * A boolean representing if div should start collapsed */ - public isCollapsed = true; + public isCollapsed = false; + /** + * Check if the HealthInfoComponent is has only string property or contains object + * + * @param entry The HealthInfoComponent to check + * @return boolean + */ isPlainProperty(entry: HealthInfoComponent | string): boolean { return typeof entry === 'string'; } + } diff --git a/src/app/health-page/health-info/health-info.component.html b/src/app/health-page/health-info/health-info.component.html index 12764ead45b..47e4cfb4d2f 100644 --- a/src/app/health-page/health-info/health-info.component.html +++ b/src/app/health-page/health-info/health-info.component.html @@ -2,10 +2,10 @@ -
+
diff --git a/src/app/health-page/health-info/health-info.component.scss b/src/app/health-page/health-info/health-info.component.scss index e69de29bb2d..a6f0e734136 100644 --- a/src/app/health-page/health-info/health-info.component.scss +++ b/src/app/health-page/health-info/health-info.component.scss @@ -0,0 +1,3 @@ +.collapse-toggle { + cursor: pointer; +} diff --git a/src/app/health-page/health-info/health-info.component.spec.ts b/src/app/health-page/health-info/health-info.component.spec.ts index a7f319b88b3..5a9b8bf0aa5 100644 --- a/src/app/health-page/health-info/health-info.component.spec.ts +++ b/src/app/health-page/health-info/health-info.component.spec.ts @@ -6,6 +6,8 @@ import { ObjNgFor } from '../../shared/utils/object-ngfor.pipe'; import { By } from '@angular/platform-browser'; import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'; import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; describe('HealthInfoComponent', () => { let component: HealthInfoComponent; @@ -15,6 +17,12 @@ describe('HealthInfoComponent', () => { await TestBed.configureTestingModule({ imports: [ NgbAccordionModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) ], declarations: [ HealthInfoComponent, diff --git a/src/app/health-page/health-info/health-info.component.ts b/src/app/health-page/health-info/health-info.component.ts index 9fddaeb7e43..d8c629636b1 100644 --- a/src/app/health-page/health-info/health-info.component.ts +++ b/src/app/health-page/health-info/health-info.component.ts @@ -1,6 +1,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { HealthInfoResponse } from '../models/health-component.model'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'ds-health-info', @@ -16,7 +17,21 @@ export class HealthInfoComponent implements OnInit { */ activeId: string; + constructor(private translate: TranslateService) { + } + ngOnInit(): void { this.activeId = Object.keys(this.healthInfoResponse)[0]; } + /** + * Return translated label if exist for the given property + * + * @param property + */ + public getPanelLabel(panelKey: string): string { + const translationKey = `health-page.section-info.${panelKey}.title`; + const translation = this.translate.instant(translationKey); + + return (translation === translationKey) ? panelKey : translation; + } } diff --git a/src/app/health-page/health-panel/health-component/health-component.component.html b/src/app/health-page/health-panel/health-component/health-component.component.html index 7089fe25c64..c254f128d98 100644 --- a/src/app/health-page/health-panel/health-component/health-component.component.html +++ b/src/app/health-page/health-panel/health-component/health-component.component.html @@ -1,6 +1,6 @@
-
+
diff --git a/src/app/health-page/health-panel/health-panel.component.scss b/src/app/health-page/health-panel/health-panel.component.scss index e69de29bb2d..a6f0e734136 100644 --- a/src/app/health-page/health-panel/health-panel.component.scss +++ b/src/app/health-page/health-panel/health-panel.component.scss @@ -0,0 +1,3 @@ +.collapse-toggle { + cursor: pointer; +} diff --git a/src/app/health-page/health-panel/health-panel.component.ts b/src/app/health-page/health-panel/health-panel.component.ts index 8bb670e67f4..3137334d6f7 100644 --- a/src/app/health-page/health-panel/health-panel.component.ts +++ b/src/app/health-page/health-panel/health-panel.component.ts @@ -1,5 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; import { HealthResponse } from '../models/health-component.model'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'ds-health-panel', @@ -18,7 +19,22 @@ export class HealthPanelComponent implements OnInit { */ activeId: string; + constructor(private translate: TranslateService) { + } + ngOnInit(): void { this.activeId = Object.keys(this.healthResponse.components)[0]; } + + /** + * Return translated label if exist for the given property + * + * @param property + */ + public getPanelLabel(panelKey: string): string { + const translationKey = `health-page.section.${panelKey}.title`; + const translation = this.translate.instant(translationKey); + + return (translation === translationKey) ? panelKey : translation; + } } diff --git a/src/app/health-page/health-panel/health-status/health-status.component.spec.ts b/src/app/health-page/health-panel/health-status/health-status.component.spec.ts index 13df9c23e36..f0f61ebdbbe 100644 --- a/src/app/health-page/health-panel/health-status/health-status.component.spec.ts +++ b/src/app/health-page/health-panel/health-status/health-status.component.spec.ts @@ -3,6 +3,9 @@ import { By } from '@angular/platform-browser'; import { HealthStatusComponent } from './health-status.component'; import { HealthStatus } from '../../models/health-component.model'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; describe('HealthStatusComponent', () => { let component: HealthStatusComponent; @@ -10,6 +13,15 @@ describe('HealthStatusComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [ + NgbTooltipModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) + ], declarations: [ HealthStatusComponent ] }) .compileComponents(); diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 216b29fcd01..18a406b77b8 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1585,6 +1585,8 @@ "health-page.error.msg": "The health check service is temporarily unavailable", + "health-page.property.status": "Status code", + "health-page.section.db.title": "Database", "health-page.section.geoIp.title": "GeoIp", From ef332af17ea62afce19ef83763ac30b356e63289 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 18 May 2022 13:31:09 +0200 Subject: [PATCH 236/409] [CST-5535] Fix issue with error notice message on health page loading --- .../health-page/health-page.component.html | 2 +- src/app/health-page/health-page.component.ts | 30 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/app/health-page/health-page.component.html b/src/app/health-page/health-page.component.html index 0647620c733..605927dc552 100644 --- a/src/app/health-page/health-page.component.html +++ b/src/app/health-page/health-page.component.html @@ -1,4 +1,4 @@ -
+