diff --git a/lib/pages/access_management/view/access_management.dart b/lib/pages/access_management/view/access_management.dart index 26a1dcc2..cebf2eae 100644 --- a/lib/pages/access_management/view/access_management.dart +++ b/lib/pages/access_management/view/access_management.dart @@ -82,6 +82,7 @@ class AccessManagementPage extends StatelessWidget with HelperResponsiveLayout { const SizedBox(height: 20), Expanded( child: DynamicTable( + uuidIndex: 0, isEmpty: filteredData.isEmpty, withCheckBox: false, size: MediaQuery.of(context).size, diff --git a/lib/pages/common/custom_table.dart b/lib/pages/common/custom_table.dart index 5308e450..a1532b68 100644 --- a/lib/pages/common/custom_table.dart +++ b/lib/pages/common/custom_table.dart @@ -14,6 +14,7 @@ class DynamicTable extends StatefulWidget { final void Function(bool?)? selectAll; final void Function(int, bool, dynamic)? onRowSelected; final List? initialSelectedIds; + final int uuidIndex; const DynamicTable({ super.key, required this.headers, @@ -26,6 +27,7 @@ class DynamicTable extends StatefulWidget { this.selectAll, this.onRowSelected, this.initialSelectedIds, + required this.uuidIndex, }); @override @@ -38,9 +40,24 @@ class _DynamicTableState extends State { @override void initState() { super.initState(); + _initializeSelection(); + } + + @override + void didUpdateWidget(DynamicTable oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.data != widget.data) { + _initializeSelection(); + } + } + + void _initializeSelection() { _selected = List.generate(widget.data.length, (index) { + // Check if the initialSelectedIds contains the deviceUuid + // uuidIndex is the index of the column containing the deviceUuid + final deviceUuid = widget.data[index][widget.uuidIndex]; return widget.initialSelectedIds != null && - widget.initialSelectedIds!.contains(widget.data[index][1]); + widget.initialSelectedIds!.contains(deviceUuid); }); } @@ -71,8 +88,7 @@ class _DynamicTableState extends State { children: [ if (widget.withCheckBox) _buildSelectAllCheckbox(), ...widget.headers - .map((header) => _buildTableHeaderCell(header)) - .toList(), + .map((header) => _buildTableHeaderCell(header)), ], ), ), @@ -119,11 +135,9 @@ class _DynamicTableState extends State { if (widget.withCheckBox) _buildRowCheckbox( index, widget.size.height * 0.10), - ...row - .map((cell) => _buildTableCell( - cell.toString(), - widget.size.height * 0.10)) - .toList(), + ...row.map((cell) => _buildTableCell( + cell.toString(), + widget.size.height * 0.10)), ], ); }, diff --git a/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart b/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart index d5ad921f..d64599f1 100644 --- a/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart +++ b/lib/pages/device_managment/all_devices/bloc/device_managment_bloc.dart @@ -28,11 +28,12 @@ class DeviceManagementBloc emit(DeviceManagementLoading()); try { final devices = await DevicesManagementApi().fetchDevices(); + _selectedDevices.clear(); _devices = devices; _calculateDeviceCounts(); emit(DeviceManagementLoaded( devices: devices, - selectedIndex: _selectedIndex, + selectedIndex: 0, onlineCount: _onlineCount, offlineCount: _offlineCount, lowBatteryCount: _lowBatteryCount, @@ -64,6 +65,8 @@ class DeviceManagementBloc onlineCount: _onlineCount, offlineCount: _offlineCount, lowBatteryCount: _lowBatteryCount, + selectedDevice: + _selectedDevices.isNotEmpty ? _selectedDevices.first : null, )); } } @@ -76,8 +79,10 @@ class DeviceManagementBloc void _onSelectDevice( SelectDevice event, Emitter emit) { - if (_selectedDevices.contains(event.selectedDevice)) { - _selectedDevices.remove(event.selectedDevice); + final selectedUuid = event.selectedDevice.uuid; + + if (_selectedDevices.any((device) => device.uuid == selectedUuid)) { + _selectedDevices.removeWhere((device) => device.uuid == selectedUuid); } else { _selectedDevices.add(event.selectedDevice); } @@ -130,6 +135,9 @@ class DeviceManagementBloc void _onSearchDevices( SearchDevices event, Emitter emit) { if (_devices.isNotEmpty) { + _selectedDevices.clear(); + _selectedIndex = 0; + final filteredDevices = _devices.where((device) { final matchesCommunity = event.community == null || event.community!.isEmpty || @@ -151,7 +159,6 @@ class DeviceManagementBloc false); return matchesCommunity && matchesUnit && matchesProductName; }).toList(); - _selectedDevices = []; emit(DeviceManagementFiltered( filteredDevices: filteredDevices, selectedIndex: 0, diff --git a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart index 2e9d916a..7f40bf37 100644 --- a/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart +++ b/lib/pages/device_managment/all_devices/widgets/device_managment_body.dart @@ -42,6 +42,10 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { offlineCount = state.offlineCount; lowBatteryCount = state.lowBatteryCount; isControlButtonEnabled = state.selectedDevice != null; + } else if (state is DeviceManagementInitial) { + devicesToShow = []; + selectedIndex = 0; + isControlButtonEnabled = false; } final tabs = [ @@ -125,6 +129,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { }, withCheckBox: true, size: context.screenSize, + uuidIndex: 2, headers: const [ 'Device Name', 'Product Name', @@ -153,10 +158,15 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout { (device.updateTime ?? 0) * 1000)), ]; }).toList(), + initialSelectedIds: context + .read() + .selectedDevices + .map((device) => device.uuid!) + .toList(), isEmpty: devicesToShow.isEmpty, ), ), - ), + ) ], ); }, diff --git a/lib/pages/home/bloc/home_bloc.dart b/lib/pages/home/bloc/home_bloc.dart index 79579efc..cc40b8fe 100644 --- a/lib/pages/home/bloc/home_bloc.dart +++ b/lib/pages/home/bloc/home_bloc.dart @@ -16,11 +16,11 @@ class HomeBloc extends Bloc { final BuchheimWalkerConfiguration builder = BuchheimWalkerConfiguration(); List sourcesList = []; List destinationsList = []; - static UserModel? user; + UserModel? user; HomeBloc() : super((HomeInitial())) { on(_createNode); - fetchUserInfo(); + on(_fetchUserInfo); } void _createNode(CreateNewNode event, Emitter emit) async { @@ -39,10 +39,12 @@ class HomeBloc extends Bloc { emit(HomeUpdateTree(graph: graph, builder: builder)); } - static Future fetchUserInfo() async { + Future _fetchUserInfo(FetchUserInfo event, Emitter emit) async { try { - var uuid = await const FlutterSecureStorage().read(key: UserModel.userUuidKey); + var uuid = + await const FlutterSecureStorage().read(key: UserModel.userUuidKey); user = await HomeApi().fetchUserInfo(uuid); + emit(HomeInitial()); } catch (e) { return; } diff --git a/lib/pages/home/bloc/home_event.dart b/lib/pages/home/bloc/home_event.dart index da517943..963202b9 100644 --- a/lib/pages/home/bloc/home_event.dart +++ b/lib/pages/home/bloc/home_event.dart @@ -17,3 +17,7 @@ class CreateNewNode extends HomeEvent { @override List get props => [sourceNode, destinationNode]; } + +class FetchUserInfo extends HomeEvent { + const FetchUserInfo(); +} \ No newline at end of file diff --git a/lib/pages/home/view/home_page.dart b/lib/pages/home/view/home_page.dart index 9159011f..75107e84 100644 --- a/lib/pages/home/view/home_page.dart +++ b/lib/pages/home/view/home_page.dart @@ -1,11 +1,25 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/home/bloc/home_bloc.dart'; +import 'package:syncrow_web/pages/home/bloc/home_event.dart'; import 'package:syncrow_web/pages/home/view/home_page_mobile.dart'; import 'package:syncrow_web/pages/home/view/home_page_web.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class HomePage extends StatelessWidget with HelperResponsiveLayout { +class HomePage extends StatefulWidget { const HomePage({super.key}); + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State with HelperResponsiveLayout { + @override + void initState() { + super.initState(); + context.read().add(const FetchUserInfo()); + } + @override Widget build(BuildContext context) { final isSmallScreen = isSmallScreenSize(context); diff --git a/lib/pages/home/view/home_page_mobile.dart b/lib/pages/home/view/home_page_mobile.dart index c0abdfe3..e8371cf2 100644 --- a/lib/pages/home/view/home_page_mobile.dart +++ b/lib/pages/home/view/home_page_mobile.dart @@ -10,6 +10,7 @@ import 'package:syncrow_web/web_layout/web_scaffold.dart'; class HomeMobilePage extends StatelessWidget { HomeMobilePage({super.key}); + @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; @@ -79,7 +80,7 @@ class HomeMobilePage extends StatelessWidget { ); } - dynamic homeItems = [ + final dynamic homeItems = [ { 'title': 'Access', 'icon': Assets.accessIcon, diff --git a/lib/pages/visitor_password/view/add_device_dialog.dart b/lib/pages/visitor_password/view/add_device_dialog.dart index 85262ff1..38b08f6c 100644 --- a/lib/pages/visitor_password/view/add_device_dialog.dart +++ b/lib/pages/visitor_password/view/add_device_dialog.dart @@ -184,6 +184,7 @@ class AddDeviceDialog extends StatelessWidget { }, withCheckBox: true, size: size * 0.5, + uuidIndex: 1, headers: const [ 'Device Name', 'Device ID', diff --git a/lib/web_layout/web_app_bar.dart b/lib/web_layout/web_app_bar.dart index 46b9c614..e63a329a 100644 --- a/lib/web_layout/web_app_bar.dart +++ b/lib/web_layout/web_app_bar.dart @@ -15,13 +15,14 @@ class WebAppBar extends StatelessWidget with HelperResponsiveLayout { @override Widget build(BuildContext context) { bool isSmallScreen = isSmallScreenSize(context); - + bool isHalfMediumScreen = isHafMediumScreenSize(context); return BlocBuilder(builder: (context, state) { + final user = context.read().user; return Container( - height: isSmallScreen ? 130 : 100, + height: (isSmallScreen || isHalfMediumScreen) ? 130 : 100, decoration: const BoxDecoration(color: ColorsManager.secondaryColor), padding: const EdgeInsets.all(10), - child: isSmallScreen + child: isSmallScreen || isHalfMediumScreen ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -31,14 +32,11 @@ class WebAppBar extends StatelessWidget with HelperResponsiveLayout { child: title!, ), if (centerBody != null) - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: const EdgeInsets.only(top: 8.0), - child: centerBody, - ), + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: centerBody, ), - if (rightBody != null || HomeBloc.user != null) + if (rightBody != null || user != null) Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -61,9 +59,9 @@ class WebAppBar extends StatelessWidget with HelperResponsiveLayout { const SizedBox( width: 10, ), - if (HomeBloc.user != null) + if (user != null) Text( - '${HomeBloc.user!.firstName} ${HomeBloc.user!.lastName}', + '${user.firstName} ${user.lastName}', style: Theme.of(context).textTheme.bodyLarge, ), ], @@ -78,14 +76,19 @@ class WebAppBar extends StatelessWidget with HelperResponsiveLayout { children: [ Align( alignment: Alignment.centerLeft, - child: title!, - ), - if (centerBody != null) - Expanded( - child: Center( - child: centerBody, + child: Expanded( + child: Row( + children: [ + title!, + if (centerBody != null) + Padding( + padding: const EdgeInsets.only(left: 80), + child: centerBody!, + ), + ], ), ), + ), Row( mainAxisSize: MainAxisSize.min, children: [ @@ -113,9 +116,9 @@ class WebAppBar extends StatelessWidget with HelperResponsiveLayout { const SizedBox( width: 10, ), - if (HomeBloc.user != null) + if (user != null) Text( - '${HomeBloc.user!.firstName} ${HomeBloc.user!.lastName}', + '${user.firstName} ${user.lastName}', style: Theme.of(context).textTheme.bodyLarge, ), ],