all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH pve-flutter-frontend v2] node overview: add power settings menu
@ 2024-04-17  6:45 Dominik Csapak
  2024-04-17  8:19 ` Folke Gleumes
  2024-04-17  8:48 ` [pve-devel] applied: " Thomas Lamprecht
  0 siblings, 2 replies; 4+ messages in thread
From: Dominik Csapak @ 2024-04-17  6:45 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 v1:
* add an AlertDialog as confirmation before executing the action

 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..621ac68
--- /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 $actionText node '${bloc.nodeID}'?"),
+            actions: [
+              TextButton(
+                  onPressed: () => Navigator.of(context).pop(true),
+                  child: const Text("Yes")),
+              TextButton(
+                  onPressed: () => Navigator.of(context).pop(false),
+                  child: const Text("No"))
+            ],
+          );
+        })) {
+      bloc.events.add(PerformNodeAction(action));
+      if (context.mounted) Navigator.of(context).pop();
+    }
+  }
+}
-- 
2.39.2





^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [pve-devel] [PATCH pve-flutter-frontend v2] node overview: add power settings menu
  2024-04-17  6:45 [pve-devel] [PATCH pve-flutter-frontend v2] node overview: add power settings menu Dominik Csapak
@ 2024-04-17  8:19 ` Folke Gleumes
  2024-04-17  8:33   ` Dominik Csapak
  2024-04-17  8:48 ` [pve-devel] applied: " Thomas Lamprecht
  1 sibling, 1 reply; 4+ messages in thread
From: Folke Gleumes @ 2024-04-17  8:19 UTC (permalink / raw)
  To: Proxmox VE development discussion

On Wed, 2024-04-17 at 08:45 +0200, Dominik Csapak wrote:
> 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 v1:
> * add an AlertDialog as confirmation before executing the action
> 
>  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.d
> art';
>  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..621ac68
> --- /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.d
> art';
> +
> +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 $actionText node
> '${bloc.nodeID}'?"),
> +            actions: [
> +              TextButton(
> +                  onPressed: () => Navigator.of(context).pop(true),
> +                  child: const Text("Yes")),
> +              TextButton(
> +                  onPressed: () => Navigator.of(context).pop(false),
> +                  child: const Text("No"))
> +            ],

The order of buttons probably should be reversed. According to material
guidelines a dismissive action has to be placed to the left of
confirming actions [0]. In practice, I accidentally shut down my test
VM because I intuitively went for the leftmost button to abort. To make
the actions even more obvious, they could be phrased as Cancel and
Shutdown/Reboot.

> +          );
> +        })) {
> +      bloc.events.add(PerformNodeAction(action));
> +      if (context.mounted) Navigator.of(context).pop();
> +    }
> +  }
> +}

Besides the button ordering, everything worked well, so if those are
changed, consider this:

Tested-by: Folke Gleumes <f.gleumes@proxmox.com>

[0] https://m2.material.io/components/dialogs#actions

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [pve-devel] [PATCH pve-flutter-frontend v2] node overview: add power settings menu
  2024-04-17  8:19 ` Folke Gleumes
@ 2024-04-17  8:33   ` Dominik Csapak
  0 siblings, 0 replies; 4+ messages in thread
From: Dominik Csapak @ 2024-04-17  8:33 UTC (permalink / raw)
  To: Proxmox VE development discussion, Folke Gleumes

On 4/17/24 10:19, Folke Gleumes wrote:
> On Wed, 2024-04-17 at 08:45 +0200, Dominik Csapak wrote:
>> 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 v1:
>> * add an AlertDialog as confirmation before executing the action
>>
>>   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.d
>> art';
>>   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..621ac68
>> --- /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.d
>> art';
>> +
>> +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 $actionText node
>> '${bloc.nodeID}'?"),
>> +            actions: [
>> +              TextButton(
>> +                  onPressed: () => Navigator.of(context).pop(true),
>> +                  child: const Text("Yes")),
>> +              TextButton(
>> +                  onPressed: () => Navigator.of(context).pop(false),
>> +                  child: const Text("No"))
>> +            ],
> 
> The order of buttons probably should be reversed. According to material
> guidelines a dismissive action has to be placed to the left of
> confirming actions [0]. In practice, I accidentally shut down my test
> VM because I intuitively went for the leftmost button to abort. To make
> the actions even more obvious, they could be phrased as Cancel and
> Shutdown/Reboot.

fair enough, i used the same order as we do for the desktop ui
(left yes, right no), but that is probably also not super ideal?

i'll send a v3

> 
>> +          );
>> +        })) {
>> +      bloc.events.add(PerformNodeAction(action));
>> +      if (context.mounted) Navigator.of(context).pop();
>> +    }
>> +  }
>> +}
> 
> Besides the button ordering, everything worked well, so if those are
> changed, consider this:
> 
> Tested-by: Folke Gleumes <f.gleumes@proxmox.com>
> 
> [0] https://m2.material.io/components/dialogs#actions
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel





^ permalink raw reply	[flat|nested] 4+ messages in thread

* [pve-devel] applied: [PATCH pve-flutter-frontend v2] node overview: add power settings menu
  2024-04-17  6:45 [pve-devel] [PATCH pve-flutter-frontend v2] node overview: add power settings menu Dominik Csapak
  2024-04-17  8:19 ` Folke Gleumes
@ 2024-04-17  8:48 ` Thomas Lamprecht
  1 sibling, 0 replies; 4+ messages in thread
From: Thomas Lamprecht @ 2024-04-17  8:48 UTC (permalink / raw)
  To: Proxmox VE development discussion, Dominik Csapak

Am 17/04/2024 um 08:45 schrieb Dominik Csapak:
> 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 v1:
> * add an AlertDialog as confirmation before executing the action
> 
>  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
> 
>

applied this already a bit ago [0] with some code style follow-up [1], so
can you please send the changes to adapt to Folke's review as patch on-top
of current master?

[0]: https://git.proxmox.com/?p=flutter/pve_flutter_frontend.git;a=commitdiff;h=16ddf759f338e59501520068867624b549215553
[1]: https://git.proxmox.com/?p=flutter/pve_flutter_frontend.git;a=commitdiff;h=e883ee3b9c9c7c6cee85d5ac77dcc86dbf7c12c0




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-04-17  8:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-17  6:45 [pve-devel] [PATCH pve-flutter-frontend v2] node overview: add power settings menu Dominik Csapak
2024-04-17  8:19 ` Folke Gleumes
2024-04-17  8:33   ` Dominik Csapak
2024-04-17  8:48 ` [pve-devel] applied: " Thomas Lamprecht

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.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal