* [pve-devel] [PATCH pve-flutter-frontend v3] node overview: add power settings menu
@ 2024-04-17 8:41 Dominik Csapak
0 siblings, 0 replies; only message in thread
From: Dominik Csapak @ 2024-04-17 8:41 UTC (permalink / raw)
To: pve-devel
similar to how it works for qemu, but add a confirmation dialog
so one does not accidentally shutdown or reboot a node.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v2:
* reordered and renamed yes/no on the confirmation dialog
* slightly adapted the confirmation text
lib/bloc/pve_node_overview_bloc.dart | 11 +++
lib/widgets/pve_node_overview.dart | 24 ++++++
.../pve_node_power_settings_widget.dart | 84 +++++++++++++++++++
3 files changed, 119 insertions(+)
create mode 100644 lib/widgets/pve_node_power_settings_widget.dart
diff --git a/lib/bloc/pve_node_overview_bloc.dart b/lib/bloc/pve_node_overview_bloc.dart
index d14ff79..19d6563 100644
--- a/lib/bloc/pve_node_overview_bloc.dart
+++ b/lib/bloc/pve_node_overview_bloc.dart
@@ -57,9 +57,20 @@ class PveNodeOverviewBloc
final disks = await apiClient.getNodeDisksList(nodeID);
yield latestState.rebuild((b) => b..disks.replace(disks));
}
+ if (event is PerformNodeAction) {
+ await apiClient.doResourceAction(nodeID, '', 'node', event.action,
+ parameters: <String, String>{});
+ yield latestState;
+ }
}
}
abstract class PveNodeOverviewEvent {}
class UpdateNodeStatus extends PveNodeOverviewEvent {}
+
+class PerformNodeAction extends PveNodeOverviewEvent {
+ final PveClusterResourceAction action;
+
+ PerformNodeAction(this.action);
+}
diff --git a/lib/widgets/pve_node_overview.dart b/lib/widgets/pve_node_overview.dart
index 7b65c0e..ad9a3b2 100644
--- a/lib/widgets/pve_node_overview.dart
+++ b/lib/widgets/pve_node_overview.dart
@@ -8,6 +8,7 @@ import 'package:pve_flutter_frontend/states/pve_node_overview_state.dart';
import 'package:pve_flutter_frontend/states/pve_task_log_state.dart';
import 'package:pve_flutter_frontend/utils/renderers.dart';
import 'package:pve_flutter_frontend/utils/utils.dart';
+import 'package:pve_flutter_frontend/widgets/pve_node_power_settings_widget.dart';
import 'package:pve_flutter_frontend/widgets/proxmox_capacity_indicator.dart';
import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
import 'package:pve_flutter_frontend/widgets/pve_action_card_widget.dart';
@@ -189,6 +190,16 @@ class PveNodeOverview extends StatelessWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
+ ActionCard(
+ icon: const Icon(
+ Icons.power_settings_new,
+ size: 55,
+ color: Colors.white24,
+ ),
+ title: 'Power Settings',
+ onTap: () =>
+ showPowerMenuBottomSheet(context, nBloc),
+ ),
ActionCard(
icon: const Icon(
Icons.queue_play_next,
@@ -443,4 +454,17 @@ class PveNodeOverview extends StatelessWidget {
},
);
}
+
+ Future<T?> showPowerMenuBottomSheet<T>(
+ BuildContext context, PveNodeOverviewBloc nodeBloc) async {
+ return showModalBottomSheet(
+ shape: const RoundedRectangleBorder(
+ borderRadius: BorderRadius.vertical(top: Radius.circular(10))),
+ context: context,
+ builder: (context) => Provider.value(
+ value: nodeBloc,
+ child: const PveNodePowerSettings(),
+ ),
+ );
+ }
}
diff --git a/lib/widgets/pve_node_power_settings_widget.dart b/lib/widgets/pve_node_power_settings_widget.dart
new file mode 100644
index 0000000..5de9c85
--- /dev/null
+++ b/lib/widgets/pve_node_power_settings_widget.dart
@@ -0,0 +1,84 @@
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+import 'package:proxmox_dart_api_client/proxmox_dart_api_client.dart';
+import 'package:pve_flutter_frontend/bloc/pve_node_overview_bloc.dart';
+import 'package:pve_flutter_frontend/states/pve_node_overview_state.dart';
+import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
+
+class PveNodePowerSettings extends StatelessWidget {
+ const PveNodePowerSettings({
+ super.key,
+ });
+ @override
+ Widget build(BuildContext context) {
+ final bloc = Provider.of<PveNodeOverviewBloc>(context);
+ return ProxmoxStreamBuilder<PveNodeOverviewBloc, PveNodeOverviewState>(
+ bloc: bloc,
+ builder: (context, state) {
+ return SafeArea(
+ child: SingleChildScrollView(
+ child: Container(
+ constraints: BoxConstraints(
+ minHeight: MediaQuery.of(context).size.height / 3),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: <Widget>[
+ ListTile(
+ leading: const Icon(Icons.autorenew),
+ title: const Text(
+ "Reboot",
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ subtitle: const Text("Reboot Node"),
+ onTap: () => action(context,
+ PveClusterResourceAction.reboot, bloc, "Reboot"),
+ ),
+ ListTile(
+ leading: const Icon(Icons.power_settings_new),
+ title: const Text(
+ "Shutdown",
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ subtitle: const Text("Shutdown Node"),
+ onTap: () => action(context,
+ PveClusterResourceAction.shutdown, bloc, "Shutdown"),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ });
+ }
+
+ void action(BuildContext context, PveClusterResourceAction action,
+ PveNodeOverviewBloc bloc, String actionText) async {
+ if (await showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ contentPadding: const EdgeInsets.fromLTRB(24.0, 12.0, 24.0, 16.0),
+ title: const Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: <Widget>[
+ Text('Confirm'),
+ Icon(Icons.warning),
+ ],
+ ),
+ content: Text(
+ "Are you sure you want to do action '$actionText' on node '${bloc.nodeID}'?"),
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.of(context).pop(false),
+ child: const Text("Cancel")),
+ TextButton(
+ onPressed: () => Navigator.of(context).pop(true),
+ child: Text(actionText))
+ ],
+ );
+ })) {
+ bloc.events.add(PerformNodeAction(action));
+ if (context.mounted) Navigator.of(context).pop();
+ }
+ }
+}
--
2.39.2
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2024-04-17 8:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-17 8:41 [pve-devel] [PATCH pve-flutter-frontend v3] node overview: add power settings menu Dominik Csapak
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.