diff --git a/comixed-webui/src/app/admin/pages/web-audit-log-page/web-audit-log-page.component.ts b/comixed-webui/src/app/admin/pages/web-audit-log-page/web-audit-log-page.component.ts index 6bbe471df1..fe90de028a 100644 --- a/comixed-webui/src/app/admin/pages/web-audit-log-page/web-audit-log-page.component.ts +++ b/comixed-webui/src/app/admin/pages/web-audit-log-page/web-audit-log-page.component.ts @@ -42,6 +42,7 @@ import { import { MatSort } from '@angular/material/sort'; import { MatSidenav } from '@angular/material/sidenav'; import { ConfirmationService } from '@app/core/services/confirmation.service'; +import { TitleService } from '@app/core/services/title.service'; @Component({ selector: 'cx-web-audit-log-page', @@ -78,7 +79,8 @@ export class WebAuditLogPageComponent private logger: LoggerService, private store: Store, private confirmationService: ConfirmationService, - private translateService: TranslateService + private translateService: TranslateService, + private titleService: TitleService ) { this.langChangeSubscription = this.translateService.onLangChange.subscribe( () => this.loadTranslations() @@ -166,5 +168,8 @@ export class WebAuditLogPageComponent this.paginator._intl.itemsPerPageLabel = this.translateService.instant( 'web-audit-log.label.pagination-items-per-page' ); + this.titleService.setTitle( + this.translateService.instant('web-audit-log.tab-title') + ); } } diff --git a/comixed-webui/src/app/blocked-pages/pages/blocked-page-list-page/blocked-page-list-page.component.spec.ts b/comixed-webui/src/app/blocked-pages/pages/blocked-page-list-page/blocked-page-list-page.component.spec.ts index c3d82277cd..ed56f703c1 100644 --- a/comixed-webui/src/app/blocked-pages/pages/blocked-page-list-page/blocked-page-list-page.component.spec.ts +++ b/comixed-webui/src/app/blocked-pages/pages/blocked-page-list-page/blocked-page-list-page.component.spec.ts @@ -36,7 +36,7 @@ import { import { MatToolbarModule } from '@angular/material/toolbar'; import { MatTableModule } from '@angular/material/table'; import { MatPaginatorModule } from '@angular/material/paginator'; -import { TranslateModule } from '@ngx-translate/core'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { downloadBlockedPages } from '@app/blocked-pages/actions/download-blocked-pages.actions'; import { MatDialogModule } from '@angular/material/dialog'; @@ -48,6 +48,8 @@ import { SelectableListItem } from '@app/core/models/ui/selectable-list-item'; import { MatIconModule } from '@angular/material/icon'; import { MatTooltipModule } from '@angular/material/tooltip'; import { setBlockedPageDeletionFlags } from '@app/blocked-pages/actions/set-blocked-page-deletion-flag.actions'; +import { markPagesWithHash } from '@app/comic-pages/actions/blocked-hash-list.actions'; +import { TitleService } from '@app/core/services/title.service'; describe('BlockedPageListPageComponent', () => { const ENTRIES = [BLOCKED_PAGE_1, BLOCKED_PAGE_3, BLOCKED_PAGE_5]; @@ -60,6 +62,8 @@ describe('BlockedPageListPageComponent', () => { let router: Router; let store: MockStore; let confirmationService: ConfirmationService; + let titleService: TitleService; + let translateService: TranslateService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -76,7 +80,11 @@ describe('BlockedPageListPageComponent', () => { MatIconModule, MatTooltipModule ], - providers: [provideMockStore({ initialState }), ConfirmationService] + providers: [ + provideMockStore({ initialState }), + ConfirmationService, + TitleService + ] }).compileComponents(); fixture = TestBed.createComponent(BlockedPageListPageComponent); @@ -86,6 +94,9 @@ describe('BlockedPageListPageComponent', () => { store = TestBed.inject(MockStore); spyOn(store, 'dispatch'); confirmationService = TestBed.inject(ConfirmationService); + titleService = TestBed.inject(TitleService); + spyOn(titleService, 'setTitle'); + translateService = TestBed.inject(TranslateService); fixture.detectChanges(); })); @@ -93,6 +104,16 @@ describe('BlockedPageListPageComponent', () => { expect(component).toBeTruthy(); }); + describe('when the language changes', () => { + beforeEach(() => { + translateService.use('fr'); + }); + + it('loads the title', () => { + expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); + }); + }); + describe('receiving blocked page updates', () => { beforeEach(() => { store.setState({ diff --git a/comixed-webui/src/app/blocked-pages/pages/blocked-page-list-page/blocked-page-list-page.component.ts b/comixed-webui/src/app/blocked-pages/pages/blocked-page-list-page/blocked-page-list-page.component.ts index b4ad8a4cb3..d26e713d0b 100644 --- a/comixed-webui/src/app/blocked-pages/pages/blocked-page-list-page/blocked-page-list-page.component.ts +++ b/comixed-webui/src/app/blocked-pages/pages/blocked-page-list-page/blocked-page-list-page.component.ts @@ -16,7 +16,13 @@ * along with this program. If not, see */ -import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; +import { + AfterViewInit, + Component, + OnDestroy, + OnInit, + ViewChild +} from '@angular/core'; import { loadBlockedPageList } from '@app/blocked-pages/actions/blocked-page-list.actions'; import { Store } from '@ngrx/store'; import { LoggerService } from '@angular-ru/logger'; @@ -33,17 +39,24 @@ import { BlockedPage } from '@app/blocked-pages/models/blocked-page'; import { SelectableListItem } from '@app/core/models/ui/selectable-list-item'; import { ConfirmationService } from '@app/core/services/confirmation.service'; import { setBlockedPageDeletionFlags } from '@app/blocked-pages/actions/set-blocked-page-deletion-flag.actions'; +import { TitleService } from '@app/core/services/title.service'; @Component({ selector: 'cx-blocked-page-list', templateUrl: './blocked-page-list-page.component.html', styleUrls: ['./blocked-page-list-page.component.scss'] }) -export class BlockedPageListPageComponent implements OnInit, AfterViewInit { +export class BlockedPageListPageComponent + implements OnInit, AfterViewInit, OnDestroy +{ @ViewChild('MatPagination') paginator: MatPaginator; pageSubscription: Subscription; dataSource = new MatTableDataSource>([]); + + pageSubscription: Subscription; + langChangeSubscription: Subscription; + dataSource = new MatTableDataSource>([]); readonly displayedColumns = [ 'selected', 'label', @@ -59,11 +72,15 @@ export class BlockedPageListPageComponent implements OnInit, AfterViewInit { private store: Store, private router: Router, private confirmationService: ConfirmationService, - private translateService: TranslateService + private translateService: TranslateService, + private titleService: TitleService ) { this.pageSubscription = this.store .select(selectBlockedPageList) .subscribe(entries => (this.entries = entries)); + this.langChangeSubscription = this.translateService.onLangChange.subscribe( + () => this.loadTranslations() + ); } set entries(entries: BlockedPage[]) { @@ -76,8 +93,16 @@ export class BlockedPageListPageComponent implements OnInit, AfterViewInit { this.hasSelections = this.dataSource.data.some(entry => entry.selected); } + ngOnDestroy(): void { + this.logger.trace('Unsubscribing from blocked page list updates'); + this.pageSubscription.unsubscribe(); + this.logger.trace('Unsubscribing from language changes'); + this.langChangeSubscription.unsubscribe(); + } + ngOnInit(): void { this.store.dispatch(loadBlockedPageList()); + this.loadTranslations(); } onChangeSelection( @@ -186,4 +211,18 @@ export class BlockedPageListPageComponent implements OnInit, AfterViewInit { }) ); } + + private updateSelections(): void { + this.allSelected = this.dataSource.data.every(entry => entry.selected); + this.someSelected = + this.allSelected || + this.dataSource.data.some(listEntry => listEntry.selected); + } + + private loadTranslations(): void { + this.logger.trace('Loading tab title'); + this.titleService.setTitle( + this.translateService.instant('blocked-page-list.tab-title') + ); + } } diff --git a/comixed-webui/src/app/collections/pages/collection-detail/collection-detail.component.spec.ts b/comixed-webui/src/app/collections/pages/collection-detail/collection-detail.component.spec.ts index a6b003caa8..7a20433a6a 100644 --- a/comixed-webui/src/app/collections/pages/collection-detail/collection-detail.component.spec.ts +++ b/comixed-webui/src/app/collections/pages/collection-detail/collection-detail.component.spec.ts @@ -32,7 +32,7 @@ import { MatDialogModule } from '@angular/material/dialog'; import { MatMenuModule } from '@angular/material/menu'; import { LibraryToolbarComponent } from '@app/library/components/library-toolbar/library-toolbar.component'; import { MatIconModule } from '@angular/material/icon'; -import { TranslateModule } from '@ngx-translate/core'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatFormFieldModule } from '@angular/material/form-field'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; @@ -65,6 +65,7 @@ import { initialState as initialUserState, USER_FEATURE_KEY } from '@app/user/reducers/user.reducer'; +import { TitleService } from '@app/core/services/title.service'; describe('CollectionDetailComponent', () => { const COMICS = [COMIC_1, COMIC_2, COMIC_3, COMIC_4, COMIC_5]; @@ -81,6 +82,8 @@ describe('CollectionDetailComponent', () => { let store: MockStore; let activatedRoute: ActivatedRoute; let router: Router; + let titleService: TitleService; + let translateService: TranslateService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -115,7 +118,8 @@ describe('CollectionDetailComponent', () => { collectionName: 'Batman' }) } - } + }, + TitleService ] }).compileComponents(); @@ -126,6 +130,9 @@ describe('CollectionDetailComponent', () => { router = TestBed.inject(Router); spyOn(router, 'navigate'); spyOn(router, 'navigateByUrl'); + titleService = TestBed.inject(TitleService); + spyOn(titleService, 'setTitle'); + translateService = TestBed.inject(TranslateService); fixture.detectChanges(); })); @@ -133,6 +140,16 @@ describe('CollectionDetailComponent', () => { expect(component).toBeTruthy(); }); + describe('when the language changes', () => { + beforeEach(() => { + translateService.use('fr'); + }); + + it('loads the title', () => { + expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); + }); + }); + describe('when the collection type is invalid', () => { beforeEach(() => { (activatedRoute.params as BehaviorSubject<{}>).next({ diff --git a/comixed-webui/src/app/collections/pages/collection-detail/collection-detail.component.ts b/comixed-webui/src/app/collections/pages/collection-detail/collection-detail.component.ts index 9412fd255a..c0ce0965bb 100644 --- a/comixed-webui/src/app/collections/pages/collection-detail/collection-detail.component.ts +++ b/comixed-webui/src/app/collections/pages/collection-detail/collection-detail.component.ts @@ -32,6 +32,8 @@ import { ReadingList } from '@app/lists/models/reading-list'; import { selectUserReadingLists } from '@app/lists/selectors/reading-lists.selectors'; import { selectUser } from '@app/user/selectors/user.selectors'; import { isAdmin } from '@app/user/user.functions'; +import { TitleService } from '@app/core/services/title.service'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'cx-collection-detail', @@ -51,17 +53,21 @@ export class CollectionDetailComponent implements OnInit, OnDestroy { readingLists: ReadingList[] = []; userSubscription: Subscription; isAdmin = false; + langChangeSubscription: Subscription; constructor( private logger: LoggerService, private store: Store, private activatedRoute: ActivatedRoute, - private router: Router + private router: Router, + private translateService: TranslateService, + private titleService: TitleService ) { this.paramSubscription = this.activatedRoute.params.subscribe(params => { this.routableTypeName = params.collectionType; this.collectionName = params.collectionName; this.collectionType = collectionTypeFromString(this.routableTypeName); + this.loadTranslations(); if (!this.collectionType) { this.logger.error('Invalid collection type:', params.collectionType); this.router.navigateByUrl('/library'); @@ -97,9 +103,14 @@ export class CollectionDetailComponent implements OnInit, OnDestroy { this.readingListsSubscription = this.store .select(selectUserReadingLists) .subscribe(lists => (this.readingLists = lists)); + this.langChangeSubscription = this.translateService.onLangChange.subscribe( + () => this.loadTranslations() + ); } - ngOnInit(): void {} + ngOnInit(): void { + this.loadTranslations(); + } ngOnDestroy(): void { this.logger.trace('Unsubscribing from parameter updates'); @@ -111,5 +122,15 @@ export class CollectionDetailComponent implements OnInit, OnDestroy { this.userSubscription.unsubscribe(); this.logger.trace('Unsubscribing from reading list updats'); this.readingListsSubscription.unsubscribe(); + this.langChangeSubscription.unsubscribe(); + } + + private loadTranslations(): void { + this.titleService.setTitle( + this.translateService.instant('collection-detail.tab-title', { + collection: this.collectionType, + name: this.collectionName + }) + ); } } diff --git a/comixed-webui/src/app/collections/pages/collection-list/collection-list.component.spec.ts b/comixed-webui/src/app/collections/pages/collection-list/collection-list.component.spec.ts index d64c603d0d..d183ed7ab3 100644 --- a/comixed-webui/src/app/collections/pages/collection-list/collection-list.component.spec.ts +++ b/comixed-webui/src/app/collections/pages/collection-list/collection-list.component.spec.ts @@ -31,7 +31,8 @@ import { import { COMIC_1, COMIC_3, COMIC_5 } from '@app/comic-book/comic-book.fixtures'; import { CollectionListEntry } from '@app/collections/models/collection-list-entry'; import { MatTableModule } from '@angular/material/table'; -import { TranslateModule } from '@ngx-translate/core'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { TitleService } from '@app/core/services/title.service'; describe('CollectionListComponent', () => { const COMICS = [COMIC_1, COMIC_3, COMIC_5]; @@ -44,6 +45,8 @@ describe('CollectionListComponent', () => { let store: MockStore; let activatedRoute: ActivatedRoute; let router: Router; + let titleService: TitleService; + let translateService: TranslateService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -61,7 +64,8 @@ describe('CollectionListComponent', () => { useValue: { params: new BehaviorSubject<{}>({}) } - } + }, + TitleService ] }).compileComponents(); @@ -72,6 +76,9 @@ describe('CollectionListComponent', () => { router = TestBed.inject(Router); spyOn(router, 'navigate'); spyOn(router, 'navigateByUrl'); + titleService = TestBed.inject(TitleService); + spyOn(titleService, 'setTitle'); + translateService = TestBed.inject(TranslateService); fixture.detectChanges(); })); @@ -79,6 +86,16 @@ describe('CollectionListComponent', () => { expect(component).toBeTruthy(); }); + describe('when the language changes', () => { + beforeEach(() => { + translateService.use('fr'); + }); + + it('loads the title', () => { + expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); + }); + }); + describe('when the collection type is invalid', () => { beforeEach(() => { (activatedRoute.params as BehaviorSubject<{}>).next({ diff --git a/comixed-webui/src/app/collections/pages/collection-list/collection-list.component.ts b/comixed-webui/src/app/collections/pages/collection-list/collection-list.component.ts index 3f520cfccb..794ea098d3 100644 --- a/comixed-webui/src/app/collections/pages/collection-list/collection-list.component.ts +++ b/comixed-webui/src/app/collections/pages/collection-list/collection-list.component.ts @@ -35,6 +35,8 @@ import { selectComicListCollection } from '@app/comic-book/selectors/comic-list. import { MatTableDataSource } from '@angular/material/table'; import { CollectionListEntry } from '@app/collections/models/collection-list-entry'; import { MatSort } from '@angular/material/sort'; +import { TranslateService } from '@ngx-translate/core'; +import { TitleService } from '@app/core/services/title.service'; @Component({ selector: 'cx-collection-list', @@ -53,16 +55,20 @@ export class CollectionListComponent collectionSubscription: Subscription; dataSource = new MatTableDataSource([]); readonly displayedColumns = ['name', 'comic-count']; + langChangeSubscription: Subscription; constructor( private logger: LoggerService, private store: Store, private activatedRoute: ActivatedRoute, - private router: Router + private router: Router, + private translateService: TranslateService, + private titleService: TitleService ) { this.paramSubscription = this.activatedRoute.params.subscribe(params => { this.routableTypeName = params.collectionType; this.collectionType = collectionTypeFromString(this.routableTypeName); + this.loadTranslations(); if (!this.collectionType) { this.logger.error('Invalid collection type:', params.collectionType); this.router.navigateByUrl('/library'); @@ -76,6 +82,9 @@ export class CollectionListComponent ); } }); + this.langChangeSubscription = this.translateService.onLangChange.subscribe( + () => this.loadTranslations() + ); } set entries(entries: CollectionListEntry[]) { @@ -88,9 +97,12 @@ export class CollectionListComponent if (!!this.collectionSubscription) { this.collectionSubscription.unsubscribe(); } + this.langChangeSubscription.unsubscribe(); } - ngOnInit(): void {} + ngOnInit(): void { + this.loadTranslations(); + } onShowCollection(entry: CollectionListEntry): void { this.logger.debug('Collection entry selected:', entry); @@ -113,4 +125,12 @@ export class CollectionListComponent } }; } + + private loadTranslations(): void { + this.titleService.setTitle( + this.translateService.instant('collection-list.tab-title', { + collection: this.collectionType + }) + ); + } } diff --git a/comixed-webui/src/app/library/pages/library-page/library-page.component.spec.ts b/comixed-webui/src/app/library/pages/library-page/library-page.component.spec.ts index 9f3022a5e5..88236b8ea7 100644 --- a/comixed-webui/src/app/library/pages/library-page/library-page.component.spec.ts +++ b/comixed-webui/src/app/library/pages/library-page/library-page.component.spec.ts @@ -158,6 +158,7 @@ describe('LibraryPageComponent', () => { describe('loading page data', () => { beforeEach(() => { component.unreadOnly = false; + component.unscrapedOnly = false; component.deletedOnly = false; component.unscrapedOnly = false; }); @@ -172,6 +173,16 @@ describe('LibraryPageComponent', () => { }); }); + describe('when showing unscraped comics', () => { + beforeEach(() => { + (activatedRoute.data as BehaviorSubject<{}>).next({ unscraped: true }); + }); + + it('sets the unscraped only flag', () => { + expect(component.unscrapedOnly).toBeTrue(); + }); + }); + describe('when showing deleted comics', () => { beforeEach(() => { (activatedRoute.data as BehaviorSubject<{}>).next({ deleted: true }); @@ -196,6 +207,7 @@ describe('LibraryPageComponent', () => { describe('when the language changes', () => { beforeEach(() => { component.unreadOnly = false; + component.unscrapedOnly = false; component.deletedOnly = false; }); @@ -210,6 +222,12 @@ describe('LibraryPageComponent', () => { expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); }); + it('updates the page title for unscraped comic', () => { + component.unscrapedOnly = true; + translateService.use('fr'); + expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); + }); + it('updates the page title for deleted comic', () => { component.deletedOnly = true; translateService.use('fr'); diff --git a/comixed-webui/src/app/library/pages/library-page/library-page.component.ts b/comixed-webui/src/app/library/pages/library-page/library-page.component.ts index f289cf9534..716c71f2cd 100644 --- a/comixed-webui/src/app/library/pages/library-page/library-page.component.ts +++ b/comixed-webui/src/app/library/pages/library-page/library-page.component.ts @@ -173,6 +173,10 @@ export class LibraryPageComponent implements OnInit, OnDestroy { this.titleService.setTitle( this.translateService.instant('library.all-comics.tab-title-deleted') ); + } else if (this.unscrapedOnly) { + this.titleService.setTitle( + this.translateService.instant('library.all-comics.tab-title-unscraped') + ); } else if (this.unreadOnly) { this.titleService.setTitle( this.translateService.instant('library.all-comics.tab-title-unread') diff --git a/comixed-webui/src/app/lists/pages/reading-list-page/reading-list-page.component.spec.ts b/comixed-webui/src/app/lists/pages/reading-list-page/reading-list-page.component.spec.ts index ea59824483..fdc2c7db6d 100644 --- a/comixed-webui/src/app/lists/pages/reading-list-page/reading-list-page.component.spec.ts +++ b/comixed-webui/src/app/lists/pages/reading-list-page/reading-list-page.component.spec.ts @@ -19,7 +19,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ReadingListPageComponent } from './reading-list-page.component'; import { LoggerModule } from '@angular-ru/logger'; -import { TranslateModule } from '@ngx-translate/core'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { initialState as initialReadingListDetailsState, READING_LIST_DETAIL_FEATURE_KEY @@ -62,6 +62,7 @@ import { import { Subscription as WebstompSubscription } from 'webstomp-client'; import { downloadReadingList } from '@app/lists/actions/download-reading-list.actions'; import { deleteReadingLists } from '@app/lists/actions/reading-lists.actions'; +import { TitleService } from '@app/core/services/title.service'; describe('ReadingListPageComponent', () => { const READING_LIST = READING_LIST_3; @@ -87,6 +88,8 @@ describe('ReadingListPageComponent', () => { removalSubscription.unsubscribe = jasmine.createSpy( 'Subscription.unsubscribe(removals)' ); + let titleService: TitleService; + let translateService: TranslateService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -117,7 +120,8 @@ describe('ReadingListPageComponent', () => { subscribe: jasmine.createSpy('WebSocketService.subscribe()'), unsubscribe: jasmine.createSpy('WebSocketService.unsubscribe()') } - } + }, + TitleService ] }).compileComponents(); @@ -133,6 +137,9 @@ describe('ReadingListPageComponent', () => { webSocketService = TestBed.inject( WebSocketService ) as jasmine.SpyObj; + titleService = TestBed.inject(TitleService); + spyOn(titleService, 'setTitle'); + translateService = TestBed.inject(TranslateService); fixture.detectChanges(); })); @@ -140,6 +147,17 @@ describe('ReadingListPageComponent', () => { expect(component).toBeTruthy(); }); + describe('when the language changes', () => { + beforeEach(() => { + component.readingList = READING_LIST; + translateService.use('fr'); + }); + + it('loads the title', () => { + expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); + }); + }); + describe('when creating a new reading list', () => { beforeEach(() => { component.readingListId = 1; diff --git a/comixed-webui/src/app/lists/pages/reading-list-page/reading-list-page.component.ts b/comixed-webui/src/app/lists/pages/reading-list-page/reading-list-page.component.ts index c07401b8f0..85336f7764 100644 --- a/comixed-webui/src/app/lists/pages/reading-list-page/reading-list-page.component.ts +++ b/comixed-webui/src/app/lists/pages/reading-list-page/reading-list-page.component.ts @@ -51,6 +51,7 @@ import { deleteReadingLists, readingListRemoved } from '@app/lists/actions/reading-lists.actions'; +import { TitleService } from '@app/core/services/title.service'; @Component({ selector: 'cx-user-reading-list-page', @@ -67,6 +68,7 @@ export class ReadingListPageComponent implements OnInit, OnDestroy { readingListForm: FormGroup; readingListId = -1; selectedEntries: Comic[] = []; + langChangeSubscription: Subscription; constructor( private logger: LoggerService, @@ -76,7 +78,8 @@ export class ReadingListPageComponent implements OnInit, OnDestroy { private router: Router, private formBuilder: FormBuilder, private confirmationService: ConfirmationService, - private translateService: TranslateService + private translateService: TranslateService, + private titleService: TitleService ) { this.paramsSubscription = this.activatedRoute.params.subscribe(params => { if (!!params.id) { @@ -116,6 +119,7 @@ export class ReadingListPageComponent implements OnInit, OnDestroy { } else { this.logger.trace('Received reading list'); this.readingList = readingList; + this.loadTranslations(); } }); this.messagingSubscription = this.store @@ -156,6 +160,9 @@ export class ReadingListPageComponent implements OnInit, OnDestroy { ); } }); + this.langChangeSubscription = this.translateService.onLangChange.subscribe( + () => this.loadTranslations() + ); } private _readingList: ReadingList; @@ -272,4 +279,15 @@ export class ReadingListPageComponent implements OnInit, OnDestroy { summary: this.readingListForm.controls.summary.value }; } + + private loadTranslations(): void { + if (!!this.readingList) { + this.logger.trace('Loading tab title'); + this.titleService.setTitle( + this.translateService.instant('reading-list.tab-title', { + name: this.readingList.name + }) + ); + } + } } diff --git a/comixed-webui/src/app/lists/pages/reading-lists-page/reading-lists-page.component.spec.ts b/comixed-webui/src/app/lists/pages/reading-lists-page/reading-lists-page.component.spec.ts index 59229330fe..f926b6714f 100644 --- a/comixed-webui/src/app/lists/pages/reading-lists-page/reading-lists-page.component.spec.ts +++ b/comixed-webui/src/app/lists/pages/reading-lists-page/reading-lists-page.component.spec.ts @@ -26,7 +26,7 @@ import { import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatPaginatorModule } from '@angular/material/paginator'; -import { TranslateModule } from '@ngx-translate/core'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { MatIconModule } from '@angular/material/icon'; import { MatTableModule } from '@angular/material/table'; import { MatTooltipModule } from '@angular/material/tooltip'; @@ -46,6 +46,7 @@ import { uploadReadingList } from '@app/lists/actions/upload-reading-list.action import { SelectableListItem } from '@app/core/models/ui/selectable-list-item'; import { ReadingList } from '@app/lists/models/reading-list'; import { deleteReadingLists } from '@app/lists/actions/reading-lists.actions'; +import { TitleService } from '@app/core/services/title.service'; describe('ReadingListsPageComponent', () => { const READING_LISTS = [READING_LIST_1, READING_LIST_3, READING_LIST_5]; @@ -62,6 +63,8 @@ describe('ReadingListsPageComponent', () => { let fixture: ComponentFixture; let confirmationService: ConfirmationService; let store: MockStore; + let titleService: TitleService; + let translateService: TranslateService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -76,7 +79,11 @@ describe('ReadingListsPageComponent', () => { MatTooltipModule, MatDialogModule ], - providers: [provideMockStore({ initialState }), ConfirmationService] + providers: [ + provideMockStore({ initialState }), + ConfirmationService, + TitleService + ] }).compileComponents(); fixture = TestBed.createComponent(ReadingListsPageComponent); @@ -84,6 +91,9 @@ describe('ReadingListsPageComponent', () => { confirmationService = TestBed.inject(ConfirmationService); store = TestBed.inject(MockStore); spyOn(store, 'dispatch'); + titleService = TestBed.inject(TitleService); + spyOn(titleService, 'setTitle'); + translateService = TestBed.inject(TranslateService); fixture.detectChanges(); })); @@ -91,6 +101,16 @@ describe('ReadingListsPageComponent', () => { expect(component).toBeTruthy(); }); + describe('when the language changes', () => { + beforeEach(() => { + translateService.use('fr'); + }); + + it('loads the title', () => { + expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); + }); + }); + describe('sorting reading lists', () => { const LIST = { item: READING_LISTS[0], diff --git a/comixed-webui/src/app/lists/pages/reading-lists-page/reading-lists-page.component.ts b/comixed-webui/src/app/lists/pages/reading-lists-page/reading-lists-page.component.ts index 37a88c0d20..cc078a16be 100644 --- a/comixed-webui/src/app/lists/pages/reading-lists-page/reading-lists-page.component.ts +++ b/comixed-webui/src/app/lists/pages/reading-lists-page/reading-lists-page.component.ts @@ -44,6 +44,7 @@ import { ConfirmationService } from '@app/core/services/confirmation.service'; import { uploadReadingList } from '@app/lists/actions/upload-reading-list.actions'; import { selectUploadReadingListState } from '@app/lists/selectors/upload-reading-list.selectors'; import { SelectableListItem } from '@app/core/models/ui/selectable-list-item'; +import { TitleService } from '@app/core/services/title.service'; @Component({ selector: 'cx-reading-lists-page', @@ -60,6 +61,7 @@ export class ReadingListsPageComponent readingListStateSubscription: Subscription; readingListsSubscription: Subscription; uploadReadingListSubscription: Subscription; + langChangeSubscription: Subscription; readonly displayedColumns = [ 'selection', @@ -76,7 +78,8 @@ export class ReadingListsPageComponent private logger: LoggerService, private store: Store, private confirmationService: ConfirmationService, - private translateService: TranslateService + private translateService: TranslateService, + private titleService: TitleService ) { this.logger.trace('Subscribing to reading list state updates'); this.readingListStateSubscription = this.store @@ -94,6 +97,9 @@ export class ReadingListsPageComponent this.logger.trace('Uploading reading list state change'); this.store.dispatch(setBusyState({ enabled: state.uploading })); }); + this.langChangeSubscription = this.translateService.onLangChange.subscribe( + () => this.loadTranslations() + ); } private _readingLists: ReadingList[]; @@ -116,6 +122,7 @@ export class ReadingListsPageComponent ngOnInit(): void { this.logger.trace('Loading all user reading lists'); this.store.dispatch(loadReadingLists()); + this.loadTranslations(); } ngAfterViewInit(): void { @@ -145,6 +152,8 @@ export class ReadingListsPageComponent this.readingListsSubscription.unsubscribe(); this.logger.trace('Unsubscribing from upload reading list state updates'); this.uploadReadingListSubscription.unsubscribe(); + this.logger.trace('Unsubscribing from language change updates'); + this.langChangeSubscription.unsubscribe(); } onShowUploadRow(): void { @@ -207,4 +216,11 @@ export class ReadingListsPageComponent this.hasSelections = this.allSelected || this.dataSource.data.some(entry => entry.selected); } + + private loadTranslations(): void { + this.logger.trace('Loading reading lists tab title'); + this.titleService.setTitle( + this.translateService.instant('reading-lists.tab-title') + ); + } } diff --git a/comixed-webui/src/app/pages/build-details/build-details.component.html b/comixed-webui/src/app/pages/build-details/build-details.component.html index f1e252e9df..de7438bdb7 100644 --- a/comixed-webui/src/app/pages/build-details/build-details.component.html +++ b/comixed-webui/src/app/pages/build-details/build-details.component.html @@ -1,6 +1,8 @@
- {{ "build-details.title" | translate }} + + {{ "build-details.page-title" | translate }} +
{{ "build-details.label.branch" | translate: { name: details.branch } }} diff --git a/comixed-webui/src/app/pages/build-details/build-details.component.spec.ts b/comixed-webui/src/app/pages/build-details/build-details.component.spec.ts index 55e78dc1c9..610a00458d 100644 --- a/comixed-webui/src/app/pages/build-details/build-details.component.spec.ts +++ b/comixed-webui/src/app/pages/build-details/build-details.component.spec.ts @@ -24,9 +24,10 @@ import { initialState as initialBuildState } from '@app/reducers/build-details.reducer'; import { provideMockStore } from '@ngrx/store/testing'; -import { TranslateModule } from '@ngx-translate/core'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { BUILD_DETAILS } from '@app/app.fixtures'; import { MatCardModule } from '@angular/material/card'; +import { TitleService } from '@app/core/services/title.service'; describe('BuildDetailsComponent', () => { const initialState = { @@ -38,6 +39,8 @@ describe('BuildDetailsComponent', () => { let component: BuildDetailsComponent; let fixture: ComponentFixture; + let titleService: TitleService; + let translateService: TranslateService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -47,15 +50,28 @@ describe('BuildDetailsComponent', () => { TranslateModule.forRoot(), MatCardModule ], - providers: [provideMockStore({ initialState })] + providers: [provideMockStore({ initialState }), TitleService] }).compileComponents(); fixture = TestBed.createComponent(BuildDetailsComponent); component = fixture.componentInstance; + titleService = TestBed.inject(TitleService); + spyOn(titleService, 'setTitle'); + translateService = TestBed.inject(TranslateService); fixture.detectChanges(); })); it('should create', () => { expect(component).toBeTruthy(); }); + + describe('when the language changes', () => { + beforeEach(() => { + translateService.use('fr'); + }); + + it('loads the title', () => { + expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); + }); + }); }); diff --git a/comixed-webui/src/app/pages/build-details/build-details.component.ts b/comixed-webui/src/app/pages/build-details/build-details.component.ts index 34fa70459f..9b783fd623 100644 --- a/comixed-webui/src/app/pages/build-details/build-details.component.ts +++ b/comixed-webui/src/app/pages/build-details/build-details.component.ts @@ -24,6 +24,8 @@ import { BuildDetails } from '@app/models/build-details'; import { selectBuildDetailsState } from '@app/selectors/build-details.selectors'; import { setBusyState } from '@app/core/actions/busy.actions'; import { loadBuildDetails } from '@app/actions/build-details.actions'; +import { TitleService } from '@app/core/services/title.service'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'cx-build-details', @@ -33,19 +35,39 @@ import { loadBuildDetails } from '@app/actions/build-details.actions'; export class BuildDetailsComponent implements OnInit, OnDestroy { detailsSubscription: Subscription; details: BuildDetails; + langChangeSubscription: Subscription; - constructor(private logger: LoggerService, private store: Store) { + constructor( + private logger: LoggerService, + private store: Store, + private translateService: TranslateService, + private titleService: TitleService + ) { this.detailsSubscription = this.store .select(selectBuildDetailsState) .subscribe(state => { this.store.dispatch(setBusyState({ enabled: state.loading })); this.details = state.details; }); + this.langChangeSubscription = this.translateService.onLangChange.subscribe( + () => this.loadTranslations() + ); } ngOnInit(): void { this.store.dispatch(loadBuildDetails()); + this.loadTranslations(); } - ngOnDestroy(): void {} + ngOnDestroy(): void { + this.logger.trace('Unsubscribing from language changes'); + this.langChangeSubscription.unsubscribe(); + } + + private loadTranslations(): void { + this.logger.trace('Setting tab title'); + this.titleService.setTitle( + this.translateService.instant('build-details.tab-title') + ); + } } diff --git a/comixed-webui/src/app/user/pages/user-preferences-page/user-preferences-page.component.spec.ts b/comixed-webui/src/app/user/pages/user-preferences-page/user-preferences-page.component.spec.ts index 9b6c595d09..dccfaae2ca 100644 --- a/comixed-webui/src/app/user/pages/user-preferences-page/user-preferences-page.component.spec.ts +++ b/comixed-webui/src/app/user/pages/user-preferences-page/user-preferences-page.component.spec.ts @@ -19,7 +19,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { UserPreferencesPageComponent } from './user-preferences-page.component'; import { LoggerModule } from '@angular-ru/logger'; -import { TranslateModule } from '@ngx-translate/core'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { ConfirmationService } from '@app/core/services/confirmation.service'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { @@ -33,6 +33,7 @@ import { MatSortModule } from '@angular/material/sort'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { saveUserPreference } from '@app/user/actions/user.actions'; import { Confirmation } from '@app/core/models/confirmation'; +import { TitleService } from '@app/core/services/title.service'; describe('UserPreferencesPageComponent', () => { const USER = USER_READER; @@ -45,6 +46,8 @@ describe('UserPreferencesPageComponent', () => { let fixture: ComponentFixture; let confirmationService: ConfirmationService; let store: MockStore; + let titleService: TitleService; + let translateService: TranslateService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -57,7 +60,11 @@ describe('UserPreferencesPageComponent', () => { MatTableModule, MatSortModule ], - providers: [provideMockStore({ initialState }), ConfirmationService] + providers: [ + provideMockStore({ initialState }), + ConfirmationService, + TitleService + ] }).compileComponents(); fixture = TestBed.createComponent(UserPreferencesPageComponent); @@ -65,6 +72,9 @@ describe('UserPreferencesPageComponent', () => { confirmationService = TestBed.inject(ConfirmationService); store = TestBed.inject(MockStore); spyOn(store, 'dispatch'); + titleService = TestBed.inject(TitleService); + spyOn(titleService, 'setTitle'); + translateService = TestBed.inject(TranslateService); fixture.detectChanges(); })); @@ -72,6 +82,16 @@ describe('UserPreferencesPageComponent', () => { expect(component).toBeTruthy(); }); + describe('when the language changes', () => { + beforeEach(() => { + translateService.use('fr'); + }); + + it('loads the title', () => { + expect(titleService.setTitle).toHaveBeenCalledWith(jasmine.any(String)); + }); + }); + describe('deleting a user preference', () => { beforeEach(() => { spyOn(confirmationService, 'confirm').and.callFake( diff --git a/comixed-webui/src/app/user/pages/user-preferences-page/user-preferences-page.component.ts b/comixed-webui/src/app/user/pages/user-preferences-page/user-preferences-page.component.ts index e7361ab4fe..bb2cb596cf 100644 --- a/comixed-webui/src/app/user/pages/user-preferences-page/user-preferences-page.component.ts +++ b/comixed-webui/src/app/user/pages/user-preferences-page/user-preferences-page.component.ts @@ -33,6 +33,7 @@ import { ConfirmationService } from '@app/core/services/confirmation.service'; import { TranslateService } from '@ngx-translate/core'; import { saveUserPreference } from '@app/user/actions/user.actions'; import { Preference } from '@app/user/models/preference'; +import { TitleService } from '@app/core/services/title.service'; @Component({ selector: 'cx-user-preferences-page', @@ -47,17 +48,22 @@ export class UserPreferencesPageComponent readonly displayedColumns = ['name', 'value', 'actions']; dataSource = new MatTableDataSource([]); userSubscription: Subscription; + langChangeSubscription: Subscription; constructor( private logger: LoggerService, private store: Store, private confirmationService: ConfirmationService, - private translateService: TranslateService + private translateService: TranslateService, + private titleService: TitleService ) { this.userSubscription = this.store.select(selectUser).subscribe(user => { this.logger.trace('Loading user preferences'); this.dataSource.data = user.preferences; }); + this.langChangeSubscription = this.translateService.onLangChange.subscribe( + () => this.loadTranslations() + ); } ngAfterViewInit(): void { @@ -72,10 +78,14 @@ export class UserPreferencesPageComponent return data.value; } }; + this.loadTranslations(); } ngOnDestroy(): void { + this.logger.trace('Unsubscribing from user updates'); this.userSubscription.unsubscribe(); + this.logger.trace('Unsubscribing from language change updates'); + this.langChangeSubscription.unsubscribe(); } ngOnInit(): void {} @@ -94,4 +104,11 @@ export class UserPreferencesPageComponent } }); } + + private loadTranslations(): void { + this.logger.trace('Loading tab title'); + this.titleService.setTitle( + this.translateService.instant('user.user-preferences.tab-title') + ); + } } diff --git a/comixed-webui/src/assets/i18n/de/admin.json b/comixed-webui/src/assets/i18n/de/admin.json index ded4388531..297974b616 100644 --- a/comixed-webui/src/assets/i18n/de/admin.json +++ b/comixed-webui/src/assets/i18n/de/admin.json @@ -58,6 +58,7 @@ }, "request-content-title": "Request Content", "response-content-title": "Response Content", + "tab-title": "Web Audit Log", "text": { "runtime": "{time}ms" } diff --git a/comixed-webui/src/assets/i18n/de/app.json b/comixed-webui/src/assets/i18n/de/app.json index 09e3bdb00f..1c0c009f4c 100644 --- a/comixed-webui/src/assets/i18n/de/app.json +++ b/comixed-webui/src/assets/i18n/de/app.json @@ -18,8 +18,9 @@ "jdbc-url": "The database URL being used is {url}", "remote-origin-url": "This branch is tracking the remote branch {url}" }, - "title": "Build Details", - "load-effect-failure": "Failed to load the build details." + "load-effect-failure": "Failed to load the build details.", + "page-title": "Build Details", + "tab-title": "Build Details" }, "button": { "cancel": "Cancel", diff --git a/comixed-webui/src/assets/i18n/de/blocked-pages.json b/comixed-webui/src/assets/i18n/de/blocked-pages.json index 13a058ba0e..67666573d2 100644 --- a/comixed-webui/src/assets/i18n/de/blocked-pages.json +++ b/comixed-webui/src/assets/i18n/de/blocked-pages.json @@ -52,6 +52,7 @@ "effect-failure": "Failed to {deleted, select, true{mark} other{clear}} the deletion flag.", "effect-success": "{deleted, select, true{Marked} other{Cleared}} {count, plural, =1{one page} other{# pages}} for deletion." }, + "tab-title": "Blocked Hash List", "tooltip": { "clear-deleted": "Clear selected pages from deletion.", "delete-entries": "Delete selected blocked page entries.", diff --git a/comixed-webui/src/assets/i18n/de/collections.json b/comixed-webui/src/assets/i18n/de/collections.json index 3fcf8bbea0..0b066d58c5 100644 --- a/comixed-webui/src/assets/i18n/de/collections.json +++ b/comixed-webui/src/assets/i18n/de/collections.json @@ -1,9 +1,13 @@ { + "collection-detail": { + "tab-title": "{collection, select, characters{Character} teams{Team} locations{Location} stories{Storie} publishers{Publisher} series{Series} other{Unknown}}: {name}" + }, "collection-list": { "label": { "comic-count": "# Comics", "name": "Collection Name" }, + "tab-title": "Collections: {collection, select, characters{Characters} teams{Teams} locations{Locations} stories{Stories} publishers{Publishers} series{Series} other{Unknown}}", "text": { "undefined": "[UNDEFINED]" } diff --git a/comixed-webui/src/assets/i18n/de/library.json b/comixed-webui/src/assets/i18n/de/library.json index 924fc1cc4e..610efa9b7a 100644 --- a/comixed-webui/src/assets/i18n/de/library.json +++ b/comixed-webui/src/assets/i18n/de/library.json @@ -50,7 +50,8 @@ "all-comics": { "tab-title": "All Comics", "tab-title-deleted": "Deleted Comics", - "tab-title-unread": "Unread Comics" + "tab-title-unread": "Unread Comics", + "tab-title-unscraped": "Unscraped Comics" }, "comic-group": { "invalid-grouping": "The group \"{name}\" is not valid." diff --git a/comixed-webui/src/assets/i18n/de/reading-lists.json b/comixed-webui/src/assets/i18n/de/reading-lists.json index 3259e31862..ad2c31dd5e 100644 --- a/comixed-webui/src/assets/i18n/de/reading-lists.json +++ b/comixed-webui/src/assets/i18n/de/reading-lists.json @@ -20,6 +20,7 @@ "effect-failure": "Failed to save reading list.", "effect-success": "Reading list saved." }, + "tab-title": "Reading List: {name}", "text": { "no-name": "Unnamed Reading List" }, @@ -59,6 +60,7 @@ "load-for-user": { "effect-failure": "Failed to load reading lists." }, + "tab-title": "Reading Lists", "tooltip": { "add-reading-list": "Add a new reading list.", "delete-reading-lists": "Delete the selected reading lists." diff --git a/comixed-webui/src/assets/i18n/de/user.json b/comixed-webui/src/assets/i18n/de/user.json index 18c00ffd86..aef7453963 100644 --- a/comixed-webui/src/assets/i18n/de/user.json +++ b/comixed-webui/src/assets/i18n/de/user.json @@ -44,6 +44,7 @@ "preference-name": "Preference Name", "preference-value": "Value" }, + "tab-title": "User Preferences", "tooltip": { "delete-preference": "Delete this user preference." } diff --git a/comixed-webui/src/assets/i18n/en/admin.json b/comixed-webui/src/assets/i18n/en/admin.json index ded4388531..297974b616 100644 --- a/comixed-webui/src/assets/i18n/en/admin.json +++ b/comixed-webui/src/assets/i18n/en/admin.json @@ -58,6 +58,7 @@ }, "request-content-title": "Request Content", "response-content-title": "Response Content", + "tab-title": "Web Audit Log", "text": { "runtime": "{time}ms" } diff --git a/comixed-webui/src/assets/i18n/en/app.json b/comixed-webui/src/assets/i18n/en/app.json index 09e3bdb00f..1c0c009f4c 100644 --- a/comixed-webui/src/assets/i18n/en/app.json +++ b/comixed-webui/src/assets/i18n/en/app.json @@ -18,8 +18,9 @@ "jdbc-url": "The database URL being used is {url}", "remote-origin-url": "This branch is tracking the remote branch {url}" }, - "title": "Build Details", - "load-effect-failure": "Failed to load the build details." + "load-effect-failure": "Failed to load the build details.", + "page-title": "Build Details", + "tab-title": "Build Details" }, "button": { "cancel": "Cancel", diff --git a/comixed-webui/src/assets/i18n/en/blocked-pages.json b/comixed-webui/src/assets/i18n/en/blocked-pages.json index 933c752342..db86fb827a 100644 --- a/comixed-webui/src/assets/i18n/en/blocked-pages.json +++ b/comixed-webui/src/assets/i18n/en/blocked-pages.json @@ -52,6 +52,7 @@ "effect-failure": "Failed to {deleted, select, true{mark} other{clear}} the deletion flag.", "effect-success": "{deleted, select, true{Marked} other{Cleared}} {count, plural, =1{one page} other{# pages}} for deletion." }, + "tab-title": "Blocked Hash List", "tooltip": { "clear-deleted": "Clear selected pages from deletion.", "delete-entries": "Delete selected blocked page entries.", diff --git a/comixed-webui/src/assets/i18n/en/collections.json b/comixed-webui/src/assets/i18n/en/collections.json index 3fcf8bbea0..0b066d58c5 100644 --- a/comixed-webui/src/assets/i18n/en/collections.json +++ b/comixed-webui/src/assets/i18n/en/collections.json @@ -1,9 +1,13 @@ { + "collection-detail": { + "tab-title": "{collection, select, characters{Character} teams{Team} locations{Location} stories{Storie} publishers{Publisher} series{Series} other{Unknown}}: {name}" + }, "collection-list": { "label": { "comic-count": "# Comics", "name": "Collection Name" }, + "tab-title": "Collections: {collection, select, characters{Characters} teams{Teams} locations{Locations} stories{Stories} publishers{Publishers} series{Series} other{Unknown}}", "text": { "undefined": "[UNDEFINED]" } diff --git a/comixed-webui/src/assets/i18n/en/library.json b/comixed-webui/src/assets/i18n/en/library.json index 924fc1cc4e..610efa9b7a 100644 --- a/comixed-webui/src/assets/i18n/en/library.json +++ b/comixed-webui/src/assets/i18n/en/library.json @@ -50,7 +50,8 @@ "all-comics": { "tab-title": "All Comics", "tab-title-deleted": "Deleted Comics", - "tab-title-unread": "Unread Comics" + "tab-title-unread": "Unread Comics", + "tab-title-unscraped": "Unscraped Comics" }, "comic-group": { "invalid-grouping": "The group \"{name}\" is not valid." diff --git a/comixed-webui/src/assets/i18n/en/reading-lists.json b/comixed-webui/src/assets/i18n/en/reading-lists.json index e21c4a1eb0..7d5dfa4712 100644 --- a/comixed-webui/src/assets/i18n/en/reading-lists.json +++ b/comixed-webui/src/assets/i18n/en/reading-lists.json @@ -20,6 +20,7 @@ "effect-failure": "Failed to save reading list.", "effect-success": "Reading list saved." }, + "tab-title": "Reading List: {name}", "text": { "no-name": "Unnamed Reading List" }, @@ -59,6 +60,7 @@ "load-for-user": { "effect-failure": "Failed to load reading lists." }, + "tab-title": "Reading Lists", "tooltip": { "add-reading-list": "Add a new reading list.", "delete-reading-lists": "Delete the selected reading lists." diff --git a/comixed-webui/src/assets/i18n/en/user.json b/comixed-webui/src/assets/i18n/en/user.json index 18c00ffd86..aef7453963 100644 --- a/comixed-webui/src/assets/i18n/en/user.json +++ b/comixed-webui/src/assets/i18n/en/user.json @@ -44,6 +44,7 @@ "preference-name": "Preference Name", "preference-value": "Value" }, + "tab-title": "User Preferences", "tooltip": { "delete-preference": "Delete this user preference." } diff --git a/comixed-webui/src/assets/i18n/es/admin.json b/comixed-webui/src/assets/i18n/es/admin.json index 79cedf85fd..42db09eceb 100644 --- a/comixed-webui/src/assets/i18n/es/admin.json +++ b/comixed-webui/src/assets/i18n/es/admin.json @@ -58,6 +58,7 @@ }, "request-content-title": "Contenido de solicitud", "response-content-title": "Contenido de respuesta", + "tab-title": "Web Audit Log", "text": { "runtime": "{time}ms" } diff --git a/comixed-webui/src/assets/i18n/es/app.json b/comixed-webui/src/assets/i18n/es/app.json index 629ad2ea25..dbae0c6990 100644 --- a/comixed-webui/src/assets/i18n/es/app.json +++ b/comixed-webui/src/assets/i18n/es/app.json @@ -18,8 +18,9 @@ "jdbc-url": "La dirección URL de la base de datos que se utiliza es {url}", "remote-origin-url": "Esta rama está rastreando la rama remota {url}" }, - "title": "Detalles de la compilación", - "load-effect-failure": "No se pudieron cargar los detalles de la compilación." + "load-effect-failure": "No se pudieron cargar los detalles de la compilación.", + "page-title": "Detalles de la compilación" + "tab-title": "Detalles de la compilación" }, "button": { "cancel": "Cancelar", diff --git a/comixed-webui/src/assets/i18n/es/blocked-pages.json b/comixed-webui/src/assets/i18n/es/blocked-pages.json index 3183bddde8..216b9c98b9 100644 --- a/comixed-webui/src/assets/i18n/es/blocked-pages.json +++ b/comixed-webui/src/assets/i18n/es/blocked-pages.json @@ -52,6 +52,7 @@ "effect-failure": "Failed to {deleted, select, true{mark} other{clear}} the deletion flag.", "effect-success": "{deleted, select, true{Marked} other{Cleared}} {count, plural, =1{one page} other{# pages}} for deletion." }, + "tab-title": "Blocked Hash List", "tooltip": { "clear-deleted": "Clear selected pages from deletion.", "delete-entries": "Delete selected blocked page entries.", diff --git a/comixed-webui/src/assets/i18n/es/collections.json b/comixed-webui/src/assets/i18n/es/collections.json index 0326196af8..995da33c39 100644 --- a/comixed-webui/src/assets/i18n/es/collections.json +++ b/comixed-webui/src/assets/i18n/es/collections.json @@ -1,9 +1,13 @@ { + "collection-detail": { + "tab-title": "{collection, select, characters{Character} teams{Team} locations{Location} stories{Storie} publishers{Publisher} series{Series} other{Unknown}}: {name}" + }, "collection-list": { "label": { "comic-count": "# cómics", "name": "Nombre de la colección" }, + "tab-title": "Collections: {collection, select, characters{Characters} teams{Teams} locations{Locations} stories{Stories} publishers{Publishers} series{Series} other{Unknown}}", "text": { "undefined": "[INDEFINIDO]" } diff --git a/comixed-webui/src/assets/i18n/es/library.json b/comixed-webui/src/assets/i18n/es/library.json index 8dc792885f..efee36f592 100644 --- a/comixed-webui/src/assets/i18n/es/library.json +++ b/comixed-webui/src/assets/i18n/es/library.json @@ -50,7 +50,8 @@ "all-comics": { "tab-title": "Todos los cómics", "tab-title-deleted": "Cómics eliminados", - "tab-title-unread": "Cómics no leídos" + "tab-title-unread": "Cómics no leídos", + "tab-title-unscraped": "Unscraped Comics" }, "comic-group": { "invalid-grouping": "El grupo \"{name}\" no es válido." diff --git a/comixed-webui/src/assets/i18n/es/reading-lists.json b/comixed-webui/src/assets/i18n/es/reading-lists.json index 517057b28f..6af59754c5 100644 --- a/comixed-webui/src/assets/i18n/es/reading-lists.json +++ b/comixed-webui/src/assets/i18n/es/reading-lists.json @@ -20,6 +20,7 @@ "effect-failure": "Failed to save reading list.", "effect-success": "Reading list saved." }, + "tab-title": "Reading List: {name}", "text": { "no-name": "Unnamed Reading List" }, @@ -59,6 +60,7 @@ "load-for-user": { "effect-failure": "Failed to load reading lists." }, + "tab-title": "Reading Lists", "tooltip": { "add-reading-list": "Add a new reading list.", "delete-reading-lists": "Delete the selected reading lists." diff --git a/comixed-webui/src/assets/i18n/es/user.json b/comixed-webui/src/assets/i18n/es/user.json index 0d509697a0..509ba13a13 100644 --- a/comixed-webui/src/assets/i18n/es/user.json +++ b/comixed-webui/src/assets/i18n/es/user.json @@ -44,6 +44,7 @@ "preference-name": "Nombre de preferencia", "preference-value": "Valor" }, + "tab-title": "User Preferences", "tooltip": { "delete-preference": "Eliminar esta preferencia de usuario." } diff --git a/comixed-webui/src/assets/i18n/fr/admin.json b/comixed-webui/src/assets/i18n/fr/admin.json index e6d3980015..84bdf2c389 100644 --- a/comixed-webui/src/assets/i18n/fr/admin.json +++ b/comixed-webui/src/assets/i18n/fr/admin.json @@ -58,6 +58,7 @@ }, "request-content-title": "Contenu de la requête", "response-content-title": "Contenu de la réponse", + "tab-title": "Web Audit Log", "text": { "runtime": "{time}ms" } diff --git a/comixed-webui/src/assets/i18n/fr/app.json b/comixed-webui/src/assets/i18n/fr/app.json index 9ae8a8a6da..bab2c32e8c 100644 --- a/comixed-webui/src/assets/i18n/fr/app.json +++ b/comixed-webui/src/assets/i18n/fr/app.json @@ -18,8 +18,9 @@ "jdbc-url": "L'url de la base de données utilisée est {url}", "remote-origin-url": "Cette branche suit la branche distante {url}" }, - "title": "Détails du Build", - "load-effect-failure": "Échec de la récupération des détails du build..." + "load-effect-failure": "Échec de la récupération des détails du build...", + "page-title": "Détails du Build" + "tab-title": "Détails du Build" }, "button": { "cancel": "Annuler", diff --git a/comixed-webui/src/assets/i18n/fr/blocked-pages.json b/comixed-webui/src/assets/i18n/fr/blocked-pages.json index ae82b0a820..5bf8aed151 100644 --- a/comixed-webui/src/assets/i18n/fr/blocked-pages.json +++ b/comixed-webui/src/assets/i18n/fr/blocked-pages.json @@ -52,6 +52,7 @@ "effect-failure": "Échec {deleted, select, true{de l'ajout} other{de l'annulation}} du flag de suppression.", "effect-success": "{deleted, select, true{Marquage} other{Nettoyage}} {count, plural, =1{d'une page} other{# pages}} pour suppression." }, + "tab-title": "Blocked Hash List", "tooltip": { "clear-deleted": "Effacer les pages sélectionnées de la suppression.", "delete-entries": "Supprimer les entrées de pages bloquées sélectionnées.", diff --git a/comixed-webui/src/assets/i18n/fr/collections.json b/comixed-webui/src/assets/i18n/fr/collections.json index e571d05cf1..f982aa3a89 100644 --- a/comixed-webui/src/assets/i18n/fr/collections.json +++ b/comixed-webui/src/assets/i18n/fr/collections.json @@ -1,9 +1,13 @@ { + "collection-detail": { + "tab-title": "{collection, select, characters{Character} teams{Team} locations{Location} stories{Storie} publishers{Publisher} series{Series} other{Unknown}}: {name}" + }, "collection-list": { "label": { "comic-count": "# Bandes dessinées", "name": "Nom de la collection" }, + "tab-title": "Collections: {collection, select, characters{Characters} teams{Teams} locations{Locations} stories{Stories} publishers{Publishers} series{Series} other{Unknown}}", "text": { "undefined": "[NON DEFINIE]" } diff --git a/comixed-webui/src/assets/i18n/fr/library.json b/comixed-webui/src/assets/i18n/fr/library.json index 9558a70a2b..22da5a4d99 100644 --- a/comixed-webui/src/assets/i18n/fr/library.json +++ b/comixed-webui/src/assets/i18n/fr/library.json @@ -50,7 +50,8 @@ "all-comics": { "tab-title": "Toutes les Bandes Dessinées", "tab-title-deleted": "Bandes dessinées supprimées", - "tab-title-unread": "Bandes dessinées non lues" + "tab-title-unread": "Bandes dessinées non lues", + "tab-title-unscraped": "Unscraped Comics" }, "comic-group": { "invalid-grouping": "Le groupe \"{name}\" n'est pas valide." diff --git a/comixed-webui/src/assets/i18n/fr/reading-lists.json b/comixed-webui/src/assets/i18n/fr/reading-lists.json index ff43dca1c8..8b0ba6d252 100644 --- a/comixed-webui/src/assets/i18n/fr/reading-lists.json +++ b/comixed-webui/src/assets/i18n/fr/reading-lists.json @@ -20,6 +20,7 @@ "effect-failure": "Échec de la sauvegarde de la liste de lecture.", "effect-success": "Liste de lecture sauvegardée." }, + "tab-title": "Reading List: {name}", "text": { "no-name": "Liste de lecture sans nom" }, @@ -59,6 +60,7 @@ "load-for-user": { "effect-failure": "Échec du chargement des listes de lecture." }, + "tab-title": "Reading Lists", "tooltip": { "add-reading-list": "Ajouter une nouvelle liste de lecture.", "delete-reading-lists": "Supprimer les listes de lecture sélectionnées." diff --git a/comixed-webui/src/assets/i18n/fr/user.json b/comixed-webui/src/assets/i18n/fr/user.json index 0b7045efdd..0b46e12ecf 100644 --- a/comixed-webui/src/assets/i18n/fr/user.json +++ b/comixed-webui/src/assets/i18n/fr/user.json @@ -44,6 +44,7 @@ "preference-name": "Nom de la préférence", "preference-value": "Valeur" }, + "tab-title": "User Preferences", "tooltip": { "delete-preference": "Supprimer cette préférence utilisateur." } diff --git a/comixed-webui/src/assets/i18n/pt/admin.json b/comixed-webui/src/assets/i18n/pt/admin.json index ded4388531..297974b616 100644 --- a/comixed-webui/src/assets/i18n/pt/admin.json +++ b/comixed-webui/src/assets/i18n/pt/admin.json @@ -58,6 +58,7 @@ }, "request-content-title": "Request Content", "response-content-title": "Response Content", + "tab-title": "Web Audit Log", "text": { "runtime": "{time}ms" } diff --git a/comixed-webui/src/assets/i18n/pt/app.json b/comixed-webui/src/assets/i18n/pt/app.json index 09e3bdb00f..1c0c009f4c 100644 --- a/comixed-webui/src/assets/i18n/pt/app.json +++ b/comixed-webui/src/assets/i18n/pt/app.json @@ -18,8 +18,9 @@ "jdbc-url": "The database URL being used is {url}", "remote-origin-url": "This branch is tracking the remote branch {url}" }, - "title": "Build Details", - "load-effect-failure": "Failed to load the build details." + "load-effect-failure": "Failed to load the build details.", + "page-title": "Build Details", + "tab-title": "Build Details" }, "button": { "cancel": "Cancel", diff --git a/comixed-webui/src/assets/i18n/pt/blocked-pages.json b/comixed-webui/src/assets/i18n/pt/blocked-pages.json index 933c752342..db86fb827a 100644 --- a/comixed-webui/src/assets/i18n/pt/blocked-pages.json +++ b/comixed-webui/src/assets/i18n/pt/blocked-pages.json @@ -52,6 +52,7 @@ "effect-failure": "Failed to {deleted, select, true{mark} other{clear}} the deletion flag.", "effect-success": "{deleted, select, true{Marked} other{Cleared}} {count, plural, =1{one page} other{# pages}} for deletion." }, + "tab-title": "Blocked Hash List", "tooltip": { "clear-deleted": "Clear selected pages from deletion.", "delete-entries": "Delete selected blocked page entries.", diff --git a/comixed-webui/src/assets/i18n/pt/collections.json b/comixed-webui/src/assets/i18n/pt/collections.json index 3fcf8bbea0..0b066d58c5 100644 --- a/comixed-webui/src/assets/i18n/pt/collections.json +++ b/comixed-webui/src/assets/i18n/pt/collections.json @@ -1,9 +1,13 @@ { + "collection-detail": { + "tab-title": "{collection, select, characters{Character} teams{Team} locations{Location} stories{Storie} publishers{Publisher} series{Series} other{Unknown}}: {name}" + }, "collection-list": { "label": { "comic-count": "# Comics", "name": "Collection Name" }, + "tab-title": "Collections: {collection, select, characters{Characters} teams{Teams} locations{Locations} stories{Stories} publishers{Publishers} series{Series} other{Unknown}}", "text": { "undefined": "[UNDEFINED]" } diff --git a/comixed-webui/src/assets/i18n/pt/library.json b/comixed-webui/src/assets/i18n/pt/library.json index 924fc1cc4e..610efa9b7a 100644 --- a/comixed-webui/src/assets/i18n/pt/library.json +++ b/comixed-webui/src/assets/i18n/pt/library.json @@ -50,7 +50,8 @@ "all-comics": { "tab-title": "All Comics", "tab-title-deleted": "Deleted Comics", - "tab-title-unread": "Unread Comics" + "tab-title-unread": "Unread Comics", + "tab-title-unscraped": "Unscraped Comics" }, "comic-group": { "invalid-grouping": "The group \"{name}\" is not valid." diff --git a/comixed-webui/src/assets/i18n/pt/reading-lists.json b/comixed-webui/src/assets/i18n/pt/reading-lists.json index 07da1ec472..dca8e38f23 100644 --- a/comixed-webui/src/assets/i18n/pt/reading-lists.json +++ b/comixed-webui/src/assets/i18n/pt/reading-lists.json @@ -20,6 +20,7 @@ "effect-failure": "Failed to save reading list.", "effect-success": "Reading list saved." }, + "tab-title": "Reading List: {name}", "text": { "no-name": "Unnamed Reading List" }, @@ -59,6 +60,7 @@ "load-for-user": { "effect-failure": "Failed to load reading lists." }, + "tab-title": "Reading Lists", "tooltip": { "add-reading-list": "Add a new reading list.", "delete-reading-lists": "Delete the selected reading lists." diff --git a/comixed-webui/src/assets/i18n/pt/user.json b/comixed-webui/src/assets/i18n/pt/user.json index 18c00ffd86..aef7453963 100644 --- a/comixed-webui/src/assets/i18n/pt/user.json +++ b/comixed-webui/src/assets/i18n/pt/user.json @@ -44,6 +44,7 @@ "preference-name": "Preference Name", "preference-value": "Value" }, + "tab-title": "User Preferences", "tooltip": { "delete-preference": "Delete this user preference." }