@override
_AppbarSearchTextFieldState createState() => _AppbarSearchTextFieldState();
}
@@ -844,178 +849,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..15b70f1
--- /dev/null
+++ b/lib/widgets/pve_mobile_resource_filter_sheet.dart
@@ -0,0 +1,215 @@
+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,
+ ),
+ ),
+ ),
+ ),
+ _ProxmoxResourceFilterListTile(
+ title: 'Paused',
+ value: state.statusFilter
+ .contains(PveResourceStatusType.paused),
+ onChanged: (v) => rBloc.events.add(
+ FilterResources(
+ statusFilter: _addOrRemove(
+ v!,
+ PveResourceStatusType.paused,
+ 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: [
+ _ProxmoxFilterSheetHeader(title: sectionTitle),
+ ...items,
+ ],
+ ),
+ );
+ }
+}
+
+class _ProxmoxFilterSheetHeader extends StatelessWidget {
+ const _ProxmoxFilterSheetHeader({
+ required this.title,
+ });
+
+ final String title;
+
+ @override
+ Widget build(BuildContext context) {
+ return ListTile(
+ title: Text(
+ title,
+ style: TextStyle(fontWeight: FontWeight.bold),
+ ),
+ );
+ }
+}