New: Sync UI updates for providers

This commit is contained in:
Bogdan
2024-10-12 01:43:51 +03:00
parent 94e9c05d60
commit 8cb59c35fb
7 changed files with 91 additions and 19 deletions

View File

@@ -141,6 +141,16 @@ class SignalRConnector extends Component {
console.error(`signalR: Unable to find handler for ${name}`);
};
handleApplications = ({ action, resource }) => {
const section = 'settings.applications';
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: resource.id });
}
};
handleCommand = (body) => {
if (body.action === 'sync') {
this.props.dispatchFetchCommands();
@@ -150,7 +160,7 @@ class SignalRConnector extends Component {
const resource = body.resource;
const status = resource.status;
// Both sucessful and failed commands need to be
// Both successful and failed commands need to be
// completed, otherwise they spin until they time out.
if (status === 'completed' || status === 'failed') {
@@ -160,6 +170,16 @@ class SignalRConnector extends Component {
}
};
handleDownloadclient = ({ action, resource }) => {
const section = 'settings.downloadClients';
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: resource.id });
}
};
handleHealth = () => {
this.props.dispatchFetchHealth();
};
@@ -168,14 +188,33 @@ class SignalRConnector extends Component {
this.props.dispatchFetchIndexerStatus();
};
handleIndexer = (body) => {
const action = body.action;
handleIndexer = ({ action, resource }) => {
const section = 'indexers';
if (action === 'updated') {
this.props.dispatchUpdateItem({ section, ...body.resource });
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: body.resource.id });
this.props.dispatchRemoveItem({ section, id: resource.id });
}
};
handleIndexerproxy = ({ action, resource }) => {
const section = 'settings.indexerProxies';
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: resource.id });
}
};
handleNotification = ({ action, resource }) => {
const section = 'settings.notifications';
if (action === 'created' || action === 'updated') {
this.props.dispatchUpdateItem({ section, ...resource });
} else if (action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: resource.id });
}
};

View File

@@ -1,4 +1,5 @@
using NzbDrone.Core.Applications;
using NzbDrone.SignalR;
using Prowlarr.Http;
namespace Prowlarr.Api.V1.Applications
@@ -9,8 +10,8 @@ namespace Prowlarr.Api.V1.Applications
public static readonly ApplicationResourceMapper ResourceMapper = new ();
public static readonly ApplicationBulkResourceMapper BulkResourceMapper = new ();
public ApplicationController(ApplicationFactory applicationsFactory)
: base(applicationsFactory, "applications", ResourceMapper, BulkResourceMapper)
public ApplicationController(IBroadcastSignalRMessage signalRBroadcaster, ApplicationFactory applicationsFactory)
: base(signalRBroadcaster, applicationsFactory, "applications", ResourceMapper, BulkResourceMapper)
{
}
}

View File

@@ -1,4 +1,5 @@
using NzbDrone.Core.Download;
using NzbDrone.SignalR;
using Prowlarr.Http;
namespace Prowlarr.Api.V1.DownloadClient
@@ -9,8 +10,8 @@ namespace Prowlarr.Api.V1.DownloadClient
public static readonly DownloadClientResourceMapper ResourceMapper = new ();
public static readonly DownloadClientBulkResourceMapper BulkResourceMapper = new ();
public DownloadClientController(IDownloadClientFactory downloadClientFactory)
: base(downloadClientFactory, "downloadclient", ResourceMapper, BulkResourceMapper)
public DownloadClientController(IBroadcastSignalRMessage signalRBroadcaster, IDownloadClientFactory downloadClientFactory)
: base(signalRBroadcaster, downloadClientFactory, "downloadclient", ResourceMapper, BulkResourceMapper)
{
}
}

View File

@@ -1,6 +1,7 @@
using System;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.IndexerProxies;
using NzbDrone.SignalR;
using Prowlarr.Http;
namespace Prowlarr.Api.V1.IndexerProxies
@@ -11,8 +12,8 @@ namespace Prowlarr.Api.V1.IndexerProxies
public static readonly IndexerProxyResourceMapper ResourceMapper = new ();
public static readonly IndexerProxyBulkResourceMapper BulkResourceMapper = new ();
public IndexerProxyController(IndexerProxyFactory notificationFactory)
: base(notificationFactory, "indexerProxy", ResourceMapper, BulkResourceMapper)
public IndexerProxyController(IBroadcastSignalRMessage signalRBroadcaster, IndexerProxyFactory notificationFactory)
: base(signalRBroadcaster, notificationFactory, "indexerProxy", ResourceMapper, BulkResourceMapper)
{
}

View File

@@ -1,6 +1,7 @@
using FluentValidation;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Validation;
using NzbDrone.SignalR;
using Prowlarr.Http;
namespace Prowlarr.Api.V1.Indexers
@@ -8,12 +9,13 @@ namespace Prowlarr.Api.V1.Indexers
[V1ApiController]
public class IndexerController : ProviderControllerBase<IndexerResource, IndexerBulkResource, IIndexer, IndexerDefinition>
{
public IndexerController(IndexerFactory indexerFactory,
public IndexerController(IBroadcastSignalRMessage signalRBroadcaster,
IndexerFactory indexerFactory,
IndexerResourceMapper resourceMapper,
IndexerBulkResourceMapper bulkResourceMapper,
AppProfileExistsValidator appProfileExistsValidator,
DownloadClientExistsValidator downloadClientExistsValidator)
: base(indexerFactory, "indexer", resourceMapper, bulkResourceMapper)
: base(signalRBroadcaster, indexerFactory, "indexer", resourceMapper, bulkResourceMapper)
{
SharedValidator.RuleFor(c => c.AppProfileId).Cascade(CascadeMode.Stop)
.ValidId()

View File

@@ -1,6 +1,7 @@
using System;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.Notifications;
using NzbDrone.SignalR;
using Prowlarr.Http;
namespace Prowlarr.Api.V1.Notifications
@@ -11,8 +12,8 @@ namespace Prowlarr.Api.V1.Notifications
public static readonly NotificationResourceMapper ResourceMapper = new ();
public static readonly NotificationBulkResourceMapper BulkResourceMapper = new ();
public NotificationController(NotificationFactory notificationFactory)
: base(notificationFactory, "notification", ResourceMapper, BulkResourceMapper)
public NotificationController(IBroadcastSignalRMessage signalRBroadcaster, NotificationFactory notificationFactory)
: base(signalRBroadcaster, notificationFactory, "notification", ResourceMapper, BulkResourceMapper)
{
}

View File

@@ -4,14 +4,21 @@ using FluentValidation;
using FluentValidation.Results;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.ThingiProvider.Events;
using NzbDrone.Core.Validation;
using NzbDrone.Http.REST.Attributes;
using NzbDrone.SignalR;
using Prowlarr.Http.REST;
namespace Prowlarr.Api.V1
{
public abstract class ProviderControllerBase<TProviderResource, TBulkProviderResource, TProvider, TProviderDefinition> : RestController<TProviderResource>
public abstract class ProviderControllerBase<TProviderResource, TBulkProviderResource, TProvider, TProviderDefinition> : RestControllerWithSignalR<TProviderResource, TProviderDefinition>,
IHandle<ProviderAddedEvent<TProvider>>,
IHandle<ProviderUpdatedEvent<TProvider>>,
IHandle<ProviderDeletedEvent<TProvider>>
where TProviderDefinition : ProviderDefinition, new()
where TBulkProviderResource : ProviderBulkResource<TBulkProviderResource>, new()
where TProvider : IProvider
@@ -21,11 +28,13 @@ namespace Prowlarr.Api.V1
protected readonly ProviderResourceMapper<TProviderResource, TProviderDefinition> _resourceMapper;
private readonly ProviderBulkResourceMapper<TBulkProviderResource, TProviderDefinition> _bulkResourceMapper;
protected ProviderControllerBase(IProviderFactory<TProvider,
protected ProviderControllerBase(IBroadcastSignalRMessage signalRBroadcaster,
IProviderFactory<TProvider,
TProviderDefinition> providerFactory,
string resource,
ProviderResourceMapper<TProviderResource, TProviderDefinition> resourceMapper,
ProviderBulkResourceMapper<TBulkProviderResource, TProviderDefinition> bulkResourceMapper)
: base(signalRBroadcaster)
{
_providerFactory = providerFactory;
_resourceMapper = resourceMapper;
@@ -244,6 +253,24 @@ namespace Prowlarr.Api.V1
return Json(data);
}
[NonAction]
public void Handle(ProviderAddedEvent<TProvider> message)
{
BroadcastResourceChange(ModelAction.Created, message.Definition.Id);
}
[NonAction]
public void Handle(ProviderUpdatedEvent<TProvider> message)
{
BroadcastResourceChange(ModelAction.Updated, message.Definition.Id);
}
[NonAction]
public void Handle(ProviderDeletedEvent<TProvider> message)
{
BroadcastResourceChange(ModelAction.Deleted, message.ProviderId);
}
private void Validate(TProviderDefinition definition, bool includeWarnings)
{
var validationResult = definition.Settings.Validate();