initial commit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../../core/models/models.dart';
|
||||
import '../../core/network/api_client_provider.dart';
|
||||
import '../../core/network/node_master_api_client.dart';
|
||||
|
||||
part 'node_repository.g.dart';
|
||||
|
||||
/// Wraps the `/node/*` endpoints — this host's own identity, backup config,
|
||||
/// scan trigger, and update log.
|
||||
class NodeRepository {
|
||||
const NodeRepository(this._client);
|
||||
|
||||
final NodeMasterApiClient _client;
|
||||
|
||||
Future<NodeInfo> getNode() => _client.getNode();
|
||||
Future<void> updateNode(NodeInfo node) => _client.updateNode(node);
|
||||
|
||||
Future<BackupConfig> getBackup() => _client.getNodeBackup();
|
||||
Future<void> updateBackup(BackupConfig config) => _client.updateNodeBackup(config);
|
||||
Future<void> runBackup() => _client.runNodeBackup();
|
||||
|
||||
Future<List<BackupTarget>> getBackupTargets() => _client.getNodeBackupTargets();
|
||||
Future<BackupTarget> addBackupTarget(BackupTarget target) => _client.addNodeBackupTarget(target);
|
||||
Future<BackupTarget> updateBackupTarget(String targetId, BackupTarget target) =>
|
||||
_client.updateNodeBackupTarget(targetId, target);
|
||||
Future<void> deleteBackupTarget(String targetId) => _client.deleteNodeBackupTarget(targetId);
|
||||
Future<void> runBackupTarget(String targetId) => _client.runNodeBackupTarget(targetId);
|
||||
Future<RunState> getBackupTargetProgress(String targetId) =>
|
||||
_client.getNodeBackupTargetProgress(targetId);
|
||||
Future<List<RunState>> getBackupProgress() => _client.getNodeBackupProgress();
|
||||
|
||||
Future<ScanResult> scan({String? folder}) => _client.scan(folder: folder);
|
||||
|
||||
Future<List<UpdateRecord>> getUpdates() => _client.getUpdates();
|
||||
Future<UpdateRecord> addUpdate(UpdateRecord record) => _client.addUpdate(record);
|
||||
Future<void> deleteUpdate(String id) => _client.deleteUpdate(id);
|
||||
}
|
||||
|
||||
/// Null when no connection is active — mirrors [apiClientProvider] so every
|
||||
/// downstream provider that watches this gets the same "no connection"
|
||||
/// signal without re-deriving it from the connection state itself.
|
||||
@riverpod
|
||||
NodeRepository? nodeRepository(Ref ref) {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
if (client == null) return null;
|
||||
return NodeRepository(client);
|
||||
}
|
||||
|
||||
/// The active connection's node info, or null if no connection is
|
||||
/// configured. Exceptions from an unreachable/misbehaving node surface as
|
||||
/// [AsyncError] — this is also the smoke-test path proving the client →
|
||||
/// repository → provider chain works end to end against a live server.
|
||||
@riverpod
|
||||
Future<NodeInfo?> currentNode(Ref ref) async {
|
||||
final repo = ref.watch(nodeRepositoryProvider);
|
||||
if (repo == null) return null;
|
||||
return repo.getNode();
|
||||
}
|
||||
|
||||
/// The node-level backup config — manual-refresh only, same reasoning as
|
||||
/// `servicesListProvider`: this backs a detail-heavy screen with its own
|
||||
/// edit dialog, where a silent background refresh could yank state out
|
||||
/// from under an in-progress edit.
|
||||
@riverpod
|
||||
Future<BackupConfig?> backupConfig(Ref ref) async {
|
||||
final repo = ref.watch(nodeRepositoryProvider);
|
||||
if (repo == null) return null;
|
||||
return repo.getBackup();
|
||||
}
|
||||
|
||||
/// The OS update log — manual-refresh only, same reasoning as the other
|
||||
/// list providers in this app.
|
||||
@riverpod
|
||||
Future<List<UpdateRecord>> updatesList(Ref ref) async {
|
||||
final repo = ref.watch(nodeRepositoryProvider);
|
||||
if (repo == null) return [];
|
||||
return repo.getUpdates();
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'node_repository.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Null when no connection is active — mirrors [apiClientProvider] so every
|
||||
/// downstream provider that watches this gets the same "no connection"
|
||||
/// signal without re-deriving it from the connection state itself.
|
||||
|
||||
@ProviderFor(nodeRepository)
|
||||
const nodeRepositoryProvider = NodeRepositoryProvider._();
|
||||
|
||||
/// Null when no connection is active — mirrors [apiClientProvider] so every
|
||||
/// downstream provider that watches this gets the same "no connection"
|
||||
/// signal without re-deriving it from the connection state itself.
|
||||
|
||||
final class NodeRepositoryProvider
|
||||
extends
|
||||
$FunctionalProvider<NodeRepository?, NodeRepository?, NodeRepository?>
|
||||
with $Provider<NodeRepository?> {
|
||||
/// Null when no connection is active — mirrors [apiClientProvider] so every
|
||||
/// downstream provider that watches this gets the same "no connection"
|
||||
/// signal without re-deriving it from the connection state itself.
|
||||
const NodeRepositoryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'nodeRepositoryProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$nodeRepositoryHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<NodeRepository?> $createElement($ProviderPointer pointer) =>
|
||||
$ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
NodeRepository? create(Ref ref) {
|
||||
return nodeRepository(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(NodeRepository? value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<NodeRepository?>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$nodeRepositoryHash() => r'c7cf7aac4b407fd4a21a56f5c3d34c81fa9abe5e';
|
||||
|
||||
/// The active connection's node info, or null if no connection is
|
||||
/// configured. Exceptions from an unreachable/misbehaving node surface as
|
||||
/// [AsyncError] — this is also the smoke-test path proving the client →
|
||||
/// repository → provider chain works end to end against a live server.
|
||||
|
||||
@ProviderFor(currentNode)
|
||||
const currentNodeProvider = CurrentNodeProvider._();
|
||||
|
||||
/// The active connection's node info, or null if no connection is
|
||||
/// configured. Exceptions from an unreachable/misbehaving node surface as
|
||||
/// [AsyncError] — this is also the smoke-test path proving the client →
|
||||
/// repository → provider chain works end to end against a live server.
|
||||
|
||||
final class CurrentNodeProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<NodeInfo?>,
|
||||
NodeInfo?,
|
||||
FutureOr<NodeInfo?>
|
||||
>
|
||||
with $FutureModifier<NodeInfo?>, $FutureProvider<NodeInfo?> {
|
||||
/// The active connection's node info, or null if no connection is
|
||||
/// configured. Exceptions from an unreachable/misbehaving node surface as
|
||||
/// [AsyncError] — this is also the smoke-test path proving the client →
|
||||
/// repository → provider chain works end to end against a live server.
|
||||
const CurrentNodeProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'currentNodeProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$currentNodeHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<NodeInfo?> $createElement($ProviderPointer pointer) =>
|
||||
$FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<NodeInfo?> create(Ref ref) {
|
||||
return currentNode(ref);
|
||||
}
|
||||
}
|
||||
|
||||
String _$currentNodeHash() => r'e1742b62ba610695d0e8a560d554902fa29d128c';
|
||||
|
||||
/// The node-level backup config — manual-refresh only, same reasoning as
|
||||
/// `servicesListProvider`: this backs a detail-heavy screen with its own
|
||||
/// edit dialog, where a silent background refresh could yank state out
|
||||
/// from under an in-progress edit.
|
||||
|
||||
@ProviderFor(backupConfig)
|
||||
const backupConfigProvider = BackupConfigProvider._();
|
||||
|
||||
/// The node-level backup config — manual-refresh only, same reasoning as
|
||||
/// `servicesListProvider`: this backs a detail-heavy screen with its own
|
||||
/// edit dialog, where a silent background refresh could yank state out
|
||||
/// from under an in-progress edit.
|
||||
|
||||
final class BackupConfigProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<BackupConfig?>,
|
||||
BackupConfig?,
|
||||
FutureOr<BackupConfig?>
|
||||
>
|
||||
with $FutureModifier<BackupConfig?>, $FutureProvider<BackupConfig?> {
|
||||
/// The node-level backup config — manual-refresh only, same reasoning as
|
||||
/// `servicesListProvider`: this backs a detail-heavy screen with its own
|
||||
/// edit dialog, where a silent background refresh could yank state out
|
||||
/// from under an in-progress edit.
|
||||
const BackupConfigProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'backupConfigProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$backupConfigHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<BackupConfig?> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<BackupConfig?> create(Ref ref) {
|
||||
return backupConfig(ref);
|
||||
}
|
||||
}
|
||||
|
||||
String _$backupConfigHash() => r'd3eeedd7536dd8610b34b922bd5658c507c91efe';
|
||||
|
||||
/// The OS update log — manual-refresh only, same reasoning as the other
|
||||
/// list providers in this app.
|
||||
|
||||
@ProviderFor(updatesList)
|
||||
const updatesListProvider = UpdatesListProvider._();
|
||||
|
||||
/// The OS update log — manual-refresh only, same reasoning as the other
|
||||
/// list providers in this app.
|
||||
|
||||
final class UpdatesListProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<List<UpdateRecord>>,
|
||||
List<UpdateRecord>,
|
||||
FutureOr<List<UpdateRecord>>
|
||||
>
|
||||
with
|
||||
$FutureModifier<List<UpdateRecord>>,
|
||||
$FutureProvider<List<UpdateRecord>> {
|
||||
/// The OS update log — manual-refresh only, same reasoning as the other
|
||||
/// list providers in this app.
|
||||
const UpdatesListProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'updatesListProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$updatesListHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<List<UpdateRecord>> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<List<UpdateRecord>> create(Ref ref) {
|
||||
return updatesList(ref);
|
||||
}
|
||||
}
|
||||
|
||||
String _$updatesListHash() => r'01c6dd3b69dfd8f98e57f29e43e3fa60d014a6e4';
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../../core/models/models.dart';
|
||||
import '../../core/network/api_client_provider.dart';
|
||||
import '../../core/network/node_master_api_client.dart';
|
||||
import '../../core/polling/polling_async_notifier.dart';
|
||||
|
||||
part 'nodes_repository.g.dart';
|
||||
|
||||
/// Wraps the `/nodes/*` endpoints — the registry of sibling NodeMaster
|
||||
/// hosts and the server-side fan-out status view.
|
||||
class NodesRepository {
|
||||
const NodesRepository(this._client);
|
||||
|
||||
final NodeMasterApiClient _client;
|
||||
|
||||
Future<List<RemoteNode>> getAll() => _client.getAllRemoteNodes();
|
||||
Future<RemoteNode> get(String id) => _client.getRemoteNode(id);
|
||||
Future<RemoteNode> add(RemoteNode node) => _client.addRemoteNode(node);
|
||||
Future<RemoteNode> update(String id, RemoteNode node) => _client.updateRemoteNode(id, node);
|
||||
Future<void> delete(String id) => _client.deleteRemoteNode(id);
|
||||
Future<List<AggregatedNodeStatus>> getAggregated() => _client.getAggregated();
|
||||
}
|
||||
|
||||
/// Null when no connection is active, mirroring [apiClientProvider].
|
||||
@riverpod
|
||||
NodesRepository? nodesRepository(Ref ref) {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
if (client == null) return null;
|
||||
return NodesRepository(client);
|
||||
}
|
||||
|
||||
/// The registered-nodes list. Manual-refresh only, same reasoning as
|
||||
/// `servicesListProvider` — this backs Fleet's registry table (M6).
|
||||
@riverpod
|
||||
Future<List<RemoteNode>> remoteNodesList(Ref ref) async {
|
||||
final repo = ref.watch(nodesRepositoryProvider);
|
||||
if (repo == null) return [];
|
||||
return repo.getAll();
|
||||
}
|
||||
|
||||
/// The live `/nodes/aggregated` fan-out result, polled every 25s. Shared
|
||||
/// by the Dashboard's "Fleet" stat tile and the Fleet screen's card grid
|
||||
/// (M6) — one poll, cached by Riverpod, rather than each screen running
|
||||
/// its own duplicate timer against the same endpoint.
|
||||
@riverpod
|
||||
class AggregatedNodes extends _$AggregatedNodes with PollingMixin<List<AggregatedNodeStatus>> {
|
||||
@override
|
||||
Duration get interval => const Duration(seconds: 25);
|
||||
|
||||
@override
|
||||
Future<List<AggregatedNodeStatus>> fetch() async {
|
||||
final repo = ref.watch(nodesRepositoryProvider);
|
||||
if (repo == null) return [];
|
||||
return repo.getAggregated();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<AggregatedNodeStatus>> build() => startPolling();
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'nodes_repository.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Null when no connection is active, mirroring [apiClientProvider].
|
||||
|
||||
@ProviderFor(nodesRepository)
|
||||
const nodesRepositoryProvider = NodesRepositoryProvider._();
|
||||
|
||||
/// Null when no connection is active, mirroring [apiClientProvider].
|
||||
|
||||
final class NodesRepositoryProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
NodesRepository?,
|
||||
NodesRepository?,
|
||||
NodesRepository?
|
||||
>
|
||||
with $Provider<NodesRepository?> {
|
||||
/// Null when no connection is active, mirroring [apiClientProvider].
|
||||
const NodesRepositoryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'nodesRepositoryProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$nodesRepositoryHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<NodesRepository?> $createElement($ProviderPointer pointer) =>
|
||||
$ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
NodesRepository? create(Ref ref) {
|
||||
return nodesRepository(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(NodesRepository? value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<NodesRepository?>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$nodesRepositoryHash() => r'7dd03a46ea79ae87bb251ff273ff77a634a53f5f';
|
||||
|
||||
/// The registered-nodes list. Manual-refresh only, same reasoning as
|
||||
/// `servicesListProvider` — this backs Fleet's registry table (M6).
|
||||
|
||||
@ProviderFor(remoteNodesList)
|
||||
const remoteNodesListProvider = RemoteNodesListProvider._();
|
||||
|
||||
/// The registered-nodes list. Manual-refresh only, same reasoning as
|
||||
/// `servicesListProvider` — this backs Fleet's registry table (M6).
|
||||
|
||||
final class RemoteNodesListProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<List<RemoteNode>>,
|
||||
List<RemoteNode>,
|
||||
FutureOr<List<RemoteNode>>
|
||||
>
|
||||
with $FutureModifier<List<RemoteNode>>, $FutureProvider<List<RemoteNode>> {
|
||||
/// The registered-nodes list. Manual-refresh only, same reasoning as
|
||||
/// `servicesListProvider` — this backs Fleet's registry table (M6).
|
||||
const RemoteNodesListProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'remoteNodesListProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$remoteNodesListHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<List<RemoteNode>> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<List<RemoteNode>> create(Ref ref) {
|
||||
return remoteNodesList(ref);
|
||||
}
|
||||
}
|
||||
|
||||
String _$remoteNodesListHash() => r'a2d3bd0b2e2f2cd54a7590bb5ace8a0c63e3d2aa';
|
||||
|
||||
/// The live `/nodes/aggregated` fan-out result, polled every 25s. Shared
|
||||
/// by the Dashboard's "Fleet" stat tile and the Fleet screen's card grid
|
||||
/// (M6) — one poll, cached by Riverpod, rather than each screen running
|
||||
/// its own duplicate timer against the same endpoint.
|
||||
|
||||
@ProviderFor(AggregatedNodes)
|
||||
const aggregatedNodesProvider = AggregatedNodesProvider._();
|
||||
|
||||
/// The live `/nodes/aggregated` fan-out result, polled every 25s. Shared
|
||||
/// by the Dashboard's "Fleet" stat tile and the Fleet screen's card grid
|
||||
/// (M6) — one poll, cached by Riverpod, rather than each screen running
|
||||
/// its own duplicate timer against the same endpoint.
|
||||
final class AggregatedNodesProvider
|
||||
extends
|
||||
$AsyncNotifierProvider<AggregatedNodes, List<AggregatedNodeStatus>> {
|
||||
/// The live `/nodes/aggregated` fan-out result, polled every 25s. Shared
|
||||
/// by the Dashboard's "Fleet" stat tile and the Fleet screen's card grid
|
||||
/// (M6) — one poll, cached by Riverpod, rather than each screen running
|
||||
/// its own duplicate timer against the same endpoint.
|
||||
const AggregatedNodesProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'aggregatedNodesProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$aggregatedNodesHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
AggregatedNodes create() => AggregatedNodes();
|
||||
}
|
||||
|
||||
String _$aggregatedNodesHash() => r'14dd7a1e7d4b9caf2d7c975613555977c037dceb';
|
||||
|
||||
/// The live `/nodes/aggregated` fan-out result, polled every 25s. Shared
|
||||
/// by the Dashboard's "Fleet" stat tile and the Fleet screen's card grid
|
||||
/// (M6) — one poll, cached by Riverpod, rather than each screen running
|
||||
/// its own duplicate timer against the same endpoint.
|
||||
|
||||
abstract class _$AggregatedNodes
|
||||
extends $AsyncNotifier<List<AggregatedNodeStatus>> {
|
||||
FutureOr<List<AggregatedNodeStatus>> build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref =
|
||||
this.ref
|
||||
as $Ref<
|
||||
AsyncValue<List<AggregatedNodeStatus>>,
|
||||
List<AggregatedNodeStatus>
|
||||
>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<
|
||||
AsyncValue<List<AggregatedNodeStatus>>,
|
||||
List<AggregatedNodeStatus>
|
||||
>,
|
||||
AsyncValue<List<AggregatedNodeStatus>>,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../../core/models/models.dart';
|
||||
import '../../core/network/api_client_provider.dart';
|
||||
import '../../core/network/node_master_api_client.dart';
|
||||
|
||||
part 'services_repository.g.dart';
|
||||
|
||||
/// Wraps the `/services/*` endpoints — the compose-based services on this
|
||||
/// host and their start/stop/backup actions.
|
||||
class ServicesRepository {
|
||||
const ServicesRepository(this._client);
|
||||
|
||||
final NodeMasterApiClient _client;
|
||||
|
||||
Future<List<Service>> getAll() => _client.getAllServices();
|
||||
Future<Service> get(String id) => _client.getService(id);
|
||||
Future<Service> add(Service service) => _client.addService(service);
|
||||
Future<Service> update(String id, Service service) => _client.updateService(id, service);
|
||||
Future<void> delete(String id) => _client.deleteService(id);
|
||||
Future<void> start(String id) => _client.startService(id);
|
||||
Future<void> stop(String id) => _client.stopService(id);
|
||||
Future<void> backupNow(String id) => _client.backupService(id);
|
||||
|
||||
Future<List<BackupTarget>> getBackupTargets(String id) => _client.getServiceBackupTargets(id);
|
||||
Future<BackupTarget> addBackupTarget(String id, BackupTarget target) =>
|
||||
_client.addServiceBackupTarget(id, target);
|
||||
Future<BackupTarget> updateBackupTarget(String id, String targetId, BackupTarget target) =>
|
||||
_client.updateServiceBackupTarget(id, targetId, target);
|
||||
Future<void> deleteBackupTarget(String id, String targetId) =>
|
||||
_client.deleteServiceBackupTarget(id, targetId);
|
||||
Future<void> runBackupTarget(String id, String targetId) =>
|
||||
_client.runServiceBackupTarget(id, targetId);
|
||||
Future<RunState> getBackupTargetProgress(String id, String targetId) =>
|
||||
_client.getServiceBackupTargetProgress(id, targetId);
|
||||
Future<List<RunState>> getBackupProgress(String id) => _client.getServiceBackupProgress(id);
|
||||
}
|
||||
|
||||
/// Null when no connection is active, mirroring [apiClientProvider].
|
||||
@riverpod
|
||||
ServicesRepository? servicesRepository(Ref ref) {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
if (client == null) return null;
|
||||
return ServicesRepository(client);
|
||||
}
|
||||
|
||||
/// The full services list for the active connection. Manual-refresh only
|
||||
/// (not polled) — this is a detail-heavy table screen where a mid-edit
|
||||
/// slide-over silently refreshing underneath the user would be worse than
|
||||
/// slightly stale data; Dashboard's polled summary is where "did something
|
||||
/// change" gets noticed at a glance.
|
||||
@riverpod
|
||||
Future<List<Service>> servicesList(Ref ref) async {
|
||||
final repo = ref.watch(servicesRepositoryProvider);
|
||||
if (repo == null) return [];
|
||||
return repo.getAll();
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'services_repository.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Null when no connection is active, mirroring [apiClientProvider].
|
||||
|
||||
@ProviderFor(servicesRepository)
|
||||
const servicesRepositoryProvider = ServicesRepositoryProvider._();
|
||||
|
||||
/// Null when no connection is active, mirroring [apiClientProvider].
|
||||
|
||||
final class ServicesRepositoryProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
ServicesRepository?,
|
||||
ServicesRepository?,
|
||||
ServicesRepository?
|
||||
>
|
||||
with $Provider<ServicesRepository?> {
|
||||
/// Null when no connection is active, mirroring [apiClientProvider].
|
||||
const ServicesRepositoryProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'servicesRepositoryProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$servicesRepositoryHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<ServicesRepository?> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
ServicesRepository? create(Ref ref) {
|
||||
return servicesRepository(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(ServicesRepository? value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<ServicesRepository?>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$servicesRepositoryHash() =>
|
||||
r'6eab348f1911803394716fd8f90a079bfe5cbda1';
|
||||
|
||||
/// The full services list for the active connection. Manual-refresh only
|
||||
/// (not polled) — this is a detail-heavy table screen where a mid-edit
|
||||
/// slide-over silently refreshing underneath the user would be worse than
|
||||
/// slightly stale data; Dashboard's polled summary is where "did something
|
||||
/// change" gets noticed at a glance.
|
||||
|
||||
@ProviderFor(servicesList)
|
||||
const servicesListProvider = ServicesListProvider._();
|
||||
|
||||
/// The full services list for the active connection. Manual-refresh only
|
||||
/// (not polled) — this is a detail-heavy table screen where a mid-edit
|
||||
/// slide-over silently refreshing underneath the user would be worse than
|
||||
/// slightly stale data; Dashboard's polled summary is where "did something
|
||||
/// change" gets noticed at a glance.
|
||||
|
||||
final class ServicesListProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AsyncValue<List<Service>>,
|
||||
List<Service>,
|
||||
FutureOr<List<Service>>
|
||||
>
|
||||
with $FutureModifier<List<Service>>, $FutureProvider<List<Service>> {
|
||||
/// The full services list for the active connection. Manual-refresh only
|
||||
/// (not polled) — this is a detail-heavy table screen where a mid-edit
|
||||
/// slide-over silently refreshing underneath the user would be worse than
|
||||
/// slightly stale data; Dashboard's polled summary is where "did something
|
||||
/// change" gets noticed at a glance.
|
||||
const ServicesListProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'servicesListProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$servicesListHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$FutureProviderElement<List<Service>> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $FutureProviderElement(pointer);
|
||||
|
||||
@override
|
||||
FutureOr<List<Service>> create(Ref ref) {
|
||||
return servicesList(ref);
|
||||
}
|
||||
}
|
||||
|
||||
String _$servicesListHash() => r'e9d080c9ce0c0796d39c663ba79d7b67a2cf3adc';
|
||||
Reference in New Issue
Block a user