mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
Sp 1771 fe device name and subspace changes not reflected immediately after update on device management page (#313)
<!-- Thanks for contributing! Provide a description of your changes below and a general summary in the title Please look at the following checklist to ensure that your PR can be accepted quickly: --> ## Jira Ticket [SP-1771](https://syncrow.atlassian.net/browse/SP-1771) ## Description Synced state between settings and devices table. ## Type of Change <!--- Put an `x` in all the boxes that apply: --> - [ ] ✨ New feature (non-breaking change which adds functionality) - [x] 🛠️ Bug fix (non-breaking change which fixes an issue) - [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change) - [ ] 🧹 Code refactor - [ ] ✅ Build configuration change - [ ] 📝 Documentation - [ ] 🗑️ Chore [SP-1771]: https://syncrow.atlassian.net/browse/SP-1771?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
This commit is contained in:
@ -46,11 +46,11 @@ class AirQualityDistributionBloc
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onClearAirQualityDistribution(
|
||||
void _onClearAirQualityDistribution(
|
||||
ClearAirQualityDistribution event,
|
||||
Emitter<AirQualityDistributionState> emit,
|
||||
) async {
|
||||
emit(const AirQualityDistributionState());
|
||||
) {
|
||||
emit(AirQualityDistributionState(selectedAqiType: state.selectedAqiType));
|
||||
}
|
||||
|
||||
void _onUpdateAqiTypeEvent(
|
||||
|
@ -75,6 +75,6 @@ class RangeOfAqiBloc extends Bloc<RangeOfAqiEvent, RangeOfAqiState> {
|
||||
ClearRangeOfAqiEvent event,
|
||||
Emitter<RangeOfAqiState> emit,
|
||||
) {
|
||||
emit(const RangeOfAqiState());
|
||||
emit(RangeOfAqiState(selectedAqiType: state.selectedAqiType));
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ class AqiDistributionChartTitle extends StatelessWidget {
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
fit: BoxFit.scaleDown,
|
||||
child: AqiTypeDropdown(
|
||||
selectedAqiType: context.watch<AirQualityDistributionBloc>().state.selectedAqiType,
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
final bloc = context.read<AirQualityDistributionBloc>();
|
||||
|
@ -18,19 +18,20 @@ enum AqiType {
|
||||
}
|
||||
|
||||
class AqiTypeDropdown extends StatefulWidget {
|
||||
const AqiTypeDropdown({super.key, required this.onChanged});
|
||||
const AqiTypeDropdown({
|
||||
required this.onChanged,
|
||||
this.selectedAqiType,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final ValueChanged<AqiType?> onChanged;
|
||||
final AqiType? selectedAqiType;
|
||||
|
||||
@override
|
||||
State<AqiTypeDropdown> createState() => _AqiTypeDropdownState();
|
||||
}
|
||||
|
||||
class _AqiTypeDropdownState extends State<AqiTypeDropdown> {
|
||||
AqiType? _selectedItem = AqiType.aqi;
|
||||
|
||||
void _updateSelectedItem(AqiType? item) => setState(() => _selectedItem = item);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
@ -41,8 +42,8 @@ class _AqiTypeDropdownState extends State<AqiTypeDropdown> {
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: DropdownButton<AqiType?>(
|
||||
value: _selectedItem,
|
||||
child: DropdownButton<AqiType>(
|
||||
value: widget.selectedAqiType,
|
||||
isDense: true,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
dropdownColor: ColorsManager.whiteColors,
|
||||
@ -59,10 +60,7 @@ class _AqiTypeDropdownState extends State<AqiTypeDropdown> {
|
||||
items: AqiType.values
|
||||
.map((e) => DropdownMenuItem(value: e, child: Text(e.value)))
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
_updateSelectedItem(value);
|
||||
widget.onChanged(value);
|
||||
},
|
||||
onChanged: widget.onChanged,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -63,15 +63,15 @@ class RangeOfAqiChartTitle extends StatelessWidget {
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
child: AqiTypeDropdown(
|
||||
selectedAqiType: context.watch<RangeOfAqiBloc>().state.selectedAqiType,
|
||||
onChanged: (value) {
|
||||
final spaceTreeState = context.read<SpaceTreeBloc>().state;
|
||||
final spaceUuid = spaceTreeState.selectedSpaces.firstOrNull;
|
||||
|
||||
if (spaceUuid == null) return;
|
||||
|
||||
if (value != null) {
|
||||
context.read<RangeOfAqiBloc>().add(UpdateAqiTypeEvent(value));
|
||||
}
|
||||
|
||||
if (spaceUuid == null) return;
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -16,11 +16,12 @@ class DeviceManagementBloc
|
||||
int _onlineCount = 0;
|
||||
int _offlineCount = 0;
|
||||
int _lowBatteryCount = 0;
|
||||
List<AllDevicesModel> _selectedDevices = [];
|
||||
final List<AllDevicesModel> _selectedDevices = [];
|
||||
List<AllDevicesModel> _filteredDevices = [];
|
||||
String currentProductName = '';
|
||||
String? currentCommunity;
|
||||
String? currentUnitName;
|
||||
String subSpaceName = '';
|
||||
|
||||
DeviceManagementBloc() : super(DeviceManagementInitial()) {
|
||||
on<FetchDevices>(_onFetchDevices);
|
||||
@ -31,25 +32,26 @@ class DeviceManagementBloc
|
||||
on<ResetFilters>(_onResetFilters);
|
||||
on<ResetSelectedDevices>(_onResetSelectedDevices);
|
||||
on<UpdateSelection>(_onUpdateSelection);
|
||||
on<UpdateDeviceName>(_onUpdateDeviceName);
|
||||
on<UpdateSubSpaceName>(_onUpdateSubSpaceName);
|
||||
}
|
||||
|
||||
Future<void> _onFetchDevices(
|
||||
FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
||||
emit(DeviceManagementLoading());
|
||||
try {
|
||||
List<AllDevicesModel> devices = [];
|
||||
var devices = <AllDevicesModel>[];
|
||||
_devices.clear();
|
||||
var spaceBloc = event.context.read<SpaceTreeBloc>();
|
||||
final spaceBloc = event.context.read<SpaceTreeBloc>();
|
||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||
|
||||
if (spaceBloc.state.selectedCommunities.isEmpty) {
|
||||
devices =
|
||||
await DevicesManagementApi().fetchDevices('', '', projectUuid);
|
||||
devices = await DevicesManagementApi().fetchDevices('', '', projectUuid);
|
||||
} else {
|
||||
for (var community in spaceBloc.state.selectedCommunities) {
|
||||
List<String> spacesList =
|
||||
for (final community in spaceBloc.state.selectedCommunities) {
|
||||
final spacesList =
|
||||
spaceBloc.state.selectedCommunityAndSpaces[community] ?? [];
|
||||
for (var space in spacesList) {
|
||||
for (final space in spacesList) {
|
||||
devices.addAll(await DevicesManagementApi()
|
||||
.fetchDevices(community, space, projectUuid));
|
||||
}
|
||||
@ -74,7 +76,7 @@ class DeviceManagementBloc
|
||||
}
|
||||
}
|
||||
|
||||
void _onFilterDevices(
|
||||
Future<void> _onFilterDevices(
|
||||
FilterDevices event, Emitter<DeviceManagementState> emit) async {
|
||||
if (_devices.isNotEmpty) {
|
||||
_filteredDevices = List.from(_devices.where((device) {
|
||||
@ -156,8 +158,7 @@ class DeviceManagementBloc
|
||||
add(FilterDevices(_getFilterFromIndex(_selectedIndex)));
|
||||
}
|
||||
|
||||
void _onSelectDevice(
|
||||
SelectDevice event, Emitter<DeviceManagementState> emit) {
|
||||
void _onSelectDevice(SelectDevice event, Emitter<DeviceManagementState> emit) {
|
||||
final selectedUuid = event.selectedDevice.uuid;
|
||||
|
||||
if (_selectedDevices.any((device) => device.uuid == selectedUuid)) {
|
||||
@ -166,9 +167,9 @@ class DeviceManagementBloc
|
||||
_selectedDevices.add(event.selectedDevice);
|
||||
}
|
||||
|
||||
List<AllDevicesModel> clonedSelectedDevices = List.from(_selectedDevices);
|
||||
final clonedSelectedDevices = List<AllDevicesModel>.from(_selectedDevices);
|
||||
|
||||
bool isControlButtonEnabled =
|
||||
final isControlButtonEnabled =
|
||||
_checkIfControlButtonEnabled(clonedSelectedDevices);
|
||||
|
||||
if (state is DeviceManagementLoaded) {
|
||||
@ -198,8 +199,8 @@ class DeviceManagementBloc
|
||||
|
||||
void _onUpdateSelection(
|
||||
UpdateSelection event, Emitter<DeviceManagementState> emit) {
|
||||
List<AllDevicesModel> selectedDevices = [];
|
||||
List<AllDevicesModel> devicesToSelectFrom = [];
|
||||
final selectedDevices = <AllDevicesModel>[];
|
||||
var devicesToSelectFrom = <AllDevicesModel>[];
|
||||
|
||||
if (state is DeviceManagementLoaded) {
|
||||
devicesToSelectFrom = (state as DeviceManagementLoaded).devices;
|
||||
@ -207,7 +208,7 @@ class DeviceManagementBloc
|
||||
devicesToSelectFrom = (state as DeviceManagementFiltered).filteredDevices;
|
||||
}
|
||||
|
||||
for (int i = 0; i < event.selectedRows.length; i++) {
|
||||
for (var i = 0; i < event.selectedRows.length; i++) {
|
||||
if (event.selectedRows[i]) {
|
||||
selectedDevices.add(devicesToSelectFrom[i]);
|
||||
}
|
||||
@ -253,8 +254,7 @@ class DeviceManagementBloc
|
||||
_onlineCount = _devices.where((device) => device.online == true).length;
|
||||
_offlineCount = _devices.where((device) => device.online == false).length;
|
||||
_lowBatteryCount = _devices
|
||||
.where((device) =>
|
||||
device.batteryLevel != null && device.batteryLevel! < 20)
|
||||
.where((device) => device.batteryLevel != null && device.batteryLevel! < 20)
|
||||
.length;
|
||||
}
|
||||
|
||||
@ -270,8 +270,8 @@ class DeviceManagementBloc
|
||||
return 'All';
|
||||
}
|
||||
}
|
||||
void _onSearchDevices(
|
||||
SearchDevices event, Emitter<DeviceManagementState> emit) {
|
||||
|
||||
void _onSearchDevices(SearchDevices event, Emitter<DeviceManagementState> emit) {
|
||||
if ((event.community == null || event.community!.isEmpty) &&
|
||||
(event.unitName == null || event.unitName!.isEmpty) &&
|
||||
(event.deviceNameOrProductName == null ||
|
||||
@ -300,7 +300,7 @@ class DeviceManagementBloc
|
||||
currentCommunity = event.community;
|
||||
currentUnitName = event.unitName;
|
||||
|
||||
List<AllDevicesModel> devicesToSearch = _devices;
|
||||
final devicesToSearch = _devices;
|
||||
|
||||
if (devicesToSearch.isNotEmpty) {
|
||||
final searchText = event.deviceNameOrProductName?.toLowerCase() ?? '';
|
||||
@ -343,5 +343,134 @@ class DeviceManagementBloc
|
||||
}
|
||||
}
|
||||
|
||||
void _onUpdateDeviceName(
|
||||
UpdateDeviceName event, Emitter<DeviceManagementState> emit) {
|
||||
final devices = _devices.map((device) {
|
||||
if (device.uuid == event.deviceId) {
|
||||
final modifiedDevice = device.copyWith(name: event.newName);
|
||||
_selectedDevices.removeWhere((device) => device.uuid == event.deviceId);
|
||||
_selectedDevices.add(modifiedDevice);
|
||||
return modifiedDevice;
|
||||
}
|
||||
return device;
|
||||
}).toList();
|
||||
|
||||
final filteredDevices = _filteredDevices.map((device) {
|
||||
if (device.uuid == event.deviceId) {
|
||||
final modifiedDevice = device.copyWith(name: event.newName);
|
||||
_selectedDevices.removeWhere((device) => device.uuid == event.deviceId);
|
||||
_selectedDevices.add(modifiedDevice);
|
||||
return modifiedDevice;
|
||||
}
|
||||
return device;
|
||||
}).toList();
|
||||
|
||||
_devices = devices;
|
||||
_filteredDevices = filteredDevices;
|
||||
|
||||
if (state is DeviceManagementLoaded) {
|
||||
final loaded = state as DeviceManagementLoaded;
|
||||
final selectedDevices01 = _selectedDevices.map((device) {
|
||||
if (device.uuid == event.deviceId) {
|
||||
final modifiedDevice = device.copyWith(name: event.newName);
|
||||
return modifiedDevice;
|
||||
}
|
||||
return device;
|
||||
}).toList();
|
||||
emit(DeviceManagementLoaded(
|
||||
devices: devices,
|
||||
selectedIndex: loaded.selectedIndex,
|
||||
onlineCount: loaded.onlineCount,
|
||||
offlineCount: loaded.offlineCount,
|
||||
lowBatteryCount: loaded.lowBatteryCount,
|
||||
selectedDevice: selectedDevices01,
|
||||
isControlButtonEnabled: loaded.isControlButtonEnabled,
|
||||
));
|
||||
} else if (state is DeviceManagementFiltered) {
|
||||
final filtered = state as DeviceManagementFiltered;
|
||||
final selectedDevices01 = filtered.selectedDevice?.map((device) {
|
||||
if (device.uuid == event.deviceId) {
|
||||
final modifiedDevice = device.copyWith(name: event.newName);
|
||||
return modifiedDevice;
|
||||
}
|
||||
return device;
|
||||
}).toList();
|
||||
emit(DeviceManagementFiltered(
|
||||
filteredDevices: filteredDevices,
|
||||
selectedIndex: filtered.selectedIndex,
|
||||
onlineCount: filtered.onlineCount,
|
||||
offlineCount: filtered.offlineCount,
|
||||
lowBatteryCount: filtered.lowBatteryCount,
|
||||
selectedDevice: selectedDevices01,
|
||||
isControlButtonEnabled: filtered.isControlButtonEnabled,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void _onUpdateSubSpaceName(
|
||||
UpdateSubSpaceName event, Emitter<DeviceManagementState> emit) {
|
||||
final devices = _devices.map((device) {
|
||||
if (device.uuid == event.deviceId) {
|
||||
return device.copyWith(
|
||||
subspace:
|
||||
device.subspace?.copyWith(subspaceName: event.newSubSpaceName));
|
||||
}
|
||||
return device;
|
||||
}).toList();
|
||||
|
||||
final filteredDevices = _filteredDevices.map((device) {
|
||||
if (device.uuid == event.deviceId) {
|
||||
return device.copyWith(
|
||||
subspace:
|
||||
device.subspace?.copyWith(subspaceName: event.newSubSpaceName));
|
||||
}
|
||||
return device;
|
||||
}).toList();
|
||||
|
||||
_devices = devices;
|
||||
_filteredDevices = filteredDevices;
|
||||
|
||||
if (state is DeviceManagementLoaded) {
|
||||
final loaded = state as DeviceManagementLoaded;
|
||||
final selectedDevices = loaded.selectedDevice?.map((device) {
|
||||
if (device.uuid == event.deviceId) {
|
||||
return device.copyWith(
|
||||
subspace:
|
||||
device.subspace?.copyWith(subspaceName: event.newSubSpaceName));
|
||||
}
|
||||
return device;
|
||||
}).toList();
|
||||
emit(DeviceManagementLoaded(
|
||||
devices: _devices,
|
||||
selectedIndex: loaded.selectedIndex,
|
||||
onlineCount: loaded.onlineCount,
|
||||
offlineCount: loaded.offlineCount,
|
||||
lowBatteryCount: loaded.lowBatteryCount,
|
||||
selectedDevice: selectedDevices,
|
||||
isControlButtonEnabled: loaded.isControlButtonEnabled,
|
||||
));
|
||||
} else if (state is DeviceManagementFiltered) {
|
||||
// final filtered = state as DeviceManagementFiltered;
|
||||
// emit(DeviceManagementFiltered(
|
||||
// filteredDevices: _filteredDevices,
|
||||
// selectedIndex: filtered.selectedIndex,
|
||||
// onlineCount: filtered.onlineCount,
|
||||
// offlineCount: filtered.offlineCount,
|
||||
// lowBatteryCount: filtered.lowBatteryCount,
|
||||
// selectedDevice: filtered.selectedDevice,
|
||||
// isControlButtonEnabled: filtered.isControlButtonEnabled,
|
||||
// ));
|
||||
}
|
||||
}
|
||||
|
||||
void changeSubspaceName(
|
||||
String deviceId, String newSubSpaceName, String subspaceId) {
|
||||
add(UpdateSubSpaceName(
|
||||
deviceId: deviceId,
|
||||
newSubSpaceName: newSubSpaceName,
|
||||
subspaceId: subspaceId,
|
||||
));
|
||||
}
|
||||
|
||||
List<AllDevicesModel> get selectedDevices => _selectedDevices;
|
||||
}
|
||||
|
@ -70,3 +70,21 @@ class UpdateSelection extends DeviceManagementEvent {
|
||||
|
||||
const UpdateSelection(this.selectedRows);
|
||||
}
|
||||
|
||||
class UpdateDeviceName extends DeviceManagementEvent {
|
||||
final String deviceId;
|
||||
final String newName;
|
||||
|
||||
const UpdateDeviceName({required this.deviceId, required this.newName});
|
||||
}
|
||||
|
||||
class UpdateSubSpaceName extends DeviceManagementEvent {
|
||||
final String deviceId;
|
||||
final String newSubSpaceName;
|
||||
final String subspaceId;
|
||||
|
||||
const UpdateSubSpaceName(
|
||||
{required this.deviceId,
|
||||
required this.newSubSpaceName,
|
||||
required this.subspaceId});
|
||||
}
|
||||
|
@ -44,4 +44,20 @@ class DeviceSubspace {
|
||||
static List<Map<String, dynamic>> listToJson(List<DeviceSubspace> subspaces) {
|
||||
return subspaces.map((subspace) => subspace.toJson()).toList();
|
||||
}
|
||||
|
||||
DeviceSubspace copyWith({
|
||||
String? uuid,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
String? subspaceName,
|
||||
bool? disabled,
|
||||
}) {
|
||||
return DeviceSubspace(
|
||||
uuid: uuid ?? this.uuid,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
subspaceName: subspaceName ?? this.subspaceName,
|
||||
disabled: disabled ?? this.disabled,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -588,4 +588,72 @@ SOS
|
||||
"NCPS": DeviceType.NCPS,
|
||||
"PC": DeviceType.PC,
|
||||
};
|
||||
|
||||
AllDevicesModel copyWith({
|
||||
DevicesModelRoom? room,
|
||||
DeviceSubspace? subspace,
|
||||
DevicesModelUnit? unit,
|
||||
DeviceCommunityModel? community,
|
||||
String? productUuid,
|
||||
String? productType,
|
||||
String? permissionType,
|
||||
int? activeTime,
|
||||
String? category,
|
||||
String? categoryName,
|
||||
int? createTime,
|
||||
String? gatewayId,
|
||||
String? icon,
|
||||
String? ip,
|
||||
String? lat,
|
||||
String? localKey,
|
||||
String? lon,
|
||||
String? model,
|
||||
String? name,
|
||||
String? nodeId,
|
||||
bool? online,
|
||||
String? ownerId,
|
||||
bool? sub,
|
||||
String? timeZone,
|
||||
int? updateTime,
|
||||
String? uuid,
|
||||
int? batteryLevel,
|
||||
String? productName,
|
||||
List<DeviceSpaceModel>? spaces,
|
||||
List<DeviceTagModel>? deviceTags,
|
||||
DeviceSubSpace? deviceSubSpace,
|
||||
}) {
|
||||
return AllDevicesModel(
|
||||
room: room ?? this.room,
|
||||
subspace: subspace ?? this.subspace,
|
||||
unit: unit ?? this.unit,
|
||||
community: community ?? this.community,
|
||||
productUuid: productUuid ?? this.productUuid,
|
||||
productType: productType ?? this.productType,
|
||||
permissionType: permissionType ?? this.permissionType,
|
||||
activeTime: activeTime ?? this.activeTime,
|
||||
category: category ?? this.category,
|
||||
categoryName: categoryName ?? this.categoryName,
|
||||
createTime: createTime ?? this.createTime,
|
||||
gatewayId: gatewayId ?? this.gatewayId,
|
||||
icon: icon ?? this.icon,
|
||||
ip: ip ?? this.ip,
|
||||
lat: lat ?? this.lat,
|
||||
localKey: localKey ?? this.localKey,
|
||||
lon: lon ?? this.lon,
|
||||
model: model ?? this.model,
|
||||
name: name ?? this.name,
|
||||
nodeId: nodeId ?? this.nodeId,
|
||||
online: online ?? this.online,
|
||||
ownerId: ownerId ?? this.ownerId,
|
||||
sub: sub ?? this.sub,
|
||||
timeZone: timeZone ?? this.timeZone,
|
||||
updateTime: updateTime ?? this.updateTime,
|
||||
uuid: uuid ?? this.uuid,
|
||||
batteryLevel: batteryLevel ?? this.batteryLevel,
|
||||
productName: productName ?? this.productName,
|
||||
spaces: spaces ?? this.spaces,
|
||||
deviceTags: deviceTags ?? this.deviceTags,
|
||||
deviceSubSpace: deviceSubSpace ?? this.deviceSubSpace,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||
buildWhen: (previous, current) => previous != current,
|
||||
builder: (context, state) {
|
||||
List<AllDevicesModel> devicesToShow = [];
|
||||
int selectedIndex = 0;
|
||||
@ -31,7 +32,6 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
int lowBatteryCount = 0;
|
||||
bool isControlButtonEnabled = false;
|
||||
List<AllDevicesModel> selectedDevices = [];
|
||||
|
||||
if (state is DeviceManagementLoaded) {
|
||||
devicesToShow = state.devices;
|
||||
selectedIndex = state.selectedIndex;
|
||||
@ -192,7 +192,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
'Product Name',
|
||||
'Device ID',
|
||||
'Space Name',
|
||||
'location',
|
||||
'Location',
|
||||
'Battery Level',
|
||||
'Installation Date and Time',
|
||||
'Status',
|
||||
@ -244,7 +244,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
.map((device) => device.uuid!)
|
||||
.toList(),
|
||||
isEmpty: devicesToShow.isEmpty,
|
||||
onSettingsPressed: (rowIndex) {
|
||||
onSettingsPressed: (rowIndex) async {
|
||||
final device = devicesToShow[rowIndex];
|
||||
showDeviceSettingsSidebar(context, device);
|
||||
},
|
||||
@ -266,7 +266,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
barrierDismissible: true,
|
||||
barrierLabel: "Device Settings",
|
||||
transitionDuration: const Duration(milliseconds: 300),
|
||||
pageBuilder: (context, anim1, anim2) {
|
||||
pageBuilder: (_, anim1, anim2) {
|
||||
return Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Material(
|
||||
@ -276,6 +276,7 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
child: DeviceSettingsPanel(
|
||||
device: device,
|
||||
onClose: () => Navigator.of(context).pop(),
|
||||
deviceManagementBloc: context.read<DeviceManagementBloc>(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -19,11 +19,14 @@ class DeviceManagementContent extends StatelessWidget {
|
||||
required this.device,
|
||||
required this.subSpaces,
|
||||
required this.deviceInfo,
|
||||
required this.deviceManagementBloc,
|
||||
});
|
||||
|
||||
final AllDevicesModel device;
|
||||
final List<SubSpaceModel> subSpaces;
|
||||
final DeviceInfoModel deviceInfo;
|
||||
final DeviceManagementBloc deviceManagementBloc;
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -87,6 +90,11 @@ class DeviceManagementContent extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
deviceManagementBloc.add(UpdateSubSpaceName(
|
||||
subspaceId: selectedSubSpace.id!,
|
||||
deviceId: device.uuid!,
|
||||
newSubSpaceName: selectedSubSpace.name ?? ''));
|
||||
}
|
||||
},
|
||||
child: infoRow(
|
||||
|
@ -1,13 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/device_icon_type_helper.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/device_management_content.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/remove_device_widget.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/device_info_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/bloc/setting_bloc_state.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/device_setting/settings_model/sub_space_model.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
@ -17,7 +19,13 @@ import 'package:syncrow_web/web_layout/default_container.dart';
|
||||
class DeviceSettingsPanel extends StatelessWidget {
|
||||
final VoidCallback? onClose;
|
||||
final AllDevicesModel device;
|
||||
const DeviceSettingsPanel({super.key, this.onClose, required this.device});
|
||||
final DeviceManagementBloc deviceManagementBloc;
|
||||
const DeviceSettingsPanel({
|
||||
super.key,
|
||||
this.onClose,
|
||||
required this.device,
|
||||
required this.deviceManagementBloc,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -134,8 +142,14 @@ class DeviceSettingsPanel extends StatelessWidget {
|
||||
onFieldSubmitted: (value) {
|
||||
_bloc.add(const ChangeNameEvent(
|
||||
value: false));
|
||||
deviceManagementBloc
|
||||
..add(UpdateDeviceName(
|
||||
deviceId: device.uuid!,
|
||||
newName: _bloc
|
||||
.nameController
|
||||
.text))..add(ResetSelectedDevices());
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
decoration:const InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
@ -190,6 +204,7 @@ class DeviceSettingsPanel extends StatelessWidget {
|
||||
device: device,
|
||||
subSpaces: subSpaces.cast<SubSpaceModel>(),
|
||||
deviceInfo: deviceInfo,
|
||||
deviceManagementBloc: deviceManagementBloc,
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
RemoveDeviceWidget(bloc: _bloc),
|
||||
|
@ -2,10 +2,8 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||
import 'package:syncrow_web/pages/common/date_time_widget.dart';
|
||||
import 'package:syncrow_web/pages/common/text_field/custom_web_textfield.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_event.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_state.dart';
|
||||
@ -23,8 +21,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
var text = Theme.of(context)
|
||||
final size = MediaQuery.of(context).size;
|
||||
final text = Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(color: Colors.black, fontSize: 13);
|
||||
@ -41,8 +39,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
title: 'Sent Successfully',
|
||||
widgeta: Column(
|
||||
children: [
|
||||
if (visitorBloc
|
||||
.passwordStatus!.failedOperations.isNotEmpty)
|
||||
if (visitorBloc.passwordStatus!.failedOperations.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
const Text('Failed Devices'),
|
||||
@ -56,22 +53,19 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
.passwordStatus!.failedOperations.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
margin: EdgeInsets.all(5),
|
||||
margin: const EdgeInsets.all(5),
|
||||
decoration: containerDecoration,
|
||||
height: 45,
|
||||
child: Center(
|
||||
child: Text(visitorBloc
|
||||
.passwordStatus!
|
||||
.failedOperations[index]
|
||||
.deviceName)),
|
||||
child: Text(visitorBloc.passwordStatus!
|
||||
.failedOperations[index].deviceName)),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (visitorBloc
|
||||
.passwordStatus!.successOperations.isNotEmpty)
|
||||
if (visitorBloc.passwordStatus!.successOperations.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
const Text('Success Devices'),
|
||||
@ -85,14 +79,12 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
.passwordStatus!.successOperations.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
margin: EdgeInsets.all(5),
|
||||
margin: const EdgeInsets.all(5),
|
||||
decoration: containerDecoration,
|
||||
height: 45,
|
||||
child: Center(
|
||||
child: Text(visitorBloc
|
||||
.passwordStatus!
|
||||
.successOperations[index]
|
||||
.deviceName)),
|
||||
child: Text(visitorBloc.passwordStatus!
|
||||
.successOperations[index].deviceName)),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -115,16 +107,14 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
child: BlocBuilder<VisitorPasswordBloc, VisitorPasswordState>(
|
||||
builder: (BuildContext context, VisitorPasswordState state) {
|
||||
final visitorBloc = BlocProvider.of<VisitorPasswordBloc>(context);
|
||||
bool isRepeat =
|
||||
final isRepeat =
|
||||
state is IsRepeatState ? state.repeat : visitorBloc.repeat;
|
||||
return AlertDialog(
|
||||
backgroundColor: Colors.white,
|
||||
title: Text(
|
||||
'Create visitor password',
|
||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 24,
|
||||
color: Colors.black),
|
||||
fontWeight: FontWeight.w400, fontSize: 24, color: Colors.black),
|
||||
),
|
||||
content: state is LoadingInitialState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
@ -310,11 +300,9 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.add(SelectTimeEvent(
|
||||
context: context,
|
||||
isEffective: false));
|
||||
context: context, isEffective: false));
|
||||
} else {
|
||||
visitorBloc.add(
|
||||
SelectTimeVisitorPassword(
|
||||
visitorBloc.add(SelectTimeVisitorPassword(
|
||||
context: context,
|
||||
isStart: false,
|
||||
isRepeat: false));
|
||||
@ -326,31 +314,28 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.add(SelectTimeEvent(
|
||||
context: context,
|
||||
isEffective: true));
|
||||
context: context, isEffective: true));
|
||||
} else {
|
||||
visitorBloc.add(
|
||||
SelectTimeVisitorPassword(
|
||||
visitorBloc.add(SelectTimeVisitorPassword(
|
||||
context: context,
|
||||
isStart: true,
|
||||
isRepeat: false));
|
||||
}
|
||||
},
|
||||
firstString: (visitorBloc
|
||||
.usageFrequencySelected ==
|
||||
firstString:
|
||||
(visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password')
|
||||
? visitorBloc.effectiveTime
|
||||
: visitorBloc.startTimeAccess
|
||||
.toString(),
|
||||
: visitorBloc.startTimeAccess,
|
||||
secondString: (visitorBloc
|
||||
.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password')
|
||||
? visitorBloc.expirationTime
|
||||
: visitorBloc.endTimeAccess.toString(),
|
||||
: visitorBloc.endTimeAccess,
|
||||
icon: Assets.calendarIcon),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
@ -410,8 +395,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
child: CupertinoSwitch(
|
||||
value: visitorBloc.repeat,
|
||||
onChanged: (value) {
|
||||
visitorBloc
|
||||
.add(ToggleRepeatEvent());
|
||||
visitorBloc.add(ToggleRepeatEvent());
|
||||
},
|
||||
applyTheme: true,
|
||||
),
|
||||
@ -442,8 +426,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
},
|
||||
).then((listDevice) {
|
||||
if (listDevice != null) {
|
||||
visitorBloc.selectedDevices =
|
||||
listDevice;
|
||||
visitorBloc.selectedDevices = listDevice;
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -455,8 +438,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color:
|
||||
ColorsManager.whiteColors,
|
||||
color: ColorsManager.whiteColors,
|
||||
fontSize: 12),
|
||||
),
|
||||
),
|
||||
@ -495,37 +477,30 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
onPressed: () {
|
||||
if (visitorBloc.forgetFormKey.currentState!.validate()) {
|
||||
if (visitorBloc.selectedDevices.isNotEmpty) {
|
||||
if (visitorBloc.usageFrequencySelected ==
|
||||
'One-Time' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
setPasswordFunction(context, size, visitorBloc);
|
||||
} else if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
if (visitorBloc.expirationTime != 'End Time' &&
|
||||
visitorBloc.effectiveTime != 'Start Time') {
|
||||
setPasswordFunction(context, size, visitorBloc);
|
||||
} else {
|
||||
visitorBloc.stateDialog(
|
||||
context: context,
|
||||
message:
|
||||
'Please select Access Period to continue',
|
||||
message: 'Please select Access Period to continue',
|
||||
title: 'Access Period');
|
||||
}
|
||||
} else if (visitorBloc.endTimeAccess.toString() !=
|
||||
'End Time' &&
|
||||
visitorBloc.startTimeAccess.toString() !=
|
||||
'Start Time') {
|
||||
} else if (visitorBloc.endTimeAccess != 'End Time' &&
|
||||
visitorBloc.startTimeAccess != 'Start Time') {
|
||||
if (visitorBloc.effectiveTimeTimeStamp != null &&
|
||||
visitorBloc.expirationTimeTimeStamp != null) {
|
||||
if (isRepeat == true) {
|
||||
if (visitorBloc.expirationTime != 'End Time' &&
|
||||
visitorBloc.effectiveTime != 'Start Time' &&
|
||||
visitorBloc.selectedDays.isNotEmpty) {
|
||||
setPasswordFunction(
|
||||
context, size, visitorBloc);
|
||||
setPasswordFunction(context, size, visitorBloc);
|
||||
} else {
|
||||
visitorBloc.stateDialog(
|
||||
context: context,
|
||||
@ -539,15 +514,13 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
} else {
|
||||
visitorBloc.stateDialog(
|
||||
context: context,
|
||||
message:
|
||||
'Please select Access Period to continue',
|
||||
message: 'Please select Access Period to continue',
|
||||
title: 'Access Period');
|
||||
}
|
||||
} else {
|
||||
visitorBloc.stateDialog(
|
||||
context: context,
|
||||
message:
|
||||
'Please select Access Period to continue',
|
||||
message: 'Please select Access Period to continue',
|
||||
title: 'Access Period');
|
||||
}
|
||||
} else {
|
||||
@ -593,9 +566,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
alignment: Alignment.center,
|
||||
content: SizedBox(
|
||||
height: size.height * 0.25,
|
||||
child: Center(
|
||||
child:
|
||||
CircularProgressIndicator(), // Display a loading spinner
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(), // Display a loading spinner
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -619,10 +591,8 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
),
|
||||
Text(
|
||||
'Set Password',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineLarge!
|
||||
.copyWith(
|
||||
style:
|
||||
Theme.of(context).textTheme.headlineLarge!.copyWith(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black,
|
||||
@ -672,8 +642,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
if (visitorBloc.usageFrequencySelected == 'One-Time' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Online Password') {
|
||||
visitorBloc.accessTypeSelected == 'Online Password') {
|
||||
visitorBloc.add(OnlineOneTimePasswordEvent(
|
||||
context: context,
|
||||
passwordName: visitorBloc.userNameController.text,
|
||||
@ -681,8 +650,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
));
|
||||
} else if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Online Password') {
|
||||
visitorBloc.accessTypeSelected == 'Online Password') {
|
||||
visitorBloc.add(OnlineMultipleTimePasswordEvent(
|
||||
passwordName: visitorBloc.userNameController.text,
|
||||
email: visitorBloc.emailController.text,
|
||||
@ -693,8 +661,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
));
|
||||
} else if (visitorBloc.usageFrequencySelected ==
|
||||
'One-Time' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
visitorBloc.add(OfflineOneTimePasswordEvent(
|
||||
context: context,
|
||||
passwordName: visitorBloc.userNameController.text,
|
||||
@ -702,8 +669,7 @@ class VisitorPasswordDialog extends StatelessWidget {
|
||||
));
|
||||
} else if (visitorBloc.usageFrequencySelected ==
|
||||
'Periodic' &&
|
||||
visitorBloc.accessTypeSelected ==
|
||||
'Offline Password') {
|
||||
visitorBloc.accessTypeSelected == 'Offline Password') {
|
||||
visitorBloc.add(OfflineMultipleTimePasswordEvent(
|
||||
passwordName: visitorBloc.userNameController.text,
|
||||
email: visitorBloc.emailController.text,
|
||||
|
Reference in New Issue
Block a user