From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id BBE9F961F1 for ; Mon, 15 Apr 2024 12:30:35 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 4ACF4799C for ; Mon, 15 Apr 2024 12:30:35 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Mon, 15 Apr 2024 12:30:31 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 1DC4544AB1 for ; Mon, 15 Apr 2024 12:30:29 +0200 (CEST) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Mon, 15 Apr 2024 12:30:26 +0200 Message-Id: <20240415103027.3000412-8-d.csapak@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240415103027.3000412-1-d.csapak@proxmox.com> References: <20240415103027.3000412-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.014 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH pve-flutter-frontend 4/5] nove overview: add power settings menu X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Apr 2024 10:30:35 -0000 similar to how it works for qemu Signed-off-by: Dominik Csapak --- this depends on the dart-api-client patch, otherwise the url is wrong lib/bloc/pve_node_overview_bloc.dart | 11 ++++ lib/widgets/pve_node_overview.dart | 24 ++++++++ .../pve_node_power_settings_widget.dart | 59 +++++++++++++++++++ 3 files changed, 94 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 caeb1c4..2f07ef9 100644 --- a/lib/bloc/pve_node_overview_bloc.dart +++ b/lib/bloc/pve_node_overview_bloc.dart @@ -52,9 +52,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: {}); + 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 219d498..a5d79a3 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: [ + 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, @@ -439,4 +450,17 @@ class PveNodeOverview extends StatelessWidget { }, ); } + + Future showPowerMenuBottomSheet( + 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..f8d35d1 --- /dev/null +++ b/lib/widgets/pve_node_power_settings_widget.dart @@ -0,0 +1,59 @@ +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(context); + return ProxmoxStreamBuilder( + 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: [ + 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), + ), + 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), + ), + ], + ), + ), + ), + ); + }); + } + + void action(BuildContext context, PveClusterResourceAction action, + PveNodeOverviewBloc bloc) { + bloc.events.add(PerformNodeAction(action)); + Navigator.of(context).pop(); + } +} -- 2.39.2