all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused`
@ 2025-06-02 13:37 Shan Shaji
  2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/2] refactor: move and split the `_MobileResourceFilterSheet` widget Shan Shaji
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Shan Shaji @ 2025-06-02 13:37 UTC (permalink / raw)
  To: pve-devel

This patch series includes the fix for guest missing when the status 
is `paused`. Additionaly the series also includes the changes from 
another patch which can be found here: 

https://lore.proxmox.com/pve-devel/20250522130825.79862-1-s.shaji@proxmox.com/

pve_flutter_frontend:

Shan Shaji (2):
  refactor: move and split the `_MobileResourceFilterSheet` widget
  fix: ui: guests missing in resources tab when status is `paused`

 lib/pages/main_layout_slim.dart               | 175 +--------------
 .../pve_mobile_resource_filter_sheet.dart     | 202 ++++++++++++++++++
 2 files changed, 204 insertions(+), 173 deletions(-)
 create mode 100644 lib/widgets/pve_mobile_resource_filter_sheet.dart


proxmox_dart_api_client:

Shan Shaji (1):
  fix: ui: add missing `paused` status check

 lib/src/models/pve_cluster_resources_model.dart | 2 ++
 1 file changed, 2 insertions(+)


Summary over all repositories:
  3 files changed, 206 insertions(+), 173 deletions(-)

-- 
Generated by git-murpp 0.8.1


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


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

* [pve-devel] [PATCH pve_flutter_frontend v2 1/2] refactor: move and split the `_MobileResourceFilterSheet` widget
  2025-06-02 13:37 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Shan Shaji
@ 2025-06-02 13:37 ` Shan Shaji
  2025-06-03  8:10   ` Michael Köppl
  2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 2/2] fix: ui: guests missing in resources tab when status is `paused` Shan Shaji
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Shan Shaji @ 2025-06-02 13:37 UTC (permalink / raw)
  To: pve-devel

This patch splits the `_MobileResourceFilterSheet` into multiple widgets
and since the `main_layout_slim.dart` file is large, the widget has been
moved to it's own file under the widgets folder.

Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
 
 changes since v1:
 * Removed all formatting changes.
 * Only includes the refactoring of `_MobileResourceFilterSheet` widget. 
 * Moved "paused guest not showing in resources tab" bug to another patch. 
 
 lib/pages/main_layout_slim.dart               | 175 +---------------
 .../pve_mobile_resource_filter_sheet.dart     | 188 ++++++++++++++++++
 2 files changed, 190 insertions(+), 173 deletions(-)
 create mode 100644 lib/widgets/pve_mobile_resource_filter_sheet.dart

diff --git a/lib/pages/main_layout_slim.dart b/lib/pages/main_layout_slim.dart
index 3bcd83b..8d6e5ed 100644
--- a/lib/pages/main_layout_slim.dart
+++ b/lib/pages/main_layout_slim.dart
@@ -11,6 +11,7 @@ import 'package:pve_flutter_frontend/bloc/pve_cluster_status_bloc.dart';
 import 'package:pve_flutter_frontend/bloc/pve_file_selector_bloc.dart';
 import 'package:pve_flutter_frontend/bloc/pve_resource_bloc.dart';
 import 'package:pve_flutter_frontend/bloc/pve_storage_selector_bloc.dart';
+import 'package:pve_flutter_frontend/widgets/pve_mobile_resource_filter_sheet.dart';
 import 'package:pve_flutter_frontend/states/pve_access_management_state.dart';
 import 'package:pve_flutter_frontend/states/pve_cluster_status_state.dart';
 import 'package:pve_flutter_frontend/states/pve_file_selector_state.dart';
@@ -606,7 +607,7 @@ class MobileResourceOverview extends StatelessWidget {
           },
           child: ColoredSafeArea(
               child: Scaffold(
-            endDrawer: _MobileResourceFilterSheet(),
+            endDrawer: PveMobileResourceFilterSheet(),
             appBar: AppBar(
               automaticallyImplyLeading: false,
               elevation: 0,
@@ -844,178 +845,6 @@ class _AppbarSearchTextFieldState extends State<AppbarSearchTextField> {
   }
 }
 
-class _MobileResourceFilterSheet extends StatelessWidget {
-  @override
-  Widget build(BuildContext context) {
-    final rBloc = Provider.of<PveResourceBloc>(context);
-
-    return ProxmoxStreamBuilder<PveResourceBloc, PveResourceState>(
-      bloc: rBloc,
-      builder: (context, state) => Drawer(
-        child: SingleChildScrollView(
-          child: Column(
-            crossAxisAlignment: CrossAxisAlignment.start,
-            children: <Widget>[
-              Padding(
-                padding: const EdgeInsets.fromLTRB(8.0, 20.0, 8.0, 0),
-                child: ListTile(
-                  title: const Text(
-                    'Filter Results',
-                  ),
-                  trailing: rBloc.isFiltered
-                      ? TextButton(
-                          onPressed: () => rBloc.events.add(ResetFilter()),
-                          child: Text(
-                            'Reset',
-                            style: TextStyle(
-                              color: Theme.of(context).colorScheme.secondary,
-                            ),
-                          ),
-                        )
-                      : null,
-                ),
-              ),
-              const Divider(
-                indent: 0,
-                endIndent: 0,
-              ),
-              Padding(
-                padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
-                child: Column(
-                  children: [
-                    const ListTile(
-                      title: Text(
-                        'Type',
-                        style: TextStyle(fontWeight: FontWeight.bold),
-                      ),
-                    ),
-                    CheckboxListTile(
-                      dense: true,
-                      title: Text(
-                        'Nodes',
-                        style: TextStyle(
-                            color: Theme.of(context)
-                                .colorScheme
-                                .onSurface
-                                .withValues(alpha: 0.75)),
-                      ),
-                      value: state.typeFilter.contains('node'),
-                      onChanged: (v) => rBloc.events.add(FilterResources(
-                        typeFilter: addOrRemove(v!, 'node', state.typeFilter),
-                      )),
-                    ),
-                    CheckboxListTile(
-                      dense: true,
-                      title: Text(
-                        'Qemu',
-                        style: TextStyle(
-                            color: Theme.of(context)
-                                .colorScheme
-                                .onSurface
-                                .withValues(alpha: 0.75)),
-                      ),
-                      value: state.typeFilter.contains('qemu'),
-                      onChanged: (v) => rBloc.events.add(FilterResources(
-                        typeFilter: addOrRemove(v!, 'qemu', state.typeFilter),
-                      )),
-                    ),
-                    CheckboxListTile(
-                      dense: true,
-                      title: Text(
-                        'LXC',
-                        style: TextStyle(
-                            color: Theme.of(context)
-                                .colorScheme
-                                .onSurface
-                                .withValues(alpha: 0.75)),
-                      ),
-                      value: state.typeFilter.contains('lxc'),
-                      onChanged: (v) => rBloc.events.add(FilterResources(
-                        typeFilter: addOrRemove(v!, 'lxc', state.typeFilter),
-                      )),
-                    ),
-                    CheckboxListTile(
-                      dense: true,
-                      title: Text(
-                        'Storage',
-                        style: TextStyle(
-                            color: Theme.of(context)
-                                .colorScheme
-                                .onSurface
-                                .withValues(alpha: 0.75)),
-                      ),
-                      value: state.typeFilter.contains('storage'),
-                      onChanged: (v) => rBloc.events.add(FilterResources(
-                        typeFilter:
-                            addOrRemove(v!, 'storage', state.typeFilter),
-                      )),
-                    ),
-                  ],
-                ),
-              ),
-              Padding(
-                padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
-                child: Column(
-                  children: [
-                    const ListTile(
-                      title: Text(
-                        'Status',
-                        style: TextStyle(fontWeight: FontWeight.bold),
-                      ),
-                    ),
-                    CheckboxListTile(
-                      dense: true,
-                      title: Text(
-                        'Online',
-                        style: TextStyle(
-                            color: Theme.of(context)
-                                .colorScheme
-                                .onSurface
-                                .withValues(alpha: 0.75)),
-                      ),
-                      value: state.statusFilter
-                          .contains(PveResourceStatusType.running),
-                      onChanged: (v) => rBloc.events.add(FilterResources(
-                        statusFilter: addOrRemove(v!,
-                            PveResourceStatusType.running, state.statusFilter),
-                      )),
-                    ),
-                    CheckboxListTile(
-                      dense: true,
-                      title: Text(
-                        'Offline',
-                        style: TextStyle(
-                            color: Theme.of(context)
-                                .colorScheme
-                                .onSurface
-                                .withValues(alpha: 0.75)),
-                      ),
-                      value: state.statusFilter
-                          .contains(PveResourceStatusType.stopped),
-                      onChanged: (v) => rBloc.events.add(FilterResources(
-                        statusFilter: addOrRemove(v!,
-                            PveResourceStatusType.stopped, state.statusFilter),
-                      )),
-                    ),
-                  ],
-                ),
-              )
-            ],
-          ),
-        ),
-      ),
-    );
-  }
-
-  BuiltSet<S> addOrRemove<S>(bool value, S element, BuiltSet<S> filter) {
-    if (value) {
-      return filter.rebuild((b) => b..add(element));
-    } else {
-      return filter.rebuild((b) => b..remove(element));
-    }
-  }
-}
-
 class AppBarFilterIconButton extends StatelessWidget {
   const AppBarFilterIconButton({super.key});
 
diff --git a/lib/widgets/pve_mobile_resource_filter_sheet.dart b/lib/widgets/pve_mobile_resource_filter_sheet.dart
new file mode 100644
index 0000000..cee3a49
--- /dev/null
+++ b/lib/widgets/pve_mobile_resource_filter_sheet.dart
@@ -0,0 +1,188 @@
+import 'package:built_collection/built_collection.dart';
+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_resource_bloc.dart';
+import 'package:pve_flutter_frontend/states/pve_resource_state.dart';
+import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
+
+class PveMobileResourceFilterSheet extends StatelessWidget {
+  const PveMobileResourceFilterSheet({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    final rBloc = Provider.of<PveResourceBloc>(context);
+    return ProxmoxStreamBuilder<PveResourceBloc, PveResourceState>(
+      bloc: rBloc,
+      builder: (context, state) => Drawer(
+        child: SingleChildScrollView(
+          child: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Padding(
+                padding: const EdgeInsets.fromLTRB(8.0, 20.0, 8.0, 0),
+                child: ListTile(
+                  title: const Text(
+                    'Filter Results',
+                  ),
+                  trailing: rBloc.isFiltered
+                      ? TextButton(
+                          onPressed: () => rBloc.events.add(ResetFilter()),
+                          child: Text(
+                            'Reset',
+                            style: TextStyle(
+                              color: Theme.of(context).colorScheme.secondary,
+                            ),
+                          ),
+                        )
+                      : null,
+                ),
+              ),
+              const Divider(indent: 0, endIndent: 0),
+              _PveFilterSheetSection(
+                sectionTitle: 'Type',
+                items: [
+                  _ProxmoxResourceFilterListTile(
+                    title: 'Nodes',
+                    value: state.typeFilter.contains('node'),
+                    onChanged: (v) => rBloc.events.add(
+                      FilterResources(
+                        typeFilter: _addOrRemove(v!, 'node', state.typeFilter),
+                      ),
+                    ),
+                  ),
+                  _ProxmoxResourceFilterListTile(
+                    title: 'Qemu',
+                    value: state.typeFilter.contains('qemu'),
+                    onChanged: (v) => rBloc.events.add(
+                      FilterResources(
+                        typeFilter: _addOrRemove(v!, 'qemu', state.typeFilter),
+                      ),
+                    ),
+                  ),
+                  _ProxmoxResourceFilterListTile(
+                    title: 'LXC',
+                    value: state.typeFilter.contains('lxc'),
+                    onChanged: (v) => rBloc.events.add(
+                      FilterResources(
+                        typeFilter: _addOrRemove(v!, 'lxc', state.typeFilter),
+                      ),
+                    ),
+                  ),
+                  _ProxmoxResourceFilterListTile(
+                    title: 'Storage',
+                    value: state.typeFilter.contains('storage'),
+                    onChanged: (v) => rBloc.events.add(
+                      FilterResources(
+                        typeFilter:
+                            _addOrRemove(v!, 'storage', state.typeFilter),
+                      ),
+                    ),
+                  ),
+                ],
+              ),
+              _PveFilterSheetSection(
+                sectionTitle: 'Status',
+                items: [
+                  _ProxmoxResourceFilterListTile(
+                    title: 'Online',
+                    value: state.statusFilter
+                        .contains(PveResourceStatusType.running),
+                    onChanged: (v) => rBloc.events.add(
+                      FilterResources(
+                        statusFilter: _addOrRemove(
+                          v!,
+                          PveResourceStatusType.running,
+                          state.statusFilter,
+                        ),
+                      ),
+                    ),
+                  ),
+                  _ProxmoxResourceFilterListTile(
+                    title: 'Offline',
+                    value: state.statusFilter
+                        .contains(PveResourceStatusType.stopped),
+                    onChanged: (v) => rBloc.events.add(
+                      FilterResources(
+                        statusFilter: _addOrRemove(
+                          v!,
+                          PveResourceStatusType.stopped,
+                          state.statusFilter,
+                        ),
+                      ),
+                    ),
+                  ),
+                ],
+              )
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+
+  BuiltSet<S> _addOrRemove<S>(bool value, S element, BuiltSet<S> filter) {
+    if (value) {
+      return filter.rebuild((b) => b..add(element));
+    } else {
+      return filter.rebuild((b) => b..remove(element));
+    }
+  }
+}
+
+class _PveFilterSheetSection extends StatelessWidget {
+  const _PveFilterSheetSection({
+    required this.items,
+    required this.sectionTitle,
+  });
+
+  final List<Widget> items;
+  final String sectionTitle;
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 8),
+      child: Column(
+        children: [
+          ListTile(
+            title: Text(
+              sectionTitle,
+              style: TextStyle(fontWeight: FontWeight.bold),
+            ),
+          ),
+          ...items,
+        ],
+      ),
+    );
+  }
+}
+
+class _ProxmoxResourceFilterListTile extends StatelessWidget {
+  const _ProxmoxResourceFilterListTile({
+    required this.title,
+    this.onChanged,
+    this.value,
+  });
+
+  final String title;
+  final ValueChanged<bool?>? onChanged;
+  final bool? value;
+
+  @override
+  Widget build(BuildContext context) {
+    return CheckboxListTile(
+      dense: true,
+      title: Text(
+        title,
+        style: TextStyle(
+          color: Theme.of(context).colorScheme.onSurface.withValues(
+                alpha: 0.75,
+              ),
+        ),
+      ),
+      value: value,
+      onChanged: onChanged,
+    );
+  }
+}
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


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

* [pve-devel] [PATCH pve_flutter_frontend v2 2/2] fix: ui: guests missing in resources tab when status is `paused`
  2025-06-02 13:37 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Shan Shaji
  2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/2] refactor: move and split the `_MobileResourceFilterSheet` widget Shan Shaji
@ 2025-06-02 13:37 ` Shan Shaji
  2025-06-03  8:02   ` Michael Köppl
  2025-06-02 13:37 ` [pve-devel] [PATCH proxmox_dart_api_client v2 1/1] fix: ui: add missing `paused` status check Shan Shaji
  2025-06-03  8:15 ` [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Michael Köppl
  3 siblings, 1 reply; 8+ messages in thread
From: Shan Shaji @ 2025-06-02 13:37 UTC (permalink / raw)
  To: pve-devel

When the guest status is set to `paused` the guest was not showing in
the resources tab. Also there were no option in the resources
filter to select the `paused` status under the status section.

This commit fixes the issue by adding the `paused` status under the
status section in the resources filter sheet.

Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
 
 changes since v1:
 * Removed all formatting changes. 
 * New `paused` status option is added after refactoring the filter sheet. 
 
 lib/widgets/pve_mobile_resource_filter_sheet.dart | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/lib/widgets/pve_mobile_resource_filter_sheet.dart b/lib/widgets/pve_mobile_resource_filter_sheet.dart
index cee3a49..c09b2cf 100644
--- a/lib/widgets/pve_mobile_resource_filter_sheet.dart
+++ b/lib/widgets/pve_mobile_resource_filter_sheet.dart
@@ -112,6 +112,20 @@ class PveMobileResourceFilterSheet extends StatelessWidget {
                       ),
                     ),
                   ),
+                  _ProxmoxResourceFilterListTile(
+                    title: 'Paused',
+                    value: state.statusFilter
+                        .contains(PveResourceStatusType.paused),
+                    onChanged: (v) => rBloc.events.add(
+                      FilterResources(
+                        statusFilter: _addOrRemove(
+                          v!,
+                          PveResourceStatusType.paused,
+                          state.statusFilter,
+                        ),
+                      ),
+                    ),
+                  ),
                 ],
               )
             ],
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


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

* [pve-devel] [PATCH proxmox_dart_api_client v2 1/1] fix: ui: add missing `paused` status check
  2025-06-02 13:37 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Shan Shaji
  2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/2] refactor: move and split the `_MobileResourceFilterSheet` widget Shan Shaji
  2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 2/2] fix: ui: guests missing in resources tab when status is `paused` Shan Shaji
@ 2025-06-02 13:37 ` Shan Shaji
  2025-06-03  8:15 ` [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Michael Köppl
  3 siblings, 0 replies; 8+ messages in thread
From: Shan Shaji @ 2025-06-02 13:37 UTC (permalink / raw)
  To: pve-devel

The `getStatus` function was not returning the corresponding
`PveResourceStatusType` when the status was `paused`. This commit adds
the missing status check.

Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
---
 
 changes since v1:
 * Removed all formatting changes

 lib/src/models/pve_cluster_resources_model.dart | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/src/models/pve_cluster_resources_model.dart b/lib/src/models/pve_cluster_resources_model.dart
index 16e18df..b92c1ef 100644
--- a/lib/src/models/pve_cluster_resources_model.dart
+++ b/lib/src/models/pve_cluster_resources_model.dart
@@ -69,6 +69,8 @@ abstract class PveClusterResourcesModel
       return PveResourceStatusType.stopped;
     }
 
+    if(status == 'paused') return PveResourceStatusType.paused;
+
     return PveResourceStatusType.unknown;
   }
 }
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


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

* Re: [pve-devel] [PATCH pve_flutter_frontend v2 2/2] fix: ui: guests missing in resources tab when status is `paused`
  2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 2/2] fix: ui: guests missing in resources tab when status is `paused` Shan Shaji
@ 2025-06-03  8:02   ` Michael Köppl
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Köppl @ 2025-06-03  8:02 UTC (permalink / raw)
  To: Proxmox VE development discussion, Shan Shaji

On 6/2/25 15:37, Shan Shaji wrote:
> When the guest status is set to `paused` the guest was not showing in
> the resources tab. Also there were no option in the resources
> filter to select the `paused` status under the status section.

The first sentence confused me a bit. The resource tab seems to show the
guest for me, but displays its status as "Unknown". That is fixed by the
following patch. This patch "only" adds the filter. I think a commit
message like "resources: add filter option for paused guest status"
would be more appropriate.

> 
> This commit fixes the issue by adding the `paused` status under the
> status section in the resources filter sheet.

nit: the commit message should not contain "This commit...".


> 
> Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
> ---
>  
>  changes since v1:
>  * Removed all formatting changes. 
>  * New `paused` status option is added after refactoring the filter sheet. 
>  
>  lib/widgets/pve_mobile_resource_filter_sheet.dart | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/lib/widgets/pve_mobile_resource_filter_sheet.dart b/lib/widgets/pve_mobile_resource_filter_sheet.dart
> index cee3a49..c09b2cf 100644
> --- a/lib/widgets/pve_mobile_resource_filter_sheet.dart
> +++ b/lib/widgets/pve_mobile_resource_filter_sheet.dart
> @@ -112,6 +112,20 @@ class PveMobileResourceFilterSheet extends StatelessWidget {
>                        ),
>                      ),
>                    ),
> +                  _ProxmoxResourceFilterListTile(
> +                    title: 'Paused',
> +                    value: state.statusFilter
> +                        .contains(PveResourceStatusType.paused),
> +                    onChanged: (v) => rBloc.events.add(
> +                      FilterResources(
> +                        statusFilter: _addOrRemove(
> +                          v!,
> +                          PveResourceStatusType.paused,
> +                          state.statusFilter,
> +                        ),
> +                      ),
> +                    ),
> +                  ),

Could make sense to do something like this:
_PveFilterSheetSection(
  sectionTitle: 'Status',
  items: [
    for (var statusFilterItem in [
      ('Online', PveResourceStatusType.running),
      ('Offline', PveResourceStatusType.stopped),
      ('Paused', PveResourceStatusType.paused),
    ]) _ProxmoxResourceFilterListTile(
      title: statusFilterItem.$1,
      value: state.statusFilter
          .contains(statusFilterItem.$2),
      onChanged: (v) => rBloc.events.add(
        FilterResources(
          statusFilter: _addOrRemove(
            v!,
            statusFilterItem.$2,
            state.statusFilter,
          ),
        ),
      ),
    ),
  ],
)

instead of copying the entire _ProxmoxResourceFilterListTile every time
we want to add another status as a filter. Not directly related to this
patch, just a suggestion. If you do send a v3 including this, it should
probably be a separate patch.

>                  ],
>                )
>              ],




_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


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

* Re: [pve-devel] [PATCH pve_flutter_frontend v2 1/2] refactor: move and split the `_MobileResourceFilterSheet` widget
  2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/2] refactor: move and split the `_MobileResourceFilterSheet` widget Shan Shaji
@ 2025-06-03  8:10   ` Michael Köppl
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Köppl @ 2025-06-03  8:10 UTC (permalink / raw)
  To: Proxmox VE development discussion, Shan Shaji

I think it's a good change. The MainLayoutSlim class is already more
than big enough.

On 6/2/25 15:37, Shan Shaji wrote:
> This patch splits the `_MobileResourceFilterSheet` into multiple widgets
> and since the `main_layout_slim.dart` file is large, the widget has been
> moved to it's own file under the widgets folder.

nit: commit message should not contain "This patch..."
also: s/it's/its

> 
> Signed-off-by: Shan Shaji <s.shaji@proxmox.com>
> ---
>  
>  changes since v1:
>  * Removed all formatting changes.
>  * Only includes the refactoring of `_MobileResourceFilterSheet` widget. 
>  * Moved "paused guest not showing in resources tab" bug to another patch. 
>  
>  lib/pages/main_layout_slim.dart               | 175 +---------------
>  .../pve_mobile_resource_filter_sheet.dart     | 188 ++++++++++++++++++
>  2 files changed, 190 insertions(+), 173 deletions(-)
>  create mode 100644 lib/widgets/pve_mobile_resource_filter_sheet.dart
> 
> diff --git a/lib/pages/main_layout_slim.dart b/lib/pages/main_layout_slim.dart
> index 3bcd83b..8d6e5ed 100644
> --- a/lib/pages/main_layout_slim.dart
> +++ b/lib/pages/main_layout_slim.dart
> @@ -11,6 +11,7 @@ import 'package:pve_flutter_frontend/bloc/pve_cluster_status_bloc.dart';
>  import 'package:pve_flutter_frontend/bloc/pve_file_selector_bloc.dart';
>  import 'package:pve_flutter_frontend/bloc/pve_resource_bloc.dart';
>  import 'package:pve_flutter_frontend/bloc/pve_storage_selector_bloc.dart';
> +import 'package:pve_flutter_frontend/widgets/pve_mobile_resource_filter_sheet.dart';
>  import 'package:pve_flutter_frontend/states/pve_access_management_state.dart';
>  import 'package:pve_flutter_frontend/states/pve_cluster_status_state.dart';
>  import 'package:pve_flutter_frontend/states/pve_file_selector_state.dart';
> @@ -606,7 +607,7 @@ class MobileResourceOverview extends StatelessWidget {
>            },
>            child: ColoredSafeArea(
>                child: Scaffold(
> -            endDrawer: _MobileResourceFilterSheet(),
> +            endDrawer: PveMobileResourceFilterSheet(),
>              appBar: AppBar(
>                automaticallyImplyLeading: false,
>                elevation: 0,
> @@ -844,178 +845,6 @@ class _AppbarSearchTextFieldState extends State<AppbarSearchTextField> {
>    }
>  }
>  
> -class _MobileResourceFilterSheet extends StatelessWidget {
> -  @override
> -  Widget build(BuildContext context) {
> -    final rBloc = Provider.of<PveResourceBloc>(context);
> -
> -    return ProxmoxStreamBuilder<PveResourceBloc, PveResourceState>(
> -      bloc: rBloc,
> -      builder: (context, state) => Drawer(
> -        child: SingleChildScrollView(
> -          child: Column(
> -            crossAxisAlignment: CrossAxisAlignment.start,
> -            children: <Widget>[
> -              Padding(
> -                padding: const EdgeInsets.fromLTRB(8.0, 20.0, 8.0, 0),
> -                child: ListTile(
> -                  title: const Text(
> -                    'Filter Results',
> -                  ),
> -                  trailing: rBloc.isFiltered
> -                      ? TextButton(
> -                          onPressed: () => rBloc.events.add(ResetFilter()),
> -                          child: Text(
> -                            'Reset',
> -                            style: TextStyle(
> -                              color: Theme.of(context).colorScheme.secondary,
> -                            ),
> -                          ),
> -                        )
> -                      : null,
> -                ),
> -              ),
> -              const Divider(
> -                indent: 0,
> -                endIndent: 0,
> -              ),
> -              Padding(
> -                padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
> -                child: Column(
> -                  children: [
> -                    const ListTile(
> -                      title: Text(
> -                        'Type',
> -                        style: TextStyle(fontWeight: FontWeight.bold),
> -                      ),
> -                    ),
> -                    CheckboxListTile(
> -                      dense: true,
> -                      title: Text(
> -                        'Nodes',
> -                        style: TextStyle(
> -                            color: Theme.of(context)
> -                                .colorScheme
> -                                .onSurface
> -                                .withValues(alpha: 0.75)),
> -                      ),
> -                      value: state.typeFilter.contains('node'),
> -                      onChanged: (v) => rBloc.events.add(FilterResources(
> -                        typeFilter: addOrRemove(v!, 'node', state.typeFilter),
> -                      )),
> -                    ),
> -                    CheckboxListTile(
> -                      dense: true,
> -                      title: Text(
> -                        'Qemu',
> -                        style: TextStyle(
> -                            color: Theme.of(context)
> -                                .colorScheme
> -                                .onSurface
> -                                .withValues(alpha: 0.75)),
> -                      ),
> -                      value: state.typeFilter.contains('qemu'),
> -                      onChanged: (v) => rBloc.events.add(FilterResources(
> -                        typeFilter: addOrRemove(v!, 'qemu', state.typeFilter),
> -                      )),
> -                    ),
> -                    CheckboxListTile(
> -                      dense: true,
> -                      title: Text(
> -                        'LXC',
> -                        style: TextStyle(
> -                            color: Theme.of(context)
> -                                .colorScheme
> -                                .onSurface
> -                                .withValues(alpha: 0.75)),
> -                      ),
> -                      value: state.typeFilter.contains('lxc'),
> -                      onChanged: (v) => rBloc.events.add(FilterResources(
> -                        typeFilter: addOrRemove(v!, 'lxc', state.typeFilter),
> -                      )),
> -                    ),
> -                    CheckboxListTile(
> -                      dense: true,
> -                      title: Text(
> -                        'Storage',
> -                        style: TextStyle(
> -                            color: Theme.of(context)
> -                                .colorScheme
> -                                .onSurface
> -                                .withValues(alpha: 0.75)),
> -                      ),
> -                      value: state.typeFilter.contains('storage'),
> -                      onChanged: (v) => rBloc.events.add(FilterResources(
> -                        typeFilter:
> -                            addOrRemove(v!, 'storage', state.typeFilter),
> -                      )),
> -                    ),
> -                  ],
> -                ),
> -              ),
> -              Padding(
> -                padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
> -                child: Column(
> -                  children: [
> -                    const ListTile(
> -                      title: Text(
> -                        'Status',
> -                        style: TextStyle(fontWeight: FontWeight.bold),
> -                      ),
> -                    ),
> -                    CheckboxListTile(
> -                      dense: true,
> -                      title: Text(
> -                        'Online',
> -                        style: TextStyle(
> -                            color: Theme.of(context)
> -                                .colorScheme
> -                                .onSurface
> -                                .withValues(alpha: 0.75)),
> -                      ),
> -                      value: state.statusFilter
> -                          .contains(PveResourceStatusType.running),
> -                      onChanged: (v) => rBloc.events.add(FilterResources(
> -                        statusFilter: addOrRemove(v!,
> -                            PveResourceStatusType.running, state.statusFilter),
> -                      )),
> -                    ),
> -                    CheckboxListTile(
> -                      dense: true,
> -                      title: Text(
> -                        'Offline',
> -                        style: TextStyle(
> -                            color: Theme.of(context)
> -                                .colorScheme
> -                                .onSurface
> -                                .withValues(alpha: 0.75)),
> -                      ),
> -                      value: state.statusFilter
> -                          .contains(PveResourceStatusType.stopped),
> -                      onChanged: (v) => rBloc.events.add(FilterResources(
> -                        statusFilter: addOrRemove(v!,
> -                            PveResourceStatusType.stopped, state.statusFilter),
> -                      )),
> -                    ),
> -                  ],
> -                ),
> -              )
> -            ],
> -          ),
> -        ),
> -      ),
> -    );
> -  }
> -
> -  BuiltSet<S> addOrRemove<S>(bool value, S element, BuiltSet<S> filter) {
> -    if (value) {
> -      return filter.rebuild((b) => b..add(element));
> -    } else {
> -      return filter.rebuild((b) => b..remove(element));
> -    }
> -  }
> -}
> -
>  class AppBarFilterIconButton extends StatelessWidget {
>    const AppBarFilterIconButton({super.key});
>  
> diff --git a/lib/widgets/pve_mobile_resource_filter_sheet.dart b/lib/widgets/pve_mobile_resource_filter_sheet.dart
> new file mode 100644
> index 0000000..cee3a49
> --- /dev/null
> +++ b/lib/widgets/pve_mobile_resource_filter_sheet.dart
> @@ -0,0 +1,188 @@
> +import 'package:built_collection/built_collection.dart';
> +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_resource_bloc.dart';
> +import 'package:pve_flutter_frontend/states/pve_resource_state.dart';
> +import 'package:pve_flutter_frontend/widgets/proxmox_stream_builder_widget.dart';
> +
> +class PveMobileResourceFilterSheet extends StatelessWidget {
> +  const PveMobileResourceFilterSheet({super.key});
> +
> +  @override
> +  Widget build(BuildContext context) {
> +    final rBloc = Provider.of<PveResourceBloc>(context);
> +    return ProxmoxStreamBuilder<PveResourceBloc, PveResourceState>(
> +      bloc: rBloc,
> +      builder: (context, state) => Drawer(
> +        child: SingleChildScrollView(
> +          child: Column(
> +            crossAxisAlignment: CrossAxisAlignment.start,
> +            children: [
> +              Padding(
> +                padding: const EdgeInsets.fromLTRB(8.0, 20.0, 8.0, 0),
> +                child: ListTile(
> +                  title: const Text(
> +                    'Filter Results',
> +                  ),
> +                  trailing: rBloc.isFiltered
> +                      ? TextButton(
> +                          onPressed: () => rBloc.events.add(ResetFilter()),
> +                          child: Text(
> +                            'Reset',
> +                            style: TextStyle(
> +                              color: Theme.of(context).colorScheme.secondary,
> +                            ),
> +                          ),
> +                        )
> +                      : null,
> +                ),
> +              ),
> +              const Divider(indent: 0, endIndent: 0),
> +              _PveFilterSheetSection(
> +                sectionTitle: 'Type',
> +                items: [
> +                  _ProxmoxResourceFilterListTile(
> +                    title: 'Nodes',
> +                    value: state.typeFilter.contains('node'),
> +                    onChanged: (v) => rBloc.events.add(
> +                      FilterResources(
> +                        typeFilter: _addOrRemove(v!, 'node', state.typeFilter),
> +                      ),
> +                    ),
> +                  ),
> +                  _ProxmoxResourceFilterListTile(
> +                    title: 'Qemu',
> +                    value: state.typeFilter.contains('qemu'),
> +                    onChanged: (v) => rBloc.events.add(
> +                      FilterResources(
> +                        typeFilter: _addOrRemove(v!, 'qemu', state.typeFilter),
> +                      ),
> +                    ),
> +                  ),
> +                  _ProxmoxResourceFilterListTile(
> +                    title: 'LXC',
> +                    value: state.typeFilter.contains('lxc'),
> +                    onChanged: (v) => rBloc.events.add(
> +                      FilterResources(
> +                        typeFilter: _addOrRemove(v!, 'lxc', state.typeFilter),
> +                      ),
> +                    ),
> +                  ),
> +                  _ProxmoxResourceFilterListTile(
> +                    title: 'Storage',
> +                    value: state.typeFilter.contains('storage'),
> +                    onChanged: (v) => rBloc.events.add(
> +                      FilterResources(
> +                        typeFilter:
> +                            _addOrRemove(v!, 'storage', state.typeFilter),
> +                      ),
> +                    ),
> +                  ),
> +                ],
> +              ),
> +              _PveFilterSheetSection(
> +                sectionTitle: 'Status',
> +                items: [
> +                  _ProxmoxResourceFilterListTile(
> +                    title: 'Online',
> +                    value: state.statusFilter
> +                        .contains(PveResourceStatusType.running),
> +                    onChanged: (v) => rBloc.events.add(
> +                      FilterResources(
> +                        statusFilter: _addOrRemove(
> +                          v!,
> +                          PveResourceStatusType.running,
> +                          state.statusFilter,
> +                        ),
> +                      ),
> +                    ),
> +                  ),
> +                  _ProxmoxResourceFilterListTile(
> +                    title: 'Offline',
> +                    value: state.statusFilter
> +                        .contains(PveResourceStatusType.stopped),
> +                    onChanged: (v) => rBloc.events.add(
> +                      FilterResources(
> +                        statusFilter: _addOrRemove(
> +                          v!,
> +                          PveResourceStatusType.stopped,
> +                          state.statusFilter,
> +                        ),
> +                      ),
> +                    ),
> +                  ),
> +                ],
> +              )
> +            ],
> +          ),
> +        ),
> +      ),
> +    );
> +  }
> +
> +  BuiltSet<S> _addOrRemove<S>(bool value, S element, BuiltSet<S> filter) {
> +    if (value) {
> +      return filter.rebuild((b) => b..add(element));
> +    } else {
> +      return filter.rebuild((b) => b..remove(element));
> +    }
> +  }
> +}
> +
> +class _PveFilterSheetSection extends StatelessWidget {
> +  const _PveFilterSheetSection({
> +    required this.items,
> +    required this.sectionTitle,
> +  });
> +
> +  final List<Widget> items;
> +  final String sectionTitle;
> +
> +  @override
> +  Widget build(BuildContext context) {
> +    return Padding(
> +      padding: const EdgeInsets.symmetric(horizontal: 8),
> +      child: Column(
> +        children: [
> +          ListTile(
> +            title: Text(
> +              sectionTitle,
> +              style: TextStyle(fontWeight: FontWeight.bold),
> +            ),
> +          ),
> +          ...items,
> +        ],
> +      ),
> +    );
> +  }
> +}
> +
> +class _ProxmoxResourceFilterListTile extends StatelessWidget {
> +  const _ProxmoxResourceFilterListTile({
> +    required this.title,
> +    this.onChanged,
> +    this.value,
> +  });
> +
> +  final String title;
> +  final ValueChanged<bool?>? onChanged;
> +  final bool? value;
> +
> +  @override
> +  Widget build(BuildContext context) {
> +    return CheckboxListTile(
> +      dense: true,
> +      title: Text(
> +        title,
> +        style: TextStyle(
> +          color: Theme.of(context).colorScheme.onSurface.withValues(
> +                alpha: 0.75,
> +              ),
> +        ),
> +      ),
> +      value: value,
> +      onChanged: onChanged,
> +    );
> +  }
> +}



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


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

* Re: [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused`
  2025-06-02 13:37 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Shan Shaji
                   ` (2 preceding siblings ...)
  2025-06-02 13:37 ` [pve-devel] [PATCH proxmox_dart_api_client v2 1/1] fix: ui: add missing `paused` status check Shan Shaji
@ 2025-06-03  8:15 ` Michael Köppl
  2025-06-05  9:46   ` Shan Shaji
  3 siblings, 1 reply; 8+ messages in thread
From: Michael Köppl @ 2025-06-03  8:15 UTC (permalink / raw)
  To: Proxmox VE development discussion, Shan Shaji

Thanks for tackling this! Definitely improves the UX. I tested this in
my Android emulator. Paused guests were displayed with the correct
status instead of "Unknown" and I was able to filter for the "Paused"
status. Did not notice anything off. Well done!

I left some minor comments on the individual patches. With those
addressed, consider this:

Reviewed-by: Michael Köppl <m.koeppl@proxmox.com>
Tested-by: Michael Köppl <m.koeppl@proxmox.com>

On 6/2/25 15:37, Shan Shaji wrote:
> This patch series includes the fix for guest missing when the status 
> is `paused`. Additionaly the series also includes the changes from 
> another patch which can be found here: 
> 
> https://lore.proxmox.com/pve-devel/20250522130825.79862-1-s.shaji@proxmox.com/
> 
> pve_flutter_frontend:
> 
> Shan Shaji (2):
>   refactor: move and split the `_MobileResourceFilterSheet` widget
>   fix: ui: guests missing in resources tab when status is `paused`
> 
>  lib/pages/main_layout_slim.dart               | 175 +--------------
>  .../pve_mobile_resource_filter_sheet.dart     | 202 ++++++++++++++++++
>  2 files changed, 204 insertions(+), 173 deletions(-)
>  create mode 100644 lib/widgets/pve_mobile_resource_filter_sheet.dart
> 
> 
> proxmox_dart_api_client:
> 
> Shan Shaji (1):
>   fix: ui: add missing `paused` status check
> 
>  lib/src/models/pve_cluster_resources_model.dart | 2 ++
>  1 file changed, 2 insertions(+)
> 
> 
> Summary over all repositories:
>   3 files changed, 206 insertions(+), 173 deletions(-)
> 



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

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

* Re: [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused`
  2025-06-03  8:15 ` [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Michael Köppl
@ 2025-06-05  9:46   ` Shan Shaji
  0 siblings, 0 replies; 8+ messages in thread
From: Shan Shaji @ 2025-06-05  9:46 UTC (permalink / raw)
  To: Michael Köppl, Proxmox VE development discussion

On Tue Jun 3, 2025 at 10:15 AM CEST, Michael Köppl wrote:
> Thanks for tackling this! Definitely improves the UX. I tested this in
> my Android emulator. Paused guests were displayed with the correct
> status instead of "Unknown" and I was able to filter for the "Paused"
> status. Did not notice anything off. Well done!
>
> I left some minor comments on the individual patches. With those
> addressed, consider this:

Superseeded by v3: https://lore.proxmox.com/pve-devel/20250605094118.93815-2-s.shaji@proxmox.com/T/#u




_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

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

end of thread, other threads:[~2025-06-05  9:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-02 13:37 [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Shan Shaji
2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 1/2] refactor: move and split the `_MobileResourceFilterSheet` widget Shan Shaji
2025-06-03  8:10   ` Michael Köppl
2025-06-02 13:37 ` [pve-devel] [PATCH pve_flutter_frontend v2 2/2] fix: ui: guests missing in resources tab when status is `paused` Shan Shaji
2025-06-03  8:02   ` Michael Köppl
2025-06-02 13:37 ` [pve-devel] [PATCH proxmox_dart_api_client v2 1/1] fix: ui: add missing `paused` status check Shan Shaji
2025-06-03  8:15 ` [pve-devel] [PATCH proxmox_dart_api_client/pve_flutter_frontend v2 0/3] fix: ui: guest missing in resources tab when status is `paused` Michael Köppl
2025-06-05  9:46   ` Shan Shaji

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