mirror of
https://github.com/booklore-app/booklore.git
synced 2025-12-23 22:28:11 -05:00
fix: Consistent dialogs (#1842)
* fix/consistent-dialogs * fix: enforce consistent mobile dialog width * fix: cover search dialog image size
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import {inject, Injectable} from '@angular/core';
|
import {inject, Injectable} from '@angular/core';
|
||||||
import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import {DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
|
import {DialogLauncherService} from '../../../../shared/services/dialog-launcher.service';
|
||||||
import {ShelfAssignerComponent} from '../shelf-assigner/shelf-assigner.component';
|
import {ShelfAssignerComponent} from '../shelf-assigner/shelf-assigner.component';
|
||||||
import {LockUnlockMetadataDialogComponent} from './lock-unlock-metadata-dialog/lock-unlock-metadata-dialog.component';
|
import {LockUnlockMetadataDialogComponent} from './lock-unlock-metadata-dialog/lock-unlock-metadata-dialog.component';
|
||||||
import {MetadataRefreshType} from '../../../metadata/model/request/metadata-refresh-type.enum';
|
import {MetadataRefreshType} from '../../../metadata/model/request/metadata-refresh-type.enum';
|
||||||
@@ -8,50 +9,61 @@ import {MultiBookMetadataEditorComponent} from '../../../metadata/component/mult
|
|||||||
import {MultiBookMetadataFetchComponent} from '../../../metadata/component/multi-book-metadata-fetch/multi-book-metadata-fetch-component';
|
import {MultiBookMetadataFetchComponent} from '../../../metadata/component/multi-book-metadata-fetch/multi-book-metadata-fetch-component';
|
||||||
import {FileMoverComponent} from '../../../../shared/components/file-mover/file-mover-component';
|
import {FileMoverComponent} from '../../../../shared/components/file-mover/file-mover-component';
|
||||||
import {ShelfCreatorComponent} from '../shelf-creator/shelf-creator.component';
|
import {ShelfCreatorComponent} from '../shelf-creator/shelf-creator.component';
|
||||||
|
import {BookSenderComponent} from '../book-sender/book-sender.component';
|
||||||
|
import {MetadataFetchOptionsComponent} from '../../../metadata/component/metadata-options-dialog/metadata-fetch-options/metadata-fetch-options.component';
|
||||||
|
import {BookMetadataCenterComponent} from '../../../metadata/component/book-metadata-center/book-metadata-center.component';
|
||||||
|
import {CoverSearchComponent} from '../../../metadata/component/cover-search/cover-search.component';
|
||||||
|
import {Book} from '../../model/book.model';
|
||||||
|
import {AdditionalFileUploaderComponent} from '../additional-file-uploader/additional-file-uploader.component';
|
||||||
|
|
||||||
@Injectable({providedIn: 'root'})
|
@Injectable({providedIn: 'root'})
|
||||||
export class BookDialogHelperService {
|
export class BookDialogHelperService {
|
||||||
|
|
||||||
private dialogService = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
|
|
||||||
|
private openDialog(component: any, options: {}): DynamicDialogRef | null {
|
||||||
|
return this.dialogLauncherService.openDialog(component, options);
|
||||||
|
}
|
||||||
|
|
||||||
openShelfAssigner(bookIds: Set<number>): DynamicDialogRef | null {
|
openBookDetailsDialog(bookId: number): DynamicDialogRef | null {
|
||||||
return this.dialogService.open(ShelfAssignerComponent, {
|
return this.openDialog(BookMetadataCenterComponent, {
|
||||||
showHeader: false,
|
header: 'Book Details',
|
||||||
modal: true,
|
styleClass: 'book-details-dialog dialog-maximal',
|
||||||
closable: true,
|
|
||||||
contentStyle: {overflow: 'hidden'},
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
baseZIndex: 10,
|
|
||||||
data: {
|
data: {
|
||||||
isMultiBooks: true,
|
bookId: bookId,
|
||||||
bookIds,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openShelfCreator(): DynamicDialogRef {
|
openShelfAssignerDialog(book: Book | null, bookIds: Set<number> | null): DynamicDialogRef | null {
|
||||||
return this.dialogService.open(ShelfCreatorComponent, {
|
const data:any = {};
|
||||||
|
if (book !== null) {
|
||||||
|
data.isMultiBooks = false;
|
||||||
|
data.book = book;
|
||||||
|
} else if (bookIds !== null) {
|
||||||
|
data.isMultiBooks = true;
|
||||||
|
data.bookIds = bookIds;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.openDialog(ShelfAssignerComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
data: data,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openShelfCreatorDialog(): DynamicDialogRef {
|
||||||
|
return this.openDialog(ShelfCreatorComponent, {
|
||||||
showHeader: false,
|
showHeader: false,
|
||||||
modal: true,
|
|
||||||
draggable: false,
|
|
||||||
dismissableMask: true,
|
|
||||||
closable: true,
|
|
||||||
contentStyle: {overflow: 'auto'},
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
baseZIndex: 10,
|
|
||||||
style: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '15%',
|
|
||||||
},
|
|
||||||
})!;
|
})!;
|
||||||
}
|
}
|
||||||
|
|
||||||
openLockUnlockMetadataDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
openLockUnlockMetadataDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
||||||
const count = bookIds.size;
|
const count = bookIds.size;
|
||||||
return this.dialogService.open(LockUnlockMetadataDialogComponent, {
|
return this.openDialog(LockUnlockMetadataDialogComponent, {
|
||||||
header: `Lock or Unlock Metadata for ${count} Selected Book${count > 1 ? 's' : ''}`,
|
header: `Lock or Unlock Metadata for ${count} Selected Book${count > 1 ? 's' : ''}`,
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
data: {
|
data: {
|
||||||
bookIds: Array.from(bookIds),
|
bookIds: Array.from(bookIds),
|
||||||
},
|
},
|
||||||
@@ -59,70 +71,82 @@ export class BookDialogHelperService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openMetadataRefreshDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
openMetadataRefreshDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
||||||
return this.dialogService.open(MultiBookMetadataFetchComponent, {
|
return this.openDialog(MultiBookMetadataFetchComponent, {
|
||||||
header: 'Metadata Refresh Options',
|
header: 'Metadata Refresh Options',
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
data: {
|
data: {
|
||||||
bookIds: Array.from(bookIds),
|
bookIds: Array.from(bookIds),
|
||||||
metadataRefreshType: MetadataRefreshType.BOOKS,
|
metadataRefreshType: MetadataRefreshType.BOOKS,
|
||||||
},
|
},
|
||||||
|
styleClass: 'dialog-maximal',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openBulkMetadataEditDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
openBulkMetadataEditDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
||||||
return this.dialogService.open(BulkMetadataUpdateComponent, {
|
return this.openDialog(BulkMetadataUpdateComponent, {
|
||||||
header: 'Bulk Edit Metadata',
|
header: 'Bulk Edit Metadata',
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
style: {
|
|
||||||
width: '90vw',
|
|
||||||
maxWidth: '1200px',
|
|
||||||
position: 'absolute'
|
|
||||||
},
|
|
||||||
data: {
|
data: {
|
||||||
bookIds: Array.from(bookIds)
|
bookIds: Array.from(bookIds),
|
||||||
},
|
},
|
||||||
|
styleClass: 'dialog-maximal',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openMultibookMetadataEditorDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
openMultibookMetadataEditorDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
||||||
return this.dialogService.open(MultiBookMetadataEditorComponent, {
|
return this.openDialog(MultiBookMetadataEditorComponent, {
|
||||||
header: 'Bulk Edit Metadata',
|
header: 'Multi-Book Metadata Editor',
|
||||||
showHeader: false,
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
closeOnEscape: true,
|
|
||||||
dismissableMask: true,
|
|
||||||
style: {
|
|
||||||
width: '95vw',
|
|
||||||
overflow: 'none',
|
|
||||||
},
|
|
||||||
data: {
|
data: {
|
||||||
bookIds: Array.from(bookIds)
|
bookIds: Array.from(bookIds),
|
||||||
},
|
},
|
||||||
|
styleClass: 'dialog-maximal',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openFileMoverDialog(selectedBooks: Set<number>) {
|
openFileMoverDialog(bookIds: Set<number>): DynamicDialogRef | null {
|
||||||
const count = selectedBooks.size;
|
const count = bookIds.size;
|
||||||
return this.dialogService.open(FileMoverComponent, {
|
return this.openDialog(FileMoverComponent, {
|
||||||
header: `Organize Book Files (${count} book${count !== 1 ? 's' : ''})`,
|
header: `Organize Book Files (${count} book${count !== 1 ? 's' : ''})`,
|
||||||
showHeader: true,
|
|
||||||
maximizable: true,
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
closeOnEscape: false,
|
|
||||||
dismissableMask: false,
|
|
||||||
style: {
|
|
||||||
width: '95vw',
|
|
||||||
maxWidth: '97.5vw',
|
|
||||||
height: '90vh',
|
|
||||||
maxHeight: '95vh'
|
|
||||||
},
|
|
||||||
data: {
|
data: {
|
||||||
bookIds: selectedBooks
|
bookIds: Array.from(bookIds),
|
||||||
},
|
},
|
||||||
|
styleClass: 'dialog-maximal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openCustomSendDialog(bookId: number): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(BookSenderComponent, {
|
||||||
|
header: 'Send Book to Email',
|
||||||
|
data: {
|
||||||
|
bookId: bookId,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openCoverSearchDialog(bookId: number): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(CoverSearchComponent, {
|
||||||
|
header: "Search Cover",
|
||||||
|
data: {
|
||||||
|
bookId: bookId,
|
||||||
|
},
|
||||||
|
styleClass: 'dialog-maximal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openMetadataFetchOptionsDialog(bookId: number): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(MetadataFetchOptionsComponent, {
|
||||||
|
header: 'Metadata Refresh Options',
|
||||||
|
data: {
|
||||||
|
bookIds: [bookId],
|
||||||
|
metadataRefreshType: MetadataRefreshType.BOOKS,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openAdditionalFileUploaderDialog(book: Book): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(AdditionalFileUploaderComponent, {
|
||||||
|
header: 'Upload Additional File',
|
||||||
|
data: {
|
||||||
|
book: book,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -639,7 +639,7 @@ export class BookBrowserComponent implements OnInit, AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openShelfAssigner(): void {
|
openShelfAssigner(): void {
|
||||||
this.dynamicDialogRef = this.dialogHelperService.openShelfAssigner(this.selectedBooks);
|
this.dynamicDialogRef = this.dialogHelperService.openShelfAssignerDialog(null, this.selectedBooks);
|
||||||
}
|
}
|
||||||
|
|
||||||
lockUnlockMetadata(): void {
|
lockUnlockMetadata(): void {
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import {AdditionalFile, Book, ReadStatus} from '../../../model/book.model';
|
|||||||
import {Button} from 'primeng/button';
|
import {Button} from 'primeng/button';
|
||||||
import {MenuModule} from 'primeng/menu';
|
import {MenuModule} from 'primeng/menu';
|
||||||
import {ConfirmationService, MenuItem, MessageService} from 'primeng/api';
|
import {ConfirmationService, MenuItem, MessageService} from 'primeng/api';
|
||||||
import {DialogService} from 'primeng/dynamicdialog';
|
|
||||||
import {ShelfAssignerComponent} from '../../shelf-assigner/shelf-assigner.component';
|
|
||||||
import {BookService} from '../../../service/book.service';
|
import {BookService} from '../../../service/book.service';
|
||||||
import {CheckboxChangeEvent, CheckboxModule} from 'primeng/checkbox';
|
import {CheckboxChangeEvent, CheckboxModule} from 'primeng/checkbox';
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
@@ -16,16 +14,13 @@ import {UserService} from '../../../../settings/user-management/user.service';
|
|||||||
import {filter, Subject} from 'rxjs';
|
import {filter, Subject} from 'rxjs';
|
||||||
import {EmailService} from '../../../../settings/email-v2/email.service';
|
import {EmailService} from '../../../../settings/email-v2/email.service';
|
||||||
import {TieredMenu} from 'primeng/tieredmenu';
|
import {TieredMenu} from 'primeng/tieredmenu';
|
||||||
import {BookSenderComponent} from '../../book-sender/book-sender.component';
|
|
||||||
import {Router} from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
import {ProgressBar} from 'primeng/progressbar';
|
import {ProgressBar} from 'primeng/progressbar';
|
||||||
import {BookMetadataCenterComponent} from '../../../../metadata/component/book-metadata-center/book-metadata-center.component';
|
|
||||||
import {take, takeUntil} from 'rxjs/operators';
|
import {take, takeUntil} from 'rxjs/operators';
|
||||||
import {readStatusLabels} from '../book-filter/book-filter.component';
|
import {readStatusLabels} from '../book-filter/book-filter.component';
|
||||||
import {ResetProgressTypes} from '../../../../../shared/constants/reset-progress-type';
|
import {ResetProgressTypes} from '../../../../../shared/constants/reset-progress-type';
|
||||||
import {ReadStatusHelper} from '../../../helpers/read-status.helper';
|
import {ReadStatusHelper} from '../../../helpers/read-status.helper';
|
||||||
import {BookDialogHelperService} from '../BookDialogHelperService';
|
import {BookDialogHelperService} from '../BookDialogHelperService';
|
||||||
import {MetadataFetchOptionsComponent} from '../../../../metadata/component/metadata-options-dialog/metadata-fetch-options/metadata-fetch-options.component';
|
|
||||||
import {TaskHelperService} from '../../../../settings/task-management/task-helper.service';
|
import {TaskHelperService} from '../../../../settings/task-management/task-helper.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -59,7 +54,6 @@ export class BookCardComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
|
|
||||||
private bookService = inject(BookService);
|
private bookService = inject(BookService);
|
||||||
private taskHelperService = inject(TaskHelperService);
|
private taskHelperService = inject(TaskHelperService);
|
||||||
private dialogService = inject(DialogService);
|
|
||||||
private userService = inject(UserService);
|
private userService = inject(UserService);
|
||||||
private emailService = inject(EmailService);
|
private emailService = inject(EmailService);
|
||||||
private messageService = inject(MessageService);
|
private messageService = inject(MessageService);
|
||||||
@@ -293,18 +287,7 @@ export class BookCardComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
label: 'Custom Send',
|
label: 'Custom Send',
|
||||||
icon: 'pi pi-envelope',
|
icon: 'pi pi-envelope',
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(BookSenderComponent, {
|
this.bookDialogHelperService.openCustomSendDialog(this.book.id);
|
||||||
header: 'Send Book to Email',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
style: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '15%',
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
bookId: this.book.id,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -341,15 +324,7 @@ export class BookCardComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
label: 'Custom Fetch',
|
label: 'Custom Fetch',
|
||||||
icon: 'pi pi-sync',
|
icon: 'pi pi-sync',
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(MetadataFetchOptionsComponent, {
|
this.bookDialogHelperService.openMetadataRefreshDialog(new Set([this.book!.id]))
|
||||||
header: 'Metadata Refresh Options',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
data: {
|
|
||||||
bookIds: [this.book!.id],
|
|
||||||
metadataRefreshType: MetadataRefreshType.BOOKS,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -457,19 +432,7 @@ export class BookCardComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private openShelfDialog(): void {
|
private openShelfDialog(): void {
|
||||||
this.dialogService.open(ShelfAssignerComponent, {
|
this.bookDialogHelperService.openShelfAssignerDialog(this.book, null);
|
||||||
header: `Update Book's Shelves`,
|
|
||||||
showHeader: false,
|
|
||||||
modal: true,
|
|
||||||
dismissableMask: true,
|
|
||||||
closable: true,
|
|
||||||
contentStyle: {overflow: 'hidden'},
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
baseZIndex: 10,
|
|
||||||
data: {
|
|
||||||
book: this.book,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openSeriesInfo(): void {
|
openSeriesInfo(): void {
|
||||||
@@ -488,21 +451,7 @@ export class BookCardComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
queryParams: {tab: 'view'}
|
queryParams: {tab: 'view'}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.dialogService.open(BookMetadataCenterComponent, {
|
this.bookDialogHelperService.openBookDetailsDialog(book.id);
|
||||||
width: '90%',
|
|
||||||
height: '90%',
|
|
||||||
data: {bookId: book.id},
|
|
||||||
modal: true,
|
|
||||||
dismissableMask: true,
|
|
||||||
showHeader: true,
|
|
||||||
closable: true,
|
|
||||||
closeOnEscape: true,
|
|
||||||
draggable: false,
|
|
||||||
maximizable: false,
|
|
||||||
resizable: false,
|
|
||||||
header: 'Book Details',
|
|
||||||
styleClass: 'book-details-dialog'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import {MessageService} from 'primeng/api';
|
|||||||
import {Router, RouterLink} from '@angular/router';
|
import {Router, RouterLink} from '@angular/router';
|
||||||
import {filter, Subject} from 'rxjs';
|
import {filter, Subject} from 'rxjs';
|
||||||
import {UserService} from '../../../../settings/user-management/user.service';
|
import {UserService} from '../../../../settings/user-management/user.service';
|
||||||
import {BookMetadataCenterComponent} from '../../../../metadata/component/book-metadata-center/book-metadata-center.component';
|
|
||||||
import {DialogService} from 'primeng/dynamicdialog';
|
|
||||||
import {take, takeUntil} from 'rxjs/operators';
|
import {take, takeUntil} from 'rxjs/operators';
|
||||||
import {ReadStatusHelper} from '../../../helpers/read-status.helper';
|
import {ReadStatusHelper} from '../../../helpers/read-status.helper';
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { Tab, TabList, TabPanel, TabPanels, Tabs } from "primeng/tabs";
|
|||||||
import { Tag } from "primeng/tag";
|
import { Tag } from "primeng/tag";
|
||||||
import { VirtualScrollerModule } from "@iharbeck/ngx-virtual-scroller";
|
import { VirtualScrollerModule } from "@iharbeck/ngx-virtual-scroller";
|
||||||
import { ProgressSpinner } from "primeng/progressspinner";
|
import { ProgressSpinner } from "primeng/progressspinner";
|
||||||
import { DialogService, DynamicDialogRef } from "primeng/dynamicdialog";
|
import { DynamicDialogRef } from "primeng/dynamicdialog";
|
||||||
import { Router } from "@angular/router";
|
import { Router } from "@angular/router";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export class ShelfAssignerComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createShelfDialog(): void {
|
createShelfDialog(): void {
|
||||||
const dialogRef = this.bookDialogHelper.openShelfCreator();
|
const dialogRef = this.bookDialogHelper.openShelfCreatorDialog();
|
||||||
|
|
||||||
dialogRef.onClose.subscribe((created: boolean) => {
|
dialogRef.onClose.subscribe((created: boolean) => {
|
||||||
if (created) {
|
if (created) {
|
||||||
|
|||||||
@@ -5,19 +5,13 @@ import {LibraryService} from './library.service';
|
|||||||
import {ShelfService} from './shelf.service';
|
import {ShelfService} from './shelf.service';
|
||||||
import {Library} from '../model/library.model';
|
import {Library} from '../model/library.model';
|
||||||
import {Shelf} from '../model/shelf.model';
|
import {Shelf} from '../model/shelf.model';
|
||||||
import {DialogService} from 'primeng/dynamicdialog';
|
|
||||||
import {MetadataRefreshType} from '../../metadata/model/request/metadata-refresh-type.enum';
|
import {MetadataRefreshType} from '../../metadata/model/request/metadata-refresh-type.enum';
|
||||||
import {LibraryCreatorComponent} from '../../library-creator/library-creator.component';
|
|
||||||
import {ShelfEditDialogComponent} from '../components/shelf-edit-dialog/shelf-edit-dialog.component';
|
|
||||||
import {MagicShelf, MagicShelfService} from '../../magic-shelf/service/magic-shelf.service';
|
import {MagicShelf, MagicShelfService} from '../../magic-shelf/service/magic-shelf.service';
|
||||||
import {MetadataFetchOptionsComponent} from '../../metadata/component/metadata-options-dialog/metadata-fetch-options/metadata-fetch-options.component';
|
|
||||||
import {MagicShelfComponent} from '../../magic-shelf/component/magic-shelf-component';
|
|
||||||
import {TaskCreateRequest, TaskType} from '../../settings/task-management/task.service';
|
|
||||||
import {MetadataRefreshRequest} from '../../metadata/model/request/metadata-refresh-request.model';
|
|
||||||
import {TaskHelperService} from '../../settings/task-management/task-helper.service';
|
import {TaskHelperService} from '../../settings/task-management/task-helper.service';
|
||||||
import {UserService} from "../../settings/user-management/user.service";
|
import {UserService} from "../../settings/user-management/user.service";
|
||||||
import {LoadingService} from '../../../core/services/loading.service';
|
import {LoadingService} from '../../../core/services/loading.service';
|
||||||
import {finalize} from 'rxjs';
|
import {finalize} from 'rxjs';
|
||||||
|
import {DialogLauncherService} from '../../../shared/services/dialog-launcher.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -30,7 +24,7 @@ export class LibraryShelfMenuService {
|
|||||||
private shelfService = inject(ShelfService);
|
private shelfService = inject(ShelfService);
|
||||||
private taskHelperService = inject(TaskHelperService);
|
private taskHelperService = inject(TaskHelperService);
|
||||||
private router = inject(Router);
|
private router = inject(Router);
|
||||||
private dialogService = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
private magicShelfService = inject(MagicShelfService);
|
private magicShelfService = inject(MagicShelfService);
|
||||||
private userService = inject(UserService);
|
private userService = inject(UserService);
|
||||||
private loadingService = inject(LoadingService);
|
private loadingService = inject(LoadingService);
|
||||||
@@ -44,17 +38,7 @@ export class LibraryShelfMenuService {
|
|||||||
label: 'Edit Library',
|
label: 'Edit Library',
|
||||||
icon: 'pi pi-pen-to-square',
|
icon: 'pi pi-pen-to-square',
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(LibraryCreatorComponent, {
|
this.dialogLauncherService.openLibraryEditDialog(<number>entity?.id);
|
||||||
header: 'Edit Library',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
showHeader: false,
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
data: {
|
|
||||||
mode: 'edit',
|
|
||||||
libraryId: entity?.id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -93,15 +77,7 @@ export class LibraryShelfMenuService {
|
|||||||
label: 'Custom Fetch Metadata',
|
label: 'Custom Fetch Metadata',
|
||||||
icon: 'pi pi-sync',
|
icon: 'pi pi-sync',
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(MetadataFetchOptionsComponent, {
|
this.dialogLauncherService.openLibraryMetadataFetchDialog(<number>entity?.id);
|
||||||
header: 'Metadata Refresh Options',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
data: {
|
|
||||||
libraryId: entity?.id,
|
|
||||||
metadataRefreshType: MetadataRefreshType.LIBRARY
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -168,16 +144,7 @@ export class LibraryShelfMenuService {
|
|||||||
label: 'Edit Shelf',
|
label: 'Edit Shelf',
|
||||||
icon: 'pi pi-pen-to-square',
|
icon: 'pi pi-pen-to-square',
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(ShelfEditDialogComponent, {
|
this.dialogLauncherService.openShelfEditDialog(<number>entity?.id);
|
||||||
header: 'Edit Shelf',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
showHeader: false,
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
data: {
|
|
||||||
shelfId: entity?.id
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -230,17 +197,7 @@ export class LibraryShelfMenuService {
|
|||||||
icon: 'pi pi-pen-to-square',
|
icon: 'pi pi-pen-to-square',
|
||||||
disabled: disableOptions,
|
disabled: disableOptions,
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(MagicShelfComponent, {
|
this.dialogLauncherService.openMagicShelfEditDialog(<number>entity?.id);
|
||||||
header: 'Edit Magic Shelf',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
showHeader: false,
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
data: {
|
|
||||||
id: entity?.id,
|
|
||||||
editMode: true,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import {Observable, Subscription} from 'rxjs';
|
|||||||
|
|
||||||
import {AppSettings} from '../../../../shared/model/app-settings.model';
|
import {AppSettings} from '../../../../shared/model/app-settings.model';
|
||||||
import {AppSettingsService} from '../../../../shared/service/app-settings.service';
|
import {AppSettingsService} from '../../../../shared/service/app-settings.service';
|
||||||
import {DialogService} from 'primeng/dynamicdialog';
|
|
||||||
import {BookMetadata} from '../../../book/model/book.model';
|
import {BookMetadata} from '../../../book/model/book.model';
|
||||||
import {UrlHelperService} from '../../../../shared/service/url-helper.service';
|
import {UrlHelperService} from '../../../../shared/service/url-helper.service';
|
||||||
import {Checkbox} from 'primeng/checkbox';
|
import {Checkbox} from 'primeng/checkbox';
|
||||||
@@ -26,7 +25,7 @@ import {NgClass, NgStyle} from '@angular/common';
|
|||||||
import {Paginator} from 'primeng/paginator';
|
import {Paginator} from 'primeng/paginator';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import {ActivatedRoute} from '@angular/router';
|
||||||
import {BookdropFileMetadataPickerComponent} from '../bookdrop-file-metadata-picker/bookdrop-file-metadata-picker.component';
|
import {BookdropFileMetadataPickerComponent} from '../bookdrop-file-metadata-picker/bookdrop-file-metadata-picker.component';
|
||||||
import {BookdropFinalizeResultDialogComponent} from '../bookdrop-finalize-result-dialog/bookdrop-finalize-result-dialog-component';
|
import {DialogLauncherService} from '../../../../shared/services/dialog-launcher.service';
|
||||||
|
|
||||||
export interface BookdropFileUI {
|
export interface BookdropFileUI {
|
||||||
file: BookdropFile;
|
file: BookdropFile;
|
||||||
@@ -64,7 +63,7 @@ export class BookdropFileReviewComponent implements OnInit {
|
|||||||
private readonly libraryService = inject(LibraryService);
|
private readonly libraryService = inject(LibraryService);
|
||||||
private readonly confirmationService = inject(ConfirmationService);
|
private readonly confirmationService = inject(ConfirmationService);
|
||||||
private readonly destroyRef = inject(DestroyRef);
|
private readonly destroyRef = inject(DestroyRef);
|
||||||
private readonly dialogService = inject(DialogService);
|
private readonly dialogLauncherService = inject(DialogLauncherService);
|
||||||
private readonly appSettingsService = inject(AppSettingsService);
|
private readonly appSettingsService = inject(AppSettingsService);
|
||||||
private readonly messageService = inject(MessageService);
|
private readonly messageService = inject(MessageService);
|
||||||
private readonly urlHelper = inject(UrlHelperService);
|
private readonly urlHelper = inject(UrlHelperService);
|
||||||
@@ -494,13 +493,7 @@ export class BookdropFileReviewComponent implements OnInit {
|
|||||||
detail: 'Import process finished. See details below.',
|
detail: 'Import process finished. See details below.',
|
||||||
});
|
});
|
||||||
|
|
||||||
this.dialogService.open(BookdropFinalizeResultDialogComponent, {
|
this.dialogLauncherService.openBookdropFinalizeResultDialog(result);
|
||||||
header: 'Import Summary',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
closeOnEscape: true,
|
|
||||||
data: {result: result},
|
|
||||||
});
|
|
||||||
|
|
||||||
const finalizedIds = new Set(files.map(f => f.fileId));
|
const finalizedIds = new Set(files.map(f => f.fileId));
|
||||||
Object.keys(this.fileUiCache).forEach(idStr => {
|
Object.keys(this.fileUiCache).forEach(idStr => {
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
.dashboard-settings {
|
.dashboard-settings {
|
||||||
width: 1000px;
|
max-width: 600px;
|
||||||
max-width: 1200px;
|
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
padding: 2rem 1rem 0 1rem;
|
padding: 2rem 1rem 0 1rem;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
|
||||||
padding: 3rem 1rem 0 1rem;
|
padding: 3rem 1rem 0 1rem;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import {ProgressSpinner} from 'primeng/progressspinner';
|
|||||||
import {TooltipModule} from 'primeng/tooltip';
|
import {TooltipModule} from 'primeng/tooltip';
|
||||||
import {DashboardConfigService} from '../../services/dashboard-config.service';
|
import {DashboardConfigService} from '../../services/dashboard-config.service';
|
||||||
import {ScrollerConfig, ScrollerType} from '../../models/dashboard-config.model';
|
import {ScrollerConfig, ScrollerType} from '../../models/dashboard-config.model';
|
||||||
import {DashboardSettingsComponent} from '../dashboard-settings/dashboard-settings.component';
|
|
||||||
import {MagicShelfService} from '../../../magic-shelf/service/magic-shelf.service';
|
import {MagicShelfService} from '../../../magic-shelf/service/magic-shelf.service';
|
||||||
import {BookRuleEvaluatorService} from '../../../magic-shelf/service/book-rule-evaluator.service';
|
import {BookRuleEvaluatorService} from '../../../magic-shelf/service/book-rule-evaluator.service';
|
||||||
import {GroupRule} from '../../../magic-shelf/component/magic-shelf-component';
|
import {GroupRule} from '../../../magic-shelf/component/magic-shelf-component';
|
||||||
@@ -39,7 +38,6 @@ const DEFAULT_MAX_ITEMS = 20;
|
|||||||
standalone: true
|
standalone: true
|
||||||
})
|
})
|
||||||
export class MainDashboardComponent implements OnInit {
|
export class MainDashboardComponent implements OnInit {
|
||||||
ref: DynamicDialogRef | undefined | null;
|
|
||||||
|
|
||||||
private bookService = inject(BookService);
|
private bookService = inject(BookService);
|
||||||
private dialogLauncher = inject(DialogLauncherService);
|
private dialogLauncher = inject(DialogLauncherService);
|
||||||
@@ -203,14 +201,10 @@ export class MainDashboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openDashboardSettings(): void {
|
openDashboardSettings(): void {
|
||||||
this.ref = this.dialogLauncher.open({
|
this.dialogLauncher.openDashboardSettingsDialog();
|
||||||
component: DashboardSettingsComponent,
|
|
||||||
header: 'Configure Dashboard',
|
|
||||||
showHeader: false
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createNewLibrary() {
|
createNewLibrary() {
|
||||||
this.dialogLauncher.openLibraryCreatorDialog();
|
this.dialogLauncher.openLibraryCreateDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {Component, inject, OnInit} from '@angular/core';
|
import {Component, inject, OnInit} from '@angular/core';
|
||||||
import {DialogService, DynamicDialogConfig, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import {DynamicDialogConfig, DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
import {DirectoryPickerComponent} from '../../shared/components/directory-picker/directory-picker.component';
|
|
||||||
import {MessageService} from 'primeng/api';
|
import {MessageService} from 'primeng/api';
|
||||||
import {Router} from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
import {LibraryService} from '../book/service/library.service';
|
import {LibraryService} from '../book/service/library.service';
|
||||||
@@ -15,6 +14,7 @@ import {IconPickerService, IconSelection} from '../../shared/service/icon-picker
|
|||||||
import {Select} from 'primeng/select';
|
import {Select} from 'primeng/select';
|
||||||
import {Button} from 'primeng/button';
|
import {Button} from 'primeng/button';
|
||||||
import {IconDisplayComponent} from '../../shared/components/icon-display/icon-display.component';
|
import {IconDisplayComponent} from '../../shared/components/icon-display/icon-display.component';
|
||||||
|
import {DialogLauncherService} from '../../shared/services/dialog-launcher.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-library-creator',
|
selector: 'app-library-creator',
|
||||||
@@ -31,7 +31,6 @@ export class LibraryCreatorComponent implements OnInit {
|
|||||||
mode!: string;
|
mode!: string;
|
||||||
library!: Library | undefined;
|
library!: Library | undefined;
|
||||||
editModeLibraryName: string = '';
|
editModeLibraryName: string = '';
|
||||||
directoryPickerDialogRef!: DynamicDialogRef<DirectoryPickerComponent> | null;
|
|
||||||
watch: boolean = false;
|
watch: boolean = false;
|
||||||
scanMode: LibraryScanMode = 'FILE_AS_BOOK';
|
scanMode: LibraryScanMode = 'FILE_AS_BOOK';
|
||||||
defaultBookFormat: BookFileType | undefined = undefined;
|
defaultBookFormat: BookFileType | undefined = undefined;
|
||||||
@@ -48,7 +47,7 @@ export class LibraryCreatorComponent implements OnInit {
|
|||||||
{label: 'CBX/CBZ/CBR', value: 'CBX'}
|
{label: 'CBX/CBZ/CBR', value: 'CBX'}
|
||||||
];
|
];
|
||||||
|
|
||||||
private dialogService = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
private dynamicDialogRef = inject(DynamicDialogRef);
|
private dynamicDialogRef = inject(DynamicDialogRef);
|
||||||
private dynamicDialogConfig = inject(DynamicDialogConfig);
|
private dynamicDialogConfig = inject(DynamicDialogConfig);
|
||||||
private libraryService = inject(LibraryService);
|
private libraryService = inject(LibraryService);
|
||||||
@@ -85,16 +84,8 @@ export class LibraryCreatorComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openDirectoryPicker(): void {
|
openDirectoryPicker(): void {
|
||||||
this.directoryPickerDialogRef = this.dialogService.open(DirectoryPickerComponent, {
|
const ref = this.dialogLauncherService.openDirectoryPickerDialog();
|
||||||
header: 'Select Media Directory',
|
ref?.onClose.subscribe((selectedFolders: string[] | null) => {
|
||||||
showHeader: false,
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
contentStyle: {overflow: 'hidden'},
|
|
||||||
baseZIndex: 10
|
|
||||||
});
|
|
||||||
this.directoryPickerDialogRef?.onClose.subscribe((selectedFolders: string[] | null) => {
|
|
||||||
if (selectedFolders && selectedFolders.length > 0) {
|
if (selectedFolders && selectedFolders.length > 0) {
|
||||||
selectedFolders.forEach(folder => {
|
selectedFolders.forEach(folder => {
|
||||||
if (!this.folders.includes(folder)) {
|
if (!this.folders.includes(folder)) {
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
width: 250px;
|
width: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::ng-deep .cover-item p-image {
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
::ng-deep p-image img {
|
::ng-deep p-image img {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import {BookService} from "../../../../book/service/book.service";
|
|||||||
import {ProgressSpinner} from "primeng/progressspinner";
|
import {ProgressSpinner} from "primeng/progressspinner";
|
||||||
import {Tooltip} from "primeng/tooltip";
|
import {Tooltip} from "primeng/tooltip";
|
||||||
import {filter, take} from "rxjs/operators";
|
import {filter, take} from "rxjs/operators";
|
||||||
import {DialogService} from "primeng/dynamicdialog";
|
|
||||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||||
import {MetadataRefreshType} from "../../../model/request/metadata-refresh-type.enum";
|
import {MetadataRefreshType} from "../../../model/request/metadata-refresh-type.enum";
|
||||||
import {AutoComplete} from "primeng/autocomplete";
|
import {AutoComplete} from "primeng/autocomplete";
|
||||||
@@ -22,8 +21,8 @@ import {DatePicker} from "primeng/datepicker";
|
|||||||
import {Textarea} from "primeng/textarea";
|
import {Textarea} from "primeng/textarea";
|
||||||
import {Image} from "primeng/image";
|
import {Image} from "primeng/image";
|
||||||
import {LazyLoadImageModule} from "ng-lazyload-image";
|
import {LazyLoadImageModule} from "ng-lazyload-image";
|
||||||
import {CoverSearchComponent} from '../../cover-search/cover-search.component';
|
|
||||||
import {TaskHelperService} from '../../../../settings/task-management/task-helper.service';
|
import {TaskHelperService} from '../../../../settings/task-management/task-helper.service';
|
||||||
|
import {BookDialogHelperService} from "../../../../book/components/book-browser/BookDialogHelperService";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-metadata-editor",
|
selector: "app-metadata-editor",
|
||||||
@@ -61,7 +60,7 @@ export class MetadataEditorComponent implements OnInit {
|
|||||||
private bookService = inject(BookService);
|
private bookService = inject(BookService);
|
||||||
private taskHelperService = inject(TaskHelperService);
|
private taskHelperService = inject(TaskHelperService);
|
||||||
protected urlHelper = inject(UrlHelperService);
|
protected urlHelper = inject(UrlHelperService);
|
||||||
private dialogService = inject(DialogService);
|
private bookDialogHelperService = inject(BookDialogHelperService);
|
||||||
private destroyRef = inject(DestroyRef);
|
private destroyRef = inject(DestroyRef);
|
||||||
|
|
||||||
metadataForm: FormGroup;
|
metadataForm: FormGroup;
|
||||||
@@ -684,21 +683,7 @@ export class MetadataEditorComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openCoverSearch() {
|
openCoverSearch() {
|
||||||
const ref = this.dialogService.open(CoverSearchComponent, {
|
const ref = this.bookDialogHelperService.openCoverSearchDialog(this.currentBookId);
|
||||||
header: "Search Cover",
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
data: {
|
|
||||||
bookId: [this.currentBookId],
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
width: "90vw",
|
|
||||||
height: "90vh",
|
|
||||||
maxWidth: "1200px",
|
|
||||||
position: "absolute",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
ref?.onClose.subscribe((result) => {
|
ref?.onClose.subscribe((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.metadataForm.get("thumbnailUrl")?.setValue(result);
|
this.metadataForm.get("thumbnailUrl")?.setValue(result);
|
||||||
|
|||||||
@@ -10,10 +10,8 @@ import {UrlHelperService} from '../../../../../shared/service/url-helper.service
|
|||||||
import {UserService} from '../../../../settings/user-management/user.service';
|
import {UserService} from '../../../../settings/user-management/user.service';
|
||||||
import {SplitButton} from 'primeng/splitbutton';
|
import {SplitButton} from 'primeng/splitbutton';
|
||||||
import {ConfirmationService, MenuItem, MessageService} from 'primeng/api';
|
import {ConfirmationService, MenuItem, MessageService} from 'primeng/api';
|
||||||
import {BookSenderComponent} from '../../../../book/components/book-sender/book-sender.component';
|
import {DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
|
||||||
import {EmailService} from '../../../../settings/email-v2/email.service';
|
import {EmailService} from '../../../../settings/email-v2/email.service';
|
||||||
import {ShelfAssignerComponent} from '../../../../book/components/shelf-assigner/shelf-assigner.component';
|
|
||||||
import {Tooltip} from 'primeng/tooltip';
|
import {Tooltip} from 'primeng/tooltip';
|
||||||
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
|
||||||
import {Editor} from 'primeng/editor';
|
import {Editor} from 'primeng/editor';
|
||||||
@@ -29,13 +27,10 @@ import {DatePicker} from 'primeng/datepicker';
|
|||||||
import {Tab, TabList, TabPanel, TabPanels, Tabs} from 'primeng/tabs';
|
import {Tab, TabList, TabPanel, TabPanels, Tabs} from 'primeng/tabs';
|
||||||
import {BookReviewsComponent} from '../../../../book/components/book-reviews/book-reviews.component';
|
import {BookReviewsComponent} from '../../../../book/components/book-reviews/book-reviews.component';
|
||||||
import {ProgressSpinner} from 'primeng/progressspinner';
|
import {ProgressSpinner} from 'primeng/progressspinner';
|
||||||
|
|
||||||
import {TieredMenu} from 'primeng/tieredmenu';
|
import {TieredMenu} from 'primeng/tieredmenu';
|
||||||
import {AdditionalFileUploaderComponent} from '../../../../book/components/additional-file-uploader/additional-file-uploader.component';
|
|
||||||
import {Image} from 'primeng/image';
|
import {Image} from 'primeng/image';
|
||||||
import {BookDialogHelperService} from '../../../../book/components/book-browser/BookDialogHelperService';
|
import {BookDialogHelperService} from '../../../../book/components/book-browser/BookDialogHelperService';
|
||||||
import {TagColor, TagComponent} from '../../../../../shared/components/tag/tag.component';
|
import {TagColor, TagComponent} from '../../../../../shared/components/tag/tag.component';
|
||||||
import {MetadataFetchOptionsComponent} from '../../metadata-options-dialog/metadata-fetch-options/metadata-fetch-options.component';
|
|
||||||
import {BookNotesComponent} from '../../../../book/components/book-notes/book-notes-component';
|
import {BookNotesComponent} from '../../../../book/components/book-notes/book-notes-component';
|
||||||
import {TaskHelperService} from '../../../../settings/task-management/task-helper.service';
|
import {TaskHelperService} from '../../../../settings/task-management/task-helper.service';
|
||||||
import {
|
import {
|
||||||
@@ -57,7 +52,7 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
|
|||||||
@ViewChild(Editor) quillEditor!: Editor;
|
@ViewChild(Editor) quillEditor!: Editor;
|
||||||
private originalRecommendedBooks: BookRecommendation[] = [];
|
private originalRecommendedBooks: BookRecommendation[] = [];
|
||||||
|
|
||||||
private dialogService = inject(DialogService);
|
private bookDialogHelperService = inject(BookDialogHelperService)
|
||||||
private emailService = inject(EmailService);
|
private emailService = inject(EmailService);
|
||||||
private messageService = inject(MessageService);
|
private messageService = inject(MessageService);
|
||||||
private bookService = inject(BookService);
|
private bookService = inject(BookService);
|
||||||
@@ -65,7 +60,6 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
|
|||||||
protected urlHelper = inject(UrlHelperService);
|
protected urlHelper = inject(UrlHelperService);
|
||||||
protected userService = inject(UserService);
|
protected userService = inject(UserService);
|
||||||
private confirmationService = inject(ConfirmationService);
|
private confirmationService = inject(ConfirmationService);
|
||||||
private bookDialogHelperService = inject(BookDialogHelperService);
|
|
||||||
|
|
||||||
private router = inject(Router);
|
private router = inject(Router);
|
||||||
private destroyRef = inject(DestroyRef);
|
private destroyRef = inject(DestroyRef);
|
||||||
@@ -105,13 +99,7 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
|
|||||||
{
|
{
|
||||||
label: 'Custom Send',
|
label: 'Custom Send',
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(BookSenderComponent, {
|
this.bookDialogHelperService.openCustomSendDialog(metadata.bookId);
|
||||||
header: 'Send Book to Email',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
style: {position: 'absolute', top: '20%'},
|
|
||||||
data: {bookId: metadata.bookId}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
@@ -124,15 +112,7 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
|
|||||||
label: 'Custom Fetch',
|
label: 'Custom Fetch',
|
||||||
icon: 'pi pi-sync',
|
icon: 'pi pi-sync',
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(MetadataFetchOptionsComponent, {
|
this.bookDialogHelperService.openMetadataFetchOptionsDialog(book.id);
|
||||||
header: 'Metadata Refresh Options',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
data: {
|
|
||||||
bookIds: [book.id],
|
|
||||||
metadataRefreshType: MetadataRefreshType.BOOKS,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
@@ -197,16 +177,7 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
|
|||||||
label: 'Upload File',
|
label: 'Upload File',
|
||||||
icon: 'pi pi-upload',
|
icon: 'pi pi-upload',
|
||||||
command: () => {
|
command: () => {
|
||||||
this.dialogService.open(AdditionalFileUploaderComponent, {
|
this.bookDialogHelperService.openAdditionalFileUploaderDialog(book);
|
||||||
header: 'Upload Additional File',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
style: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '10%',
|
|
||||||
},
|
|
||||||
data: {book}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -425,16 +396,7 @@ export class MetadataViewerComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assignShelf(bookId: number) {
|
assignShelf(bookId: number) {
|
||||||
this.dialogService.open(ShelfAssignerComponent, {
|
this.bookDialogHelperService.openShelfAssignerDialog(<Book>this.bookService.getBookByIdFromState(bookId), null);
|
||||||
header: `Update Book's Shelves`,
|
|
||||||
showHeader: false,
|
|
||||||
dismissableMask: true,
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
contentStyle: {overflow: 'hidden'},
|
|
||||||
baseZIndex: 10,
|
|
||||||
data: {book: this.bookService.getBookByIdFromState(bookId)}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateReadStatus(status: ReadStatus): void {
|
updateReadStatus(status: ReadStatus): void {
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
@if (!loading) {
|
@if (!loading) {
|
||||||
<div class="px-4 pt-4 pb-2 h-full flex flex-col">
|
<div class="px-4 pt-4 pb-2 h-full flex flex-col">
|
||||||
|
|
||||||
<div class="flex items-center">
|
|
||||||
<h2 class="text-xl font-semibold">Review Metadata Proposal </h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex-grow overflow-auto">
|
<div class="flex-grow overflow-auto">
|
||||||
@if (currentProposal?.metadataJson; as proposed) {
|
@if (currentProposal?.metadataJson; as proposed) {
|
||||||
<app-metadata-picker
|
<app-metadata-picker
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import {Component, inject, OnInit} from '@angular/core';
|
import {Component, inject, OnInit} from '@angular/core';
|
||||||
import {Button} from 'primeng/button';
|
import {Button} from 'primeng/button';
|
||||||
import {Checkbox} from 'primeng/checkbox';
|
import {Checkbox} from 'primeng/checkbox';
|
||||||
|
|
||||||
import {MessageService, PrimeTemplate} from 'primeng/api';
|
import {MessageService, PrimeTemplate} from 'primeng/api';
|
||||||
import {RadioButton} from 'primeng/radiobutton';
|
import {RadioButton} from 'primeng/radiobutton';
|
||||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||||
import {TableModule} from 'primeng/table';
|
import {TableModule} from 'primeng/table';
|
||||||
import {Tooltip} from 'primeng/tooltip';
|
import {Tooltip} from 'primeng/tooltip';
|
||||||
import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import {DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
import {EmailV2ProviderService} from './email-v2-provider.service';
|
import {EmailV2ProviderService} from './email-v2-provider.service';
|
||||||
import {CreateEmailProviderDialogComponent} from '../create-email-provider-dialog/create-email-provider-dialog.component';
|
|
||||||
import {EmailProvider} from '../email-provider.model';
|
import {EmailProvider} from '../email-provider.model';
|
||||||
import {UserService} from '../../user-management/user.service';
|
import {UserService} from '../../user-management/user.service';
|
||||||
|
import {DialogLauncherService} from '../../../../shared/services/dialog-launcher.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-email-v2-provider',
|
selector: 'app-email-v2-provider',
|
||||||
@@ -32,7 +31,7 @@ export class EmailV2ProviderComponent implements OnInit {
|
|||||||
emailProviders: EmailProvider[] = [];
|
emailProviders: EmailProvider[] = [];
|
||||||
editingProviderIds: number[] = [];
|
editingProviderIds: number[] = [];
|
||||||
ref: DynamicDialogRef | undefined | null;
|
ref: DynamicDialogRef | undefined | null;
|
||||||
private dialogService = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
private emailProvidersService = inject(EmailV2ProviderService);
|
private emailProvidersService = inject(EmailV2ProviderService);
|
||||||
private messageService = inject(MessageService);
|
private messageService = inject(MessageService);
|
||||||
private userService = inject(UserService);
|
private userService = inject(UserService);
|
||||||
@@ -124,13 +123,7 @@ export class EmailV2ProviderComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openCreateProviderDialog() {
|
openCreateProviderDialog() {
|
||||||
this.ref = this.dialogService.open(CreateEmailProviderDialogComponent, {
|
this.ref = this.dialogLauncherService.openEmailProviderDialog();
|
||||||
header: 'Create Email Provider',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
showHeader: false,
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
});
|
|
||||||
this.ref?.onClose.subscribe((result) => {
|
this.ref?.onClose.subscribe((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.loadEmailProviders();
|
this.loadEmailProviders();
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import {Component, inject, OnInit} from '@angular/core';
|
import {Component, inject, OnInit} from '@angular/core';
|
||||||
import {Button} from 'primeng/button';
|
import {Button} from 'primeng/button';
|
||||||
|
|
||||||
import {MessageService, PrimeTemplate} from 'primeng/api';
|
import {MessageService, PrimeTemplate} from 'primeng/api';
|
||||||
import {RadioButton} from 'primeng/radiobutton';
|
import {RadioButton} from 'primeng/radiobutton';
|
||||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||||
import {TableModule} from 'primeng/table';
|
import {TableModule} from 'primeng/table';
|
||||||
import {Tooltip} from 'primeng/tooltip';
|
import {Tooltip} from 'primeng/tooltip';
|
||||||
import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import {DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
import {EmailV2RecipientService} from './email-v2-recipient.service';
|
import {EmailV2RecipientService} from './email-v2-recipient.service';
|
||||||
import {EmailRecipient} from '../email-recipient.model';
|
import {EmailRecipient} from '../email-recipient.model';
|
||||||
import {CreateEmailRecipientDialogComponent} from '../create-email-recipient-dialog/create-email-recipient-dialog.component';
|
import {DialogLauncherService} from '../../../../shared/services/dialog-launcher.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-email-v2-recipient',
|
selector: 'app-email-v2-recipient',
|
||||||
@@ -29,7 +28,7 @@ export class EmailV2RecipientComponent implements OnInit {
|
|||||||
recipientEmails: EmailRecipient[] = [];
|
recipientEmails: EmailRecipient[] = [];
|
||||||
editingRecipientIds: number[] = [];
|
editingRecipientIds: number[] = [];
|
||||||
ref: DynamicDialogRef | undefined | null;
|
ref: DynamicDialogRef | undefined | null;
|
||||||
private dialogService = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
private emailRecipientService = inject(EmailV2RecipientService);
|
private emailRecipientService = inject(EmailV2RecipientService);
|
||||||
private messageService = inject(MessageService);
|
private messageService = inject(MessageService);
|
||||||
defaultRecipientId: any;
|
defaultRecipientId: any;
|
||||||
@@ -111,13 +110,7 @@ export class EmailV2RecipientComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openAddRecipientDialog() {
|
openAddRecipientDialog() {
|
||||||
this.ref = this.dialogService.open(CreateEmailRecipientDialogComponent, {
|
this.ref = this.dialogLauncherService.openEmailRecipientDialog();
|
||||||
header: 'Add New Recipient',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
showHeader: false,
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
});
|
|
||||||
this.ref?.onClose.subscribe((result) => {
|
this.ref?.onClose.subscribe((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.loadRecipientEmails();
|
this.loadRecipientEmails();
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import {Component, inject, OnDestroy, OnInit} from '@angular/core';
|
import {Component, inject, OnDestroy, OnInit} from '@angular/core';
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import {Button} from 'primeng/button';
|
import {Button} from 'primeng/button';
|
||||||
import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import {DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
import {CreateUserDialogComponent} from './create-user-dialog/create-user-dialog.component';
|
|
||||||
import {TableModule} from 'primeng/table';
|
import {TableModule} from 'primeng/table';
|
||||||
import {LowerCasePipe, TitleCasePipe} from '@angular/common';
|
import {LowerCasePipe, TitleCasePipe} from '@angular/common';
|
||||||
import {User, UserService} from './user.service';
|
import {User, UserService} from './user.service';
|
||||||
@@ -16,6 +15,7 @@ import {Password} from 'primeng/password';
|
|||||||
import {filter, take, takeUntil} from 'rxjs/operators';
|
import {filter, take, takeUntil} from 'rxjs/operators';
|
||||||
import {Subject} from 'rxjs';
|
import {Subject} from 'rxjs';
|
||||||
import {Tooltip} from 'primeng/tooltip';
|
import {Tooltip} from 'primeng/tooltip';
|
||||||
|
import {DialogLauncherService} from '../../../shared/services/dialog-launcher.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-user-management',
|
selector: 'app-user-management',
|
||||||
@@ -36,7 +36,7 @@ import {Tooltip} from 'primeng/tooltip';
|
|||||||
})
|
})
|
||||||
export class UserManagementComponent implements OnInit, OnDestroy {
|
export class UserManagementComponent implements OnInit, OnDestroy {
|
||||||
ref: DynamicDialogRef | undefined | null;
|
ref: DynamicDialogRef | undefined | null;
|
||||||
private dialogService = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
private userService = inject(UserService);
|
private userService = inject(UserService);
|
||||||
private libraryService = inject(LibraryService);
|
private libraryService = inject(LibraryService);
|
||||||
private messageService = inject(MessageService);
|
private messageService = inject(MessageService);
|
||||||
@@ -105,13 +105,7 @@ export class UserManagementComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openCreateUserDialog() {
|
openCreateUserDialog() {
|
||||||
this.ref = this.dialogService.open(CreateUserDialogComponent, {
|
this.ref = this.dialogLauncherService.openCreateUserDialog();
|
||||||
header: 'Create New User',
|
|
||||||
showHeader: false,
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
});
|
|
||||||
this.ref?.onClose.subscribe((result) => {
|
this.ref?.onClose.subscribe((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.loadUsers();
|
this.loadUsers();
|
||||||
|
|||||||
@@ -6,15 +6,14 @@ import {ProgressBarModule} from 'primeng/progressbar';
|
|||||||
import {ButtonModule} from 'primeng/button';
|
import {ButtonModule} from 'primeng/button';
|
||||||
import {Divider} from 'primeng/divider';
|
import {Divider} from 'primeng/divider';
|
||||||
import {Tooltip} from 'primeng/tooltip';
|
import {Tooltip} from 'primeng/tooltip';
|
||||||
import {DialogService} from 'primeng/dynamicdialog';
|
|
||||||
import {MessageService} from 'primeng/api';
|
import {MessageService} from 'primeng/api';
|
||||||
|
|
||||||
import {MetadataBatchProgressNotification, MetadataBatchStatus, MetadataBatchStatusLabels} from '../../model/metadata-batch-progress.model';
|
import {MetadataBatchProgressNotification, MetadataBatchStatus, MetadataBatchStatusLabels} from '../../model/metadata-batch-progress.model';
|
||||||
import {MetadataProgressService} from '../../service/metadata-progress-service';
|
import {MetadataProgressService} from '../../service/metadata-progress-service';
|
||||||
import {MetadataReviewDialogComponent} from '../../../features/metadata/component/metadata-review-dialog/metadata-review-dialog-component';
|
|
||||||
import {MetadataTaskService} from '../../../features/book/service/metadata-task';
|
import {MetadataTaskService} from '../../../features/book/service/metadata-task';
|
||||||
import {Tag} from 'primeng/tag';
|
import {Tag} from 'primeng/tag';
|
||||||
import {TaskService} from '../../../features/settings/task-management/task.service';
|
import {TaskService} from '../../../features/settings/task-management/task.service';
|
||||||
|
import {DialogLauncherService} from '../../services/dialog-launcher.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-metadata-progress-widget',
|
selector: 'app-metadata-progress-widget',
|
||||||
@@ -27,7 +26,7 @@ export class MetadataProgressWidgetComponent implements OnInit, OnDestroy {
|
|||||||
activeTasks: { [taskId: string]: MetadataBatchProgressNotification } = {};
|
activeTasks: { [taskId: string]: MetadataBatchProgressNotification } = {};
|
||||||
|
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
private dialogService = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
private metadataProgressService = inject(MetadataProgressService);
|
private metadataProgressService = inject(MetadataProgressService);
|
||||||
private metadataTaskService = inject(MetadataTaskService);
|
private metadataTaskService = inject(MetadataTaskService);
|
||||||
private taskService = inject(TaskService);
|
private taskService = inject(TaskService);
|
||||||
@@ -102,14 +101,7 @@ export class MetadataProgressWidgetComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reviewTask(taskId: string): void {
|
reviewTask(taskId: string): void {
|
||||||
this.dialogService.open(MetadataReviewDialogComponent, {
|
this.dialogLauncherService.openMetadataReviewDialog(taskId);
|
||||||
showHeader: false,
|
|
||||||
width: '90vw',
|
|
||||||
height: '90vh',
|
|
||||||
data: {taskId},
|
|
||||||
closable: false,
|
|
||||||
modal: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelTask(taskId: string): void {
|
cancelTask(taskId: string): void {
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import {ShelfService} from '../../../../features/book/service/shelf.service';
|
|||||||
import {BookService} from '../../../../features/book/service/book.service';
|
import {BookService} from '../../../../features/book/service/book.service';
|
||||||
import {LibraryShelfMenuService} from '../../../../features/book/service/library-shelf-menu.service';
|
import {LibraryShelfMenuService} from '../../../../features/book/service/library-shelf-menu.service';
|
||||||
import {AppVersion, VersionService} from '../../../service/version.service';
|
import {AppVersion, VersionService} from '../../../service/version.service';
|
||||||
import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import {DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
import {VersionChangelogDialogComponent} from './version-changelog-dialog/version-changelog-dialog.component';
|
|
||||||
import {UserService} from '../../../../features/settings/user-management/user.service';
|
import {UserService} from '../../../../features/settings/user-management/user.service';
|
||||||
import {MagicShelfService, MagicShelfState} from '../../../../features/magic-shelf/service/magic-shelf.service';
|
import {MagicShelfService, MagicShelfState} from '../../../../features/magic-shelf/service/magic-shelf.service';
|
||||||
|
import {DialogLauncherService} from '../../../services/dialog-launcher.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-menu',
|
selector: 'app-menu',
|
||||||
@@ -34,7 +34,7 @@ export class AppMenuComponent implements OnInit {
|
|||||||
private bookService = inject(BookService);
|
private bookService = inject(BookService);
|
||||||
private versionService = inject(VersionService);
|
private versionService = inject(VersionService);
|
||||||
private libraryShelfMenuService = inject(LibraryShelfMenuService);
|
private libraryShelfMenuService = inject(LibraryShelfMenuService);
|
||||||
private dialogService = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
private userService = inject(UserService);
|
private userService = inject(UserService);
|
||||||
private magicShelfService = inject(MagicShelfService);
|
private magicShelfService = inject(MagicShelfService);
|
||||||
|
|
||||||
@@ -198,20 +198,7 @@ export class AppMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openChangelogDialog() {
|
openChangelogDialog() {
|
||||||
const isMobile = window.innerWidth <= 768;
|
this.dialogLauncherService.openVersionChangelogDialog();
|
||||||
this.dynamicDialogRef = this.dialogService.open(VersionChangelogDialogComponent, {
|
|
||||||
header: 'What’s New',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
style: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '10%',
|
|
||||||
bottom: '10%',
|
|
||||||
width: isMobile ? '90vw' : '800px',
|
|
||||||
maxWidth: isMobile ? '90vw' : '800px',
|
|
||||||
minWidth: isMobile ? '90vw' : '800px',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getVersionUrl(version: string | undefined): string {
|
getVersionUrl(version: string | undefined): string {
|
||||||
|
|||||||
@@ -155,13 +155,13 @@ export class AppMenuitemComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
openDialog(item: any) {
|
openDialog(item: any) {
|
||||||
if (item.type === 'library' && this.canManipulateLibrary) {
|
if (item.type === 'library' && this.canManipulateLibrary) {
|
||||||
this.dialogLauncher.openLibraryCreatorDialog();
|
this.dialogLauncher.openLibraryCreateDialog();
|
||||||
}
|
}
|
||||||
if (item.type === 'magicShelf') {
|
if (item.type === 'magicShelf') {
|
||||||
this.dialogLauncher.openMagicShelfDialog();
|
this.dialogLauncher.openMagicShelfCreateDialog();
|
||||||
}
|
}
|
||||||
if (item.type === 'shelf') {
|
if (item.type === 'shelf') {
|
||||||
this.bookDialogHelperService.openShelfCreator();
|
this.bookDialogHelperService.openShelfCreatorDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {Component, ElementRef, OnDestroy, ViewChild} from '@angular/core';
|
|||||||
import {MenuItem} from 'primeng/api';
|
import {MenuItem} from 'primeng/api';
|
||||||
import {LayoutService} from '../layout-main/service/app.layout.service';
|
import {LayoutService} from '../layout-main/service/app.layout.service';
|
||||||
import {Router, RouterLink} from '@angular/router';
|
import {Router, RouterLink} from '@angular/router';
|
||||||
import {DialogService as PrimeDialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
import {DynamicDialogRef} from 'primeng/dynamicdialog';
|
||||||
import {TooltipModule} from 'primeng/tooltip';
|
import {TooltipModule} from 'primeng/tooltip';
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import {InputTextModule} from 'primeng/inputtext';
|
import {InputTextModule} from 'primeng/inputtext';
|
||||||
@@ -72,7 +72,6 @@ export class AppTopBarComponent implements OnDestroy {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public layoutService: LayoutService,
|
public layoutService: LayoutService,
|
||||||
public dialogService: PrimeDialogService,
|
|
||||||
private notificationService: NotificationEventService,
|
private notificationService: NotificationEventService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
@@ -120,7 +119,7 @@ export class AppTopBarComponent implements OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openLibraryCreatorDialog(): void {
|
openLibraryCreatorDialog(): void {
|
||||||
this.dialogLauncher.openLibraryCreatorDialog();
|
this.dialogLauncher.openLibraryCreateDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
openFileUploadDialog(): void {
|
openFileUploadDialog(): void {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {inject, Injectable} from '@angular/core';
|
import {inject, Injectable} from '@angular/core';
|
||||||
import {DialogService, DynamicDialogRef} from 'primeng/dynamicdialog';
|
|
||||||
import {IconPickerComponent} from '../components/icon-picker/icon-picker-component';
|
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
|
import {DialogLauncherService} from '../services/dialog-launcher.service';
|
||||||
|
|
||||||
export interface IconSelection {
|
export interface IconSelection {
|
||||||
type: 'PRIME_NG' | 'CUSTOM_SVG';
|
type: 'PRIME_NG' | 'CUSTOM_SVG';
|
||||||
@@ -10,23 +9,10 @@ export interface IconSelection {
|
|||||||
|
|
||||||
@Injectable({providedIn: 'root'})
|
@Injectable({providedIn: 'root'})
|
||||||
export class IconPickerService {
|
export class IconPickerService {
|
||||||
private dialog = inject(DialogService);
|
private dialogLauncherService = inject(DialogLauncherService);
|
||||||
|
|
||||||
open(): Observable<IconSelection> {
|
open(): Observable<IconSelection> {
|
||||||
const isMobile = window.innerWidth <= 768;
|
const ref = this.dialogLauncherService.openIconPickerDialog();
|
||||||
const ref: DynamicDialogRef | null = this.dialog.open(IconPickerComponent, {
|
|
||||||
header: 'Choose an Icon',
|
|
||||||
modal: true,
|
|
||||||
closable: true,
|
|
||||||
style: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '10%',
|
|
||||||
bottom: '10%',
|
|
||||||
width: isMobile ? '90vw' : '800px',
|
|
||||||
maxWidth: isMobile ? '90vw' : '800px',
|
|
||||||
minWidth: isMobile ? '90vw' : '800px',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return ref!.onClose as Observable<IconSelection>;
|
return ref!.onClose as Observable<IconSelection>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,19 @@ import {LibraryCreatorComponent} from '../../features/library-creator/library-cr
|
|||||||
import {BookUploaderComponent} from '../components/book-uploader/book-uploader.component';
|
import {BookUploaderComponent} from '../components/book-uploader/book-uploader.component';
|
||||||
import {UserProfileDialogComponent} from '../../features/settings/user-profile-dialog/user-profile-dialog.component';
|
import {UserProfileDialogComponent} from '../../features/settings/user-profile-dialog/user-profile-dialog.component';
|
||||||
import {MagicShelfComponent} from '../../features/magic-shelf/component/magic-shelf-component';
|
import {MagicShelfComponent} from '../../features/magic-shelf/component/magic-shelf-component';
|
||||||
|
import {DashboardSettingsComponent} from '../../features/dashboard/components/dashboard-settings/dashboard-settings.component';
|
||||||
|
import {VersionChangelogDialogComponent} from '../layout/component/layout-menu/version-changelog-dialog/version-changelog-dialog.component';
|
||||||
|
import {CreateUserDialogComponent} from '../../features/settings/user-management/create-user-dialog/create-user-dialog.component';
|
||||||
|
import {CreateEmailRecipientDialogComponent} from '../../features/settings/email-v2/create-email-recipient-dialog/create-email-recipient-dialog.component';
|
||||||
|
import {CreateEmailProviderDialogComponent} from '../../features/settings/email-v2/create-email-provider-dialog/create-email-provider-dialog.component';
|
||||||
|
import {DirectoryPickerComponent} from '../components/directory-picker/directory-picker.component';
|
||||||
|
import {BookdropFinalizeResultDialogComponent} from '../../features/bookdrop/component/bookdrop-finalize-result-dialog/bookdrop-finalize-result-dialog-component';
|
||||||
|
import {BookdropFinalizeResult} from '../../features/bookdrop/service/bookdrop.service';
|
||||||
|
import {MetadataReviewDialogComponent} from '../../features/metadata/component/metadata-review-dialog/metadata-review-dialog-component';
|
||||||
|
import {MetadataRefreshType} from '../../features/metadata/model/request/metadata-refresh-type.enum';
|
||||||
|
import {MetadataFetchOptionsComponent} from '../../features/metadata/component/metadata-options-dialog/metadata-fetch-options/metadata-fetch-options.component';
|
||||||
|
import {ShelfEditDialogComponent} from '../../features/book/components/shelf-edit-dialog/shelf-edit-dialog.component';
|
||||||
|
import {IconPickerComponent} from '../components/icon-picker/icon-picker-component';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -13,73 +26,164 @@ export class DialogLauncherService {
|
|||||||
|
|
||||||
dialogService = inject(DialogService);
|
dialogService = inject(DialogService);
|
||||||
|
|
||||||
open(options: { component: any; header: string; top?: string; width?: string; showHeader?: boolean; styleClass?: string }): DynamicDialogRef | null {
|
private defaultDialogOptions = {
|
||||||
const isMobile = window.innerWidth <= 768;
|
baseZIndex: 10,
|
||||||
const {component, header, top, width, showHeader = true, styleClass} = options;
|
closable: true,
|
||||||
|
dismissableMask: true,
|
||||||
|
draggable: false,
|
||||||
|
modal: true,
|
||||||
|
resizable: false,
|
||||||
|
showHeader: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
openDialog(component: any, options: {}): DynamicDialogRef | null {
|
||||||
return this.dialogService.open(component, {
|
return this.dialogService.open(component, {
|
||||||
header,
|
...this.defaultDialogOptions,
|
||||||
showHeader,
|
...options,
|
||||||
modal: true,
|
});
|
||||||
closable: true,
|
}
|
||||||
styleClass: styleClass,
|
|
||||||
style: {
|
openDashboardSettingsDialog(): DynamicDialogRef | null {
|
||||||
position: 'absolute',
|
return this.openDialog(DashboardSettingsComponent, {
|
||||||
...(top ? {top} : {}),
|
header: 'Configure Dashboard',
|
||||||
...(isMobile
|
});
|
||||||
? {
|
}
|
||||||
width: '90vw',
|
|
||||||
maxWidth: '90vw',
|
openGithubSupportDialog(): DynamicDialogRef | null {
|
||||||
minWidth: '90vw',
|
return this.openDialog(GithubSupportDialog, {
|
||||||
}
|
header: 'Support Booklore',
|
||||||
: width
|
});
|
||||||
? {width}
|
}
|
||||||
: {}),
|
|
||||||
|
openLibraryCreateDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(LibraryCreatorComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openDirectoryPickerDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(DirectoryPickerComponent, {
|
||||||
|
header: 'Select Media Directory',
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openLibraryEditDialog(libraryId: number): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(LibraryCreatorComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
data: {
|
||||||
|
mode: 'edit',
|
||||||
|
libraryId: libraryId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openLibraryMetadataFetchDialog(libraryId: number): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(MetadataFetchOptionsComponent, {
|
||||||
|
header: 'Metadata Refresh Options',
|
||||||
|
data: {
|
||||||
|
libraryId: libraryId,
|
||||||
|
metadataRefreshType: MetadataRefreshType.LIBRARY,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openShelfEditDialog(shelfId: number): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(ShelfEditDialogComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
data: {
|
||||||
|
shelfId: shelfId
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
openFileUploadDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(BookUploaderComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openCreateUserDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(CreateUserDialogComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openUserProfileDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(UserProfileDialogComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openMagicShelfCreateDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(MagicShelfComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openMagicShelfEditDialog(shelfId: number): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(MagicShelfComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
data: {
|
||||||
|
id: shelfId,
|
||||||
|
editMode: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
openVersionChangelogDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(VersionChangelogDialogComponent, {
|
||||||
|
header: "What's New",
|
||||||
|
styleClass: 'dialog-maximal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openEmailRecipientDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(CreateEmailRecipientDialogComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openEmailProviderDialog(): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(CreateEmailProviderDialogComponent, {
|
||||||
|
showHeader: false,
|
||||||
|
styleClass: 'dynamic-dialog-minimal',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openBookdropFinalizeResultDialog(result: BookdropFinalizeResult): DynamicDialogRef | null {
|
||||||
|
return this.openDialog(BookdropFinalizeResultDialogComponent, {
|
||||||
|
header: 'Import Summary',
|
||||||
|
data: {
|
||||||
|
result: result,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openGithubSupportDialog(): void {
|
openMetadataReviewDialog(taskId: string): DynamicDialogRef | null {
|
||||||
this.open({
|
return this.openDialog(MetadataReviewDialogComponent, {
|
||||||
component: GithubSupportDialog,
|
header: 'Review Metadata Proposal',
|
||||||
header: 'Support Booklore',
|
data: {
|
||||||
showHeader: true,
|
taskId,
|
||||||
top: '15%'
|
},
|
||||||
|
styleClass: 'dialog-maximal',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openLibraryCreatorDialog(): void {
|
openIconPickerDialog(): DynamicDialogRef | null {
|
||||||
this.open({
|
return this.openDialog(IconPickerComponent, {
|
||||||
component: LibraryCreatorComponent,
|
header: 'Choose an Icon',
|
||||||
header: 'Create New Library',
|
styleClass: 'dialog-maximal',
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
showHeader: false
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openFileUploadDialog(): void {
|
}
|
||||||
this.open({
|
|
||||||
component: BookUploaderComponent,
|
|
||||||
header: 'Book Uploader',
|
|
||||||
showHeader: false,
|
|
||||||
styleClass: 'dynamic-dialog-minimal'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
openUserProfileDialog(): void {
|
|
||||||
this.open({
|
|
||||||
component: UserProfileDialogComponent,
|
|
||||||
header: 'User Profile Information',
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
showHeader: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
openMagicShelfDialog(): void {
|
|
||||||
this.open({
|
|
||||||
component: MagicShelfComponent,
|
|
||||||
header: 'Magic Shelf Creator',
|
|
||||||
styleClass: 'dynamic-dialog-minimal',
|
|
||||||
showHeader: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,14 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-dialog {
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
width: 95vw !important;
|
||||||
|
max-width: 95vw !important;
|
||||||
|
max-height: 95vh !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dynamic-dialog-minimal.p-dialog {
|
.dynamic-dialog-minimal.p-dialog {
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
@@ -12,6 +20,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog-maximal.p-dialog {
|
||||||
|
width: 95vw;
|
||||||
|
max-width: 1200px;
|
||||||
|
height: 95vh;
|
||||||
|
max-height: 95vh;
|
||||||
|
}
|
||||||
|
|
||||||
.gradient-divider {
|
.gradient-divider {
|
||||||
min-height: 1px;
|
min-height: 1px;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
|
|||||||
Reference in New Issue
Block a user