From 97642cf7428b3240df90c0d1563900c28939d53c Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 23 Sep 2022 20:04:18 -0500 Subject: [PATCH] Fixed a bug where when no devices, the submenu item would still render. (#1558) --- API/Controllers/DeviceController.cs | 11 +++++++++- .../app/_services/action-factory.service.ts | 10 ++++++--- .../card-detail-drawer.component.ts | 2 +- .../card-actionables.component.html | 22 ++++++++++++------- .../card-actionables.component.ts | 13 +++++++++-- .../series-detail/series-detail.component.ts | 2 +- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/API/Controllers/DeviceController.cs b/API/Controllers/DeviceController.cs index ff96ea2b2..0bcdce0dd 100644 --- a/API/Controllers/DeviceController.cs +++ b/API/Controllers/DeviceController.cs @@ -6,6 +6,7 @@ using API.Data.Repositories; using API.DTOs.Device; using API.Extensions; using API.Services; +using Kavita.Common; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -81,7 +82,15 @@ public class DeviceController : BaseApiController if (await _emailService.IsDefaultEmailService()) return BadRequest("Send to device cannot be used with Kavita's email service. Please configure your own."); - if (await _deviceService.SendTo(dto.ChapterId, dto.DeviceId)) return Ok(); + try + { + var success = await _deviceService.SendTo(dto.ChapterId, dto.DeviceId); + if (success) return Ok(); + } + catch (KavitaException ex) + { + return BadRequest(ex.Message); + } return BadRequest("There was an error sending the file to the device"); } diff --git a/UI/Web/src/app/_services/action-factory.service.ts b/UI/Web/src/app/_services/action-factory.service.ts index bcc577b31..1fa0072d1 100644 --- a/UI/Web/src/app/_services/action-factory.service.ts +++ b/UI/Web/src/app/_services/action-factory.service.ts @@ -93,13 +93,14 @@ export interface ActionItem { requiresAdmin: boolean; children: Array>; /** - * Indicates that there exists a separate list will be loaded from an API + * Indicates that there exists a separate list will be loaded from an API. + * Rule: If using this, only one child should exist in children with the Action for dynamicList. */ dynamicList?: Observable<{title: string, data: any}[]> | undefined; /** * Extra data that needs to be sent back from the card item. Used mainly for dynamicList. This will be the item from dyanamicList return */ - _extra?: any; + _extra?: {title: string, data: any}; } @Injectable({ @@ -416,13 +417,16 @@ export class ActionFactoryService { title: 'Send To', callback: this.dummyCallback, requiresAdmin: false, + // dynamicList: this.deviceService.devices$.pipe(map((devices: Array) => devices.map(d => { + // return {'title': d.name, 'data': d}; + // }), shareReplay())), children: [ { action: Action.SendTo, title: '', callback: this.dummyCallback, requiresAdmin: false, - dynamicList: this.deviceService.devices$.pipe(map(devices => devices.map(d => { + dynamicList: this.deviceService.devices$.pipe(map((devices: Array) => devices.map(d => { return {'title': d.name, 'data': d}; }), shareReplay())), children: [] diff --git a/UI/Web/src/app/cards/card-detail-drawer/card-detail-drawer.component.ts b/UI/Web/src/app/cards/card-detail-drawer/card-detail-drawer.component.ts index 17769094d..caf3c238b 100644 --- a/UI/Web/src/app/cards/card-detail-drawer/card-detail-drawer.component.ts +++ b/UI/Web/src/app/cards/card-detail-drawer/card-detail-drawer.component.ts @@ -221,7 +221,7 @@ export class CardDetailDrawerComponent implements OnInit, OnDestroy { break; case (Action.SendTo): { - const device = (action._extra.data as Device); + const device = (action._extra!.data as Device); this.deviceSerivce.sendTo(chapter.id, device.id).subscribe(() => { this.toastr.success('File emailed to ' + device.name); }); diff --git a/UI/Web/src/app/cards/card-item/card-actionables/card-actionables.component.html b/UI/Web/src/app/cards/card-item/card-actionables/card-actionables.component.html index 6415cfc73..86d573326 100644 --- a/UI/Web/src/app/cards/card-item/card-actionables/card-actionables.component.html +++ b/UI/Web/src/app/cards/card-item/card-actionables/card-actionables.component.html @@ -7,23 +7,29 @@ - - - + + + + + + -
- -
- + + +
+ +
+ +
-
+ diff --git a/UI/Web/src/app/cards/card-item/card-actionables/card-actionables.component.ts b/UI/Web/src/app/cards/card-item/card-actionables/card-actionables.component.ts index 90eec0bb3..df54b42d3 100644 --- a/UI/Web/src/app/cards/card-item/card-actionables/card-actionables.component.ts +++ b/UI/Web/src/app/cards/card-item/card-actionables/card-actionables.component.ts @@ -47,10 +47,14 @@ export class CardActionablesComponent implements OnInit { } } - willRenderAction(action: ActionItem): boolean { + willRenderAction(action: ActionItem) { return (action.requiresAdmin && this.isAdmin) || (action.action === Action.Download && (this.canDownload || this.isAdmin)) - || (!action.requiresAdmin && action.action !== Action.Download) + || (!action.requiresAdmin && action.action !== Action.Download); + } + + shouldRenderSubMenu(action: ActionItem, dynamicList: null | Array) { + return (action.children[0].dynamicList === undefined || action.children[0].dynamicList === null) || (dynamicList !== null && dynamicList.length > 0); } openSubmenu(actionTitle: string, subMenu: NgbDropdown) { @@ -71,4 +75,9 @@ export class CardActionablesComponent implements OnInit { this.performAction(event, action); } + toDList(d: any) { + console.log('d: ', d); + if (d === undefined || d === null) return []; + return d as {title: string, data: any}[]; + } } diff --git a/UI/Web/src/app/series-detail/series-detail.component.ts b/UI/Web/src/app/series-detail/series-detail.component.ts index 4f3d91d76..f6354512f 100644 --- a/UI/Web/src/app/series-detail/series-detail.component.ts +++ b/UI/Web/src/app/series-detail/series-detail.component.ts @@ -446,7 +446,7 @@ export class SeriesDetailComponent implements OnInit, OnDestroy, AfterContentChe break; case (Action.SendTo): { - const device = (action._extra.data as Device); + const device = (action._extra!.data as Device); this.deviceSerivce.sendTo(chapter.id, device.id).subscribe(() => { this.toastr.success('File emailed to ' + device.name); });