mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
@ -46,10 +46,9 @@ class CustomSearchBar extends StatelessWidget {
|
||||
filled: true,
|
||||
fillColor: ColorsManager.textFieldGreyColor,
|
||||
hintText: hintText,
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xB2999999),
|
||||
hintStyle: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||
color: ColorsManager.lightGrayColor,
|
||||
fontSize: 12,
|
||||
fontFamily: 'Aftika',
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 0,
|
||||
letterSpacing: -0.24,
|
25
lib/common/widgets/spaces_side_tree.dart
Normal file
25
lib/common/widgets/spaces_side_tree.dart
Normal file
@ -0,0 +1,25 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||
|
||||
class SpacesSideTree extends StatefulWidget {
|
||||
final List<CommunityModel> communities;
|
||||
final String? selectedSpaceUuid;
|
||||
const SpacesSideTree({
|
||||
super.key,
|
||||
required this.communities,
|
||||
this.selectedSpaceUuid,
|
||||
});
|
||||
|
||||
@override
|
||||
State<SpacesSideTree> createState() => _SpacesSideTreeState();
|
||||
}
|
||||
|
||||
class _SpacesSideTreeState extends State<SpacesSideTree> {
|
||||
String _searchQuery = '';
|
||||
String? _selectedSpaceUuid;
|
||||
String? _selectedId;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
@ -6,7 +6,9 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:syncrow_web/pages/auth/bloc/auth_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/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||
import 'package:syncrow_web/pages/visitor_password/bloc/visitor_password_bloc.dart';
|
||||
import 'package:syncrow_web/services/locator.dart';
|
||||
import 'package:syncrow_web/utils/app_routes.dart';
|
||||
@ -15,8 +17,7 @@ import 'package:syncrow_web/utils/theme/theme.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
try {
|
||||
const environment =
|
||||
String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
||||
const environment = String.fromEnvironment('FLAVOR', defaultValue: 'development');
|
||||
await dotenv.load(fileName: '.env.$environment');
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
initialSetup();
|
||||
@ -48,14 +49,16 @@ class MyApp extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||
BlocProvider(create: (context) => HomeBloc()..add(const FetchUserInfo())),
|
||||
BlocProvider<VisitorPasswordBloc>(
|
||||
create: (context) => VisitorPasswordBloc(),
|
||||
),
|
||||
BlocProvider<RoutineBloc>(
|
||||
create: (context) => RoutineBloc(),
|
||||
),
|
||||
BlocProvider<SpaceTreeBloc>(
|
||||
create: (context) => SpaceTreeBloc()..add(InitialEvent()),
|
||||
),
|
||||
],
|
||||
child: MaterialApp.router(
|
||||
debugShowCheckedModeBanner: false,
|
||||
|
@ -6,8 +6,7 @@ import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||
part 'device_managment_event.dart';
|
||||
part 'device_managment_state.dart';
|
||||
|
||||
class DeviceManagementBloc
|
||||
extends Bloc<DeviceManagementEvent, DeviceManagementState> {
|
||||
class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementState> {
|
||||
int _selectedIndex = 0;
|
||||
List<AllDevicesModel> _devices = [];
|
||||
int _onlineCount = 0;
|
||||
@ -30,11 +29,10 @@ class DeviceManagementBloc
|
||||
on<UpdateSelection>(_onUpdateSelection);
|
||||
}
|
||||
|
||||
Future<void> _onFetchDevices(
|
||||
FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
||||
Future<void> _onFetchDevices(FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
||||
emit(DeviceManagementLoading());
|
||||
try {
|
||||
final devices = await DevicesManagementApi().fetchDevices();
|
||||
final devices = await DevicesManagementApi().fetchDevices(event.communityId, event.spaceId);
|
||||
_selectedDevices.clear();
|
||||
_devices = devices;
|
||||
_filteredDevices = devices;
|
||||
@ -53,8 +51,7 @@ class DeviceManagementBloc
|
||||
}
|
||||
}
|
||||
|
||||
void _onFilterDevices(
|
||||
FilterDevices event, Emitter<DeviceManagementState> emit) async {
|
||||
void _onFilterDevices(FilterDevices event, Emitter<DeviceManagementState> emit) async {
|
||||
if (_devices.isNotEmpty) {
|
||||
_filteredDevices = List.from(_devices.where((device) {
|
||||
switch (event.filter) {
|
||||
@ -85,8 +82,7 @@ class DeviceManagementBloc
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onResetFilters(
|
||||
ResetFilters event, Emitter<DeviceManagementState> emit) async {
|
||||
Future<void> _onResetFilters(ResetFilters event, Emitter<DeviceManagementState> emit) async {
|
||||
currentProductName = '';
|
||||
_selectedDevices.clear();
|
||||
_filteredDevices = List.from(_devices);
|
||||
@ -102,8 +98,7 @@ class DeviceManagementBloc
|
||||
));
|
||||
}
|
||||
|
||||
void _onResetSelectedDevices(
|
||||
ResetSelectedDevices event, Emitter<DeviceManagementState> emit) {
|
||||
void _onResetSelectedDevices(ResetSelectedDevices event, Emitter<DeviceManagementState> emit) {
|
||||
_selectedDevices.clear();
|
||||
|
||||
if (state is DeviceManagementLoaded) {
|
||||
@ -129,14 +124,12 @@ class DeviceManagementBloc
|
||||
}
|
||||
}
|
||||
|
||||
void _onSelectedFilterChanged(
|
||||
SelectedFilterChanged event, Emitter<DeviceManagementState> emit) {
|
||||
void _onSelectedFilterChanged(SelectedFilterChanged event, Emitter<DeviceManagementState> emit) {
|
||||
_selectedIndex = event.selectedIndex;
|
||||
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)) {
|
||||
@ -147,8 +140,7 @@ class DeviceManagementBloc
|
||||
|
||||
List<AllDevicesModel> clonedSelectedDevices = List.from(_selectedDevices);
|
||||
|
||||
bool isControlButtonEnabled =
|
||||
_checkIfControlButtonEnabled(clonedSelectedDevices);
|
||||
bool isControlButtonEnabled = _checkIfControlButtonEnabled(clonedSelectedDevices);
|
||||
|
||||
if (state is DeviceManagementLoaded) {
|
||||
emit(DeviceManagementLoaded(
|
||||
@ -157,8 +149,7 @@ class DeviceManagementBloc
|
||||
onlineCount: _onlineCount,
|
||||
offlineCount: _offlineCount,
|
||||
lowBatteryCount: _lowBatteryCount,
|
||||
selectedDevice:
|
||||
clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null,
|
||||
selectedDevice: clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null,
|
||||
isControlButtonEnabled: isControlButtonEnabled,
|
||||
));
|
||||
} else if (state is DeviceManagementFiltered) {
|
||||
@ -168,15 +159,13 @@ class DeviceManagementBloc
|
||||
onlineCount: _onlineCount,
|
||||
offlineCount: _offlineCount,
|
||||
lowBatteryCount: _lowBatteryCount,
|
||||
selectedDevice:
|
||||
clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null,
|
||||
selectedDevice: clonedSelectedDevices.isNotEmpty ? clonedSelectedDevices : null,
|
||||
isControlButtonEnabled: isControlButtonEnabled,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void _onUpdateSelection(
|
||||
UpdateSelection event, Emitter<DeviceManagementState> emit) {
|
||||
void _onUpdateSelection(UpdateSelection event, Emitter<DeviceManagementState> emit) {
|
||||
List<AllDevicesModel> selectedDevices = [];
|
||||
List<AllDevicesModel> devicesToSelectFrom = [];
|
||||
|
||||
@ -219,8 +208,7 @@ class DeviceManagementBloc
|
||||
|
||||
bool _checkIfControlButtonEnabled(List<AllDevicesModel> selectedDevices) {
|
||||
if (selectedDevices.length > 1) {
|
||||
final productTypes =
|
||||
selectedDevices.map((device) => device.productType).toSet();
|
||||
final productTypes = selectedDevices.map((device) => device.productType).toSet();
|
||||
return productTypes.length == 1;
|
||||
} else if (selectedDevices.length == 1) {
|
||||
return true;
|
||||
@ -231,10 +219,8 @@ class DeviceManagementBloc
|
||||
void _calculateDeviceCounts() {
|
||||
_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)
|
||||
.length;
|
||||
_lowBatteryCount =
|
||||
_devices.where((device) => device.batteryLevel != null && device.batteryLevel! < 20).length;
|
||||
}
|
||||
|
||||
String _getFilterFromIndex(int index) {
|
||||
@ -250,8 +236,7 @@ class DeviceManagementBloc
|
||||
}
|
||||
}
|
||||
|
||||
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.productName == null || event.productName!.isEmpty)) {
|
||||
@ -280,33 +265,22 @@ class DeviceManagementBloc
|
||||
final filteredDevices = devicesToSearch.where((device) {
|
||||
final matchesCommunity = event.community == null ||
|
||||
event.community!.isEmpty ||
|
||||
(device.community?.name
|
||||
?.toLowerCase()
|
||||
.contains(event.community!.toLowerCase()) ??
|
||||
(device.community?.name?.toLowerCase().contains(event.community!.toLowerCase()) ??
|
||||
false);
|
||||
final matchesUnit = event.unitName == null ||
|
||||
event.unitName!.isEmpty ||
|
||||
(device.spaces != null &&
|
||||
device.spaces!.isNotEmpty &&
|
||||
device.spaces![0].spaceName
|
||||
!.toLowerCase()
|
||||
.contains(event.unitName!.toLowerCase()));
|
||||
device.spaces![0].spaceName!.toLowerCase().contains(event.unitName!.toLowerCase()));
|
||||
final matchesProductName = event.productName == null ||
|
||||
event.productName!.isEmpty ||
|
||||
(device.name
|
||||
?.toLowerCase()
|
||||
.contains(event.productName!.toLowerCase()) ??
|
||||
false);
|
||||
(device.name?.toLowerCase().contains(event.productName!.toLowerCase()) ?? false);
|
||||
final matchesDeviceName = event.productName == null ||
|
||||
event.productName!.isEmpty ||
|
||||
(device.categoryName
|
||||
?.toLowerCase()
|
||||
.contains(event.productName!.toLowerCase()) ??
|
||||
(device.categoryName?.toLowerCase().contains(event.productName!.toLowerCase()) ??
|
||||
false);
|
||||
|
||||
return matchesCommunity &&
|
||||
matchesUnit &&
|
||||
(matchesProductName || matchesDeviceName);
|
||||
return matchesCommunity && matchesUnit && (matchesProductName || matchesDeviceName);
|
||||
}).toList();
|
||||
|
||||
emit(DeviceManagementFiltered(
|
||||
|
@ -7,7 +7,14 @@ abstract class DeviceManagementEvent extends Equatable {
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class FetchDevices extends DeviceManagementEvent {}
|
||||
class FetchDevices extends DeviceManagementEvent {
|
||||
final String communityId;
|
||||
final String spaceId;
|
||||
|
||||
const FetchDevices(this.communityId, this.spaceId);
|
||||
@override
|
||||
List<Object?> get props => [communityId, spaceId];
|
||||
}
|
||||
|
||||
class FilterDevices extends DeviceManagementEvent {
|
||||
final String filter;
|
||||
|
@ -3,11 +3,11 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_spa
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_subspace.model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/one_gang_switch/one_gang_switch.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/three_gang_switch/three_gang_switch.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/two_gang_switch/two_gang_switch.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/ac/ac_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/enum/device_types.dart';
|
||||
|
||||
@ -148,9 +148,7 @@ class AllDevicesModel {
|
||||
|
||||
productName = json['productName']?.toString();
|
||||
if (json['spaces'] != null && json['spaces'] is List) {
|
||||
spaces = (json['spaces'] as List)
|
||||
.map((space) => DeviceSpaceModel.fromJson(space))
|
||||
.toList();
|
||||
spaces = (json['spaces'] as List).map((space) => DeviceSpaceModel.fromJson(space)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,8 +196,7 @@ SOS
|
||||
String tempIcon = '';
|
||||
if (type == DeviceType.LightBulb) {
|
||||
tempIcon = Assets.lightBulb;
|
||||
} else if (type == DeviceType.CeilingSensor ||
|
||||
type == DeviceType.WallSensor) {
|
||||
} else if (type == DeviceType.CeilingSensor || type == DeviceType.WallSensor) {
|
||||
tempIcon = Assets.sensors;
|
||||
} else if (type == DeviceType.AC) {
|
||||
tempIcon = Assets.ac;
|
||||
@ -254,34 +251,25 @@ SOS
|
||||
case '1G':
|
||||
return [
|
||||
OneGangSwitchFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
OneGangCountdownFunction(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
OneGangCountdownFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
];
|
||||
|
||||
case '2G':
|
||||
return [
|
||||
TwoGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
TwoGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
TwoGangCountdown1Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
TwoGangCountdown2Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
TwoGangCountdown1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
TwoGangCountdown2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
];
|
||||
|
||||
case '3G':
|
||||
return [
|
||||
ThreeGangSwitch1Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangSwitch2Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangSwitch3Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown1Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown2Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown3Function(
|
||||
deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangSwitch3Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
ThreeGangCountdown3Function(deviceId: uuid ?? '', deviceName: name ?? ''),
|
||||
];
|
||||
|
||||
default:
|
||||
|
@ -3,9 +3,9 @@ import 'package:flutter_bloc/flutter_bloc.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/widgets/device_managment_body.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/navigate_home_grid_view.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/view/create_new_routine_view.dart';
|
||||
import 'package:syncrow_web/pages/routiens/view/routines_view.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/view/create_new_routine_view.dart';
|
||||
import 'package:syncrow_web/pages/routines/view/routines_view.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
@ -19,7 +19,7 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
create: (context) => DeviceManagementBloc()..add(FetchDevices()),
|
||||
create: (context) => DeviceManagementBloc()..add(const FetchDevices('', '')),
|
||||
),
|
||||
],
|
||||
child: WebScaffold(
|
||||
@ -80,7 +80,7 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
||||
return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||
builder: (context, deviceState) {
|
||||
if (deviceState is DeviceManagementLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
return const DeviceManagementBody(devices: []);
|
||||
} else if (deviceState is DeviceManagementLoaded) {
|
||||
return DeviceManagementBody(devices: deviceState.devices);
|
||||
} else if (deviceState is DeviceManagementFiltered) {
|
||||
|
@ -8,6 +8,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_search_filters.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/device_control_dialog.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/view/side_tree_view.dart';
|
||||
import 'package:syncrow_web/utils/format_date_time.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
@ -59,10 +60,24 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
|
||||
final buttonLabel = (selectedDevices.length > 1) ? 'Batch Control' : 'Control';
|
||||
|
||||
return Column(
|
||||
return Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
child: SideTreeView(
|
||||
// onSelectAction: (String communityId, String spaceId) {
|
||||
// context.read<DeviceManagementBloc>().add(FetchDevices(communityId, spaceId));
|
||||
// },
|
||||
)),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: state is DeviceManagementLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: isLargeScreenSize(context) ? const EdgeInsets.all(30) : const EdgeInsets.all(15),
|
||||
padding: isLargeScreenSize(context)
|
||||
? const EdgeInsets.all(30)
|
||||
: const EdgeInsets.all(15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -71,7 +86,9 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
tabs: tabs,
|
||||
selectedIndex: selectedIndex,
|
||||
onTabChanged: (index) {
|
||||
context.read<DeviceManagementBloc>().add(SelectedFilterChanged(index));
|
||||
context
|
||||
.read<DeviceManagementBloc>()
|
||||
.add(SelectedFilterChanged(index));
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
@ -93,7 +110,9 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
),
|
||||
);
|
||||
} else if (selectedDevices.length > 1) {
|
||||
final productTypes = selectedDevices.map((device) => device.productType).toSet();
|
||||
final productTypes = selectedDevices
|
||||
.map((device) => device.productType)
|
||||
.toSet();
|
||||
if (productTypes.length == 1) {
|
||||
showDialog(
|
||||
context: context,
|
||||
@ -122,13 +141,17 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: isLargeScreenSize(context) ? const EdgeInsets.all(30) : const EdgeInsets.all(15),
|
||||
padding: isLargeScreenSize(context)
|
||||
? const EdgeInsets.all(30)
|
||||
: const EdgeInsets.all(15),
|
||||
child: DynamicTable(
|
||||
withSelectAll: true,
|
||||
cellDecoration: containerDecoration,
|
||||
onRowSelected: (index, isSelected, row) {
|
||||
final selectedDevice = devicesToShow[index];
|
||||
context.read<DeviceManagementBloc>().add(SelectDevice(selectedDevice));
|
||||
context
|
||||
.read<DeviceManagementBloc>()
|
||||
.add(SelectDevice(selectedDevice));
|
||||
},
|
||||
withCheckBox: true,
|
||||
size: MediaQuery.of(context).size,
|
||||
@ -147,31 +170,45 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
||||
data: devicesToShow.map((device) {
|
||||
final combinedSpaceNames = device.spaces != null
|
||||
? device.spaces!.map((space) => space.spaceName).join(' > ') +
|
||||
(device.community != null ? ' > ${device.community!.name}' : '')
|
||||
(device.community != null
|
||||
? ' > ${device.community!.name}'
|
||||
: '')
|
||||
: (device.community != null ? device.community!.name : '');
|
||||
|
||||
return [
|
||||
device.name ?? '',
|
||||
device.productName ?? '',
|
||||
device.uuid ?? '',
|
||||
(device.spaces != null && device.spaces!.isNotEmpty) ? device.spaces![0].spaceName : '',
|
||||
(device.spaces != null && device.spaces!.isNotEmpty)
|
||||
? device.spaces![0].spaceName
|
||||
: '',
|
||||
combinedSpaceNames,
|
||||
device.batteryLevel != null ? '${device.batteryLevel}%' : '-',
|
||||
formatDateTime(DateTime.fromMillisecondsSinceEpoch((device.createTime ?? 0) * 1000)),
|
||||
formatDateTime(DateTime.fromMillisecondsSinceEpoch(
|
||||
(device.createTime ?? 0) * 1000)),
|
||||
device.online == true ? 'Online' : 'Offline',
|
||||
formatDateTime(DateTime.fromMillisecondsSinceEpoch((device.updateTime ?? 0) * 1000)),
|
||||
formatDateTime(DateTime.fromMillisecondsSinceEpoch(
|
||||
(device.updateTime ?? 0) * 1000)),
|
||||
];
|
||||
}).toList(),
|
||||
onSelectionChanged: (selectedRows) {
|
||||
context.read<DeviceManagementBloc>().add(UpdateSelection(selectedRows));
|
||||
context
|
||||
.read<DeviceManagementBloc>()
|
||||
.add(UpdateSelection(selectedRows));
|
||||
},
|
||||
initialSelectedIds:
|
||||
context.read<DeviceManagementBloc>().selectedDevices.map((device) => device.uuid!).toList(),
|
||||
initialSelectedIds: context
|
||||
.read<DeviceManagementBloc>()
|
||||
.selectedDevices
|
||||
.map((device) => device.uuid!)
|
||||
.toList(),
|
||||
isEmpty: devicesToShow.isEmpty,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -12,8 +12,7 @@ class DeviceSearchFilters extends StatefulWidget {
|
||||
State<DeviceSearchFilters> createState() => _DeviceSearchFiltersState();
|
||||
}
|
||||
|
||||
class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
|
||||
with HelperResponsiveLayout {
|
||||
class _DeviceSearchFiltersState extends State<DeviceSearchFilters> with HelperResponsiveLayout {
|
||||
final TextEditingController communityController = TextEditingController();
|
||||
final TextEditingController unitNameController = TextEditingController();
|
||||
final TextEditingController productNameController = TextEditingController();
|
||||
@ -27,8 +26,7 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
|
||||
const SizedBox(width: 20),
|
||||
_buildSearchField("Space Name", unitNameController, 200),
|
||||
const SizedBox(width: 20),
|
||||
_buildSearchField(
|
||||
"Device Name / Product Name", productNameController, 300),
|
||||
_buildSearchField("Device Name / Product Name", productNameController, 300),
|
||||
const SizedBox(width: 20),
|
||||
_buildSearchResetButtons(),
|
||||
],
|
||||
@ -53,8 +51,7 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSearchField(
|
||||
String title, TextEditingController controller, double width) {
|
||||
Widget _buildSearchField(String title, TextEditingController controller, double width) {
|
||||
return Container(
|
||||
child: StatefulTextField(
|
||||
title: title,
|
||||
@ -88,7 +85,7 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
|
||||
productNameController.clear();
|
||||
context.read<DeviceManagementBloc>()
|
||||
..add(ResetFilters())
|
||||
..add(FetchDevices());
|
||||
..add(const FetchDevices('', ''));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1,49 +1,49 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:graphview/GraphView.dart';
|
||||
// import 'package:graphview/GraphView.dart';
|
||||
import 'package:syncrow_web/pages/auth/model/user_model.dart';
|
||||
import 'package:syncrow_web/pages/home/bloc/home_event.dart';
|
||||
import 'package:syncrow_web/pages/home/bloc/home_state.dart';
|
||||
import 'package:syncrow_web/pages/home/home_model/home_item_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/services/home_api.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/constants/routes_const.dart';
|
||||
|
||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||
final Graph graph = Graph()..isTree = true;
|
||||
final BuchheimWalkerConfiguration builder = BuchheimWalkerConfiguration();
|
||||
List<Node> sourcesList = [];
|
||||
List<Node> destinationsList = [];
|
||||
// final Graph graph = Graph()..isTree = true;
|
||||
// final BuchheimWalkerConfiguration builder = BuchheimWalkerConfiguration();
|
||||
// List<Node> sourcesList = [];
|
||||
// List<Node> destinationsList = [];
|
||||
UserModel? user;
|
||||
String terms = '';
|
||||
String policy = '';
|
||||
|
||||
HomeBloc() : super((HomeInitial())) {
|
||||
on<CreateNewNode>(_createNode);
|
||||
// on<CreateNewNode>(_createNode);
|
||||
on<FetchUserInfo>(_fetchUserInfo);
|
||||
on<FetchTermEvent>(_fetchTerms);
|
||||
on<FetchPolicyEvent>(_fetchPolicy);
|
||||
on<ConfirmUserAgreementEvent>(_confirmUserAgreement);
|
||||
}
|
||||
|
||||
void _createNode(CreateNewNode event, Emitter<HomeState> emit) async {
|
||||
emit(HomeInitial());
|
||||
sourcesList.add(event.sourceNode);
|
||||
destinationsList.add(event.destinationNode);
|
||||
for (int i = 0; i < sourcesList.length; i++) {
|
||||
graph.addEdge(sourcesList[i], destinationsList[i]);
|
||||
}
|
||||
// void _createNode(CreateNewNode event, Emitter<HomeState> emit) async {
|
||||
// emit(HomeInitial());
|
||||
// sourcesList.add(event.sourceNode);
|
||||
// destinationsList.add(event.destinationNode);
|
||||
// for (int i = 0; i < sourcesList.length; i++) {
|
||||
// graph.addEdge(sourcesList[i], destinationsList[i]);
|
||||
// }
|
||||
|
||||
builder
|
||||
..siblingSeparation = (100)
|
||||
..levelSeparation = (150)
|
||||
..subtreeSeparation = (150)
|
||||
..orientation = (BuchheimWalkerConfiguration.ORIENTATION_TOP_BOTTOM);
|
||||
emit(HomeUpdateTree(graph: graph, builder: builder));
|
||||
}
|
||||
// builder
|
||||
// ..siblingSeparation = (100)
|
||||
// ..levelSeparation = (150)
|
||||
// ..subtreeSeparation = (150)
|
||||
// ..orientation = (BuchheimWalkerConfiguration.ORIENTATION_TOP_BOTTOM);
|
||||
// emit(HomeUpdateTree(graph: graph, builder: builder));
|
||||
// }
|
||||
|
||||
Future _fetchUserInfo(FetchUserInfo event, Emitter<HomeState> emit) async {
|
||||
try {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:graphview/GraphView.dart';
|
||||
// import 'package:graphview/GraphView.dart';
|
||||
|
||||
abstract class HomeEvent extends Equatable {
|
||||
const HomeEvent();
|
||||
@ -8,19 +8,21 @@ abstract class HomeEvent extends Equatable {
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class CreateNewNode extends HomeEvent {
|
||||
final Node sourceNode;
|
||||
final Node destinationNode;
|
||||
const CreateNewNode(
|
||||
{required this.sourceNode, required this.destinationNode});
|
||||
// class CreateNewNode extends HomeEvent {
|
||||
// final Node sourceNode;
|
||||
// final Node destinationNode;
|
||||
// const CreateNewNode(
|
||||
// {required this.sourceNode, required this.destinationNode});
|
||||
|
||||
@override
|
||||
List<Object> get props => [sourceNode, destinationNode];
|
||||
}
|
||||
// @override
|
||||
// List<Object> get props => [sourceNode, destinationNode];
|
||||
// }
|
||||
|
||||
class FetchUserInfo extends HomeEvent {
|
||||
const FetchUserInfo();
|
||||
}class FetchTermEvent extends HomeEvent {}
|
||||
}
|
||||
|
||||
class FetchTermEvent extends HomeEvent {}
|
||||
|
||||
class FetchPolicyEvent extends HomeEvent {}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:graphview/GraphView.dart';
|
||||
// import 'package:graphview/GraphView.dart';
|
||||
|
||||
abstract class HomeState extends Equatable {
|
||||
const HomeState();
|
||||
@ -7,26 +7,26 @@ abstract class HomeState extends Equatable {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class LoadingHome extends HomeState {}
|
||||
|
||||
class HomeInitial extends HomeState {}
|
||||
|
||||
class TermsAgreement extends HomeState {}
|
||||
|
||||
class PolicyAgreement extends HomeState {}
|
||||
|
||||
class HomeCounterState extends HomeState {
|
||||
final int counter;
|
||||
const HomeCounterState(this.counter);
|
||||
}
|
||||
// class HomeCounterState extends HomeState {
|
||||
// final int counter;
|
||||
// const HomeCounterState(this.counter);
|
||||
// }
|
||||
|
||||
class HomeUpdateTree extends HomeState {
|
||||
final Graph graph;
|
||||
final BuchheimWalkerConfiguration builder;
|
||||
// class HomeUpdateTree extends HomeState {
|
||||
// final Graph graph;
|
||||
// final BuchheimWalkerConfiguration builder;
|
||||
|
||||
const HomeUpdateTree({required this.graph, required this.builder});
|
||||
// const HomeUpdateTree({required this.graph, required this.builder});
|
||||
|
||||
@override
|
||||
List<Object> get props => [graph, builder];
|
||||
}
|
||||
|
||||
//FetchTermEvent
|
||||
// @override
|
||||
// List<Object> get props => [graph, builder];
|
||||
// }
|
||||
|
@ -41,8 +41,7 @@ class HomeMobilePage extends StatelessWidget {
|
||||
SizedBox(height: size.height * 0.05),
|
||||
const Text(
|
||||
'ACCESS YOUR APPS',
|
||||
style:
|
||||
TextStyle(fontSize: 20, fontWeight: FontWeight.w700),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Expanded(
|
||||
@ -51,9 +50,8 @@ class HomeMobilePage extends StatelessWidget {
|
||||
height: size.height * 0.6,
|
||||
width: size.width * 0.68,
|
||||
child: GridView.builder(
|
||||
itemCount: 8,
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
itemCount: 3,
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 20.0,
|
||||
mainAxisSpacing: 20.0,
|
||||
@ -65,8 +63,7 @@ class HomeMobilePage extends StatelessWidget {
|
||||
active: homeItems[index]['active'],
|
||||
name: homeItems[index]['title'],
|
||||
img: homeItems[index]['icon'],
|
||||
onTap: () =>
|
||||
homeBloc.homeItems[index].onPress(context),
|
||||
onTap: () => homeBloc.homeItems[index].onPress(context),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -97,33 +94,33 @@ class HomeMobilePage extends StatelessWidget {
|
||||
'icon': Assets.devicesIcon,
|
||||
'active': true,
|
||||
},
|
||||
{
|
||||
'title': 'Move in',
|
||||
'icon': Assets.moveinIcon,
|
||||
'active': false,
|
||||
},
|
||||
{
|
||||
'title': 'Construction',
|
||||
'icon': Assets.constructionIcon,
|
||||
'active': false,
|
||||
},
|
||||
{
|
||||
'title': 'Energy',
|
||||
'icon': Assets.energyIcon,
|
||||
'color': ColorsManager.slidingBlueColor.withOpacity(0.2),
|
||||
'active': false,
|
||||
},
|
||||
{
|
||||
'title': 'Integrations',
|
||||
'icon': Assets.integrationsIcon,
|
||||
'color': ColorsManager.slidingBlueColor.withOpacity(0.2),
|
||||
'active': false,
|
||||
},
|
||||
{
|
||||
'title': 'Asset',
|
||||
'icon': Assets.assetIcon,
|
||||
'color': ColorsManager.slidingBlueColor.withOpacity(0.2),
|
||||
'active': false,
|
||||
},
|
||||
// {
|
||||
// 'title': 'Move in',
|
||||
// 'icon': Assets.moveinIcon,
|
||||
// 'active': false,
|
||||
// },
|
||||
// {
|
||||
// 'title': 'Construction',
|
||||
// 'icon': Assets.constructionIcon,
|
||||
// 'active': false,
|
||||
// },
|
||||
// {
|
||||
// 'title': 'Energy',
|
||||
// 'icon': Assets.energyIcon,
|
||||
// 'color': ColorsManager.slidingBlueColor.withOpacity(0.2),
|
||||
// 'active': false,
|
||||
// },
|
||||
// {
|
||||
// 'title': 'Integrations',
|
||||
// 'icon': Assets.integrationsIcon,
|
||||
// 'color': ColorsManager.slidingBlueColor.withOpacity(0.2),
|
||||
// 'active': false,
|
||||
// },
|
||||
// {
|
||||
// 'title': 'Asset',
|
||||
// 'icon': Assets.assetIcon,
|
||||
// 'color': ColorsManager.slidingBlueColor.withOpacity(0.2),
|
||||
// 'active': false,
|
||||
// },
|
||||
];
|
||||
}
|
||||
|
@ -58,7 +58,10 @@ class HomeWebPage extends StatelessWidget {
|
||||
scaffoldBody: SizedBox(
|
||||
height: size.height,
|
||||
width: size.width,
|
||||
child: Column(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
@ -78,9 +81,8 @@ class HomeWebPage extends StatelessWidget {
|
||||
width: size.width * 0.68,
|
||||
child: GridView.builder(
|
||||
itemCount: 3, //8
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 3, //4
|
||||
crossAxisSpacing: 20.0,
|
||||
mainAxisSpacing: 20.0,
|
||||
childAspectRatio: 1.5,
|
||||
@ -91,8 +93,7 @@ class HomeWebPage extends StatelessWidget {
|
||||
active: homeBloc.homeItems[index].active!,
|
||||
name: homeBloc.homeItems[index].title!,
|
||||
img: homeBloc.homeItems[index].icon!,
|
||||
onTap: () =>
|
||||
homeBloc.homeItems[index].onPress(context),
|
||||
onTap: () => homeBloc.homeItems[index].onPress(context),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -100,6 +101,8 @@ class HomeWebPage extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -1,185 +1,185 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:graphview/GraphView.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/bloc/home_state.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
// import 'package:graphview/GraphView.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/bloc/home_state.dart';
|
||||
|
||||
class TreeWidget extends StatelessWidget {
|
||||
const TreeWidget({super.key});
|
||||
// class TreeWidget extends StatelessWidget {
|
||||
// const TreeWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// final HomeBloc homeBloc = BlocProvider.of<HomeBloc>(context);
|
||||
String firstNodeName = '';
|
||||
String secondNodeName = '';
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// // final HomeBloc homeBloc = BlocProvider.of<HomeBloc>(context);
|
||||
// String firstNodeName = '';
|
||||
// String secondNodeName = '';
|
||||
|
||||
return SafeArea(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
alignment: AlignmentDirectional.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
BlocBuilder<HomeBloc, HomeState>(builder: (context, state) {
|
||||
if (state is HomeInitial) {
|
||||
return Wrap(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: TextFormField(
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Subtree separation"),
|
||||
onChanged: (text) {
|
||||
firstNodeName = text;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Container(
|
||||
width: 100,
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(labelText: "Node Name"),
|
||||
onChanged: (text) {
|
||||
secondNodeName = text;
|
||||
},
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
final node1 = Node.Id(firstNodeName);
|
||||
final node2 = Node.Id(secondNodeName);
|
||||
context.read<HomeBloc>().add(CreateNewNode(
|
||||
sourceNode: node1, destinationNode: node2));
|
||||
},
|
||||
child: Text("Add"),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
if (state is HomeUpdateTree) {
|
||||
return Expanded(
|
||||
child: InteractiveViewer(
|
||||
constrained: false,
|
||||
boundaryMargin: const EdgeInsets.all(100),
|
||||
minScale: 0.01,
|
||||
maxScale: 5.6,
|
||||
child: GraphView(
|
||||
graph: state.graph,
|
||||
algorithm: BuchheimWalkerAlgorithm(
|
||||
state.builder, TreeEdgeRenderer(state.builder)),
|
||||
paint: Paint()
|
||||
..color = Colors.green
|
||||
..strokeWidth = 1
|
||||
..style = PaintingStyle.stroke,
|
||||
builder: (Node node) {
|
||||
// I can decide what widget should be shown here based on the id
|
||||
var nodeName = node.key!.value;
|
||||
return rectangleWidget(nodeName, node, context);
|
||||
},
|
||||
)),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
})
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
// return SafeArea(
|
||||
// child: Container(
|
||||
// padding: const EdgeInsets.all(24),
|
||||
// width: MediaQuery.sizeOf(context).width,
|
||||
// height: MediaQuery.sizeOf(context).height,
|
||||
// alignment: AlignmentDirectional.center,
|
||||
// child: Column(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// BlocBuilder<HomeBloc, HomeState>(builder: (context, state) {
|
||||
// if (state is HomeInitial) {
|
||||
// return Wrap(
|
||||
// children: [
|
||||
// SizedBox(
|
||||
// width: 100,
|
||||
// child: TextFormField(
|
||||
// decoration: const InputDecoration(
|
||||
// labelText: "Subtree separation"),
|
||||
// onChanged: (text) {
|
||||
// firstNodeName = text;
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(
|
||||
// width: 8,
|
||||
// ),
|
||||
// Container(
|
||||
// width: 100,
|
||||
// child: TextFormField(
|
||||
// decoration: InputDecoration(labelText: "Node Name"),
|
||||
// onChanged: (text) {
|
||||
// secondNodeName = text;
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// final node1 = Node.Id(firstNodeName);
|
||||
// final node2 = Node.Id(secondNodeName);
|
||||
// context.read<HomeBloc>().add(CreateNewNode(
|
||||
// sourceNode: node1, destinationNode: node2));
|
||||
// },
|
||||
// child: Text("Add"),
|
||||
// )
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
// if (state is HomeUpdateTree) {
|
||||
// return Expanded(
|
||||
// child: InteractiveViewer(
|
||||
// constrained: false,
|
||||
// boundaryMargin: const EdgeInsets.all(100),
|
||||
// minScale: 0.01,
|
||||
// maxScale: 5.6,
|
||||
// child: GraphView(
|
||||
// graph: state.graph,
|
||||
// algorithm: BuchheimWalkerAlgorithm(
|
||||
// state.builder, TreeEdgeRenderer(state.builder)),
|
||||
// paint: Paint()
|
||||
// ..color = Colors.green
|
||||
// ..strokeWidth = 1
|
||||
// ..style = PaintingStyle.stroke,
|
||||
// builder: (Node node) {
|
||||
// // I can decide what widget should be shown here based on the id
|
||||
// var nodeName = node.key!.value;
|
||||
// return rectangleWidget(nodeName, node, context);
|
||||
// },
|
||||
// )),
|
||||
// );
|
||||
// } else {
|
||||
// return Container();
|
||||
// }
|
||||
// })
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
Widget rectangleWidget(String text, Node node, BuildContext blocContext) {
|
||||
String nodeName = '';
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: blocContext,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('Add a child'),
|
||||
content: TextField(
|
||||
decoration:
|
||||
const InputDecoration(hintText: 'Enter your text here'),
|
||||
onChanged: (value) {
|
||||
nodeName = value;
|
||||
},
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Close'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
if (nodeName.isNotEmpty) {
|
||||
final newNode = Node.Id(nodeName);
|
||||
blocContext.read<HomeBloc>().add(CreateNewNode(
|
||||
sourceNode: node, destinationNode: newNode));
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Add'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: MediaQuery.of(blocContext).size.width * 0.2,
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
|
||||
padding: EdgeInsets.all(20.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
child: Icon(
|
||||
Icons.location_on,
|
||||
color: Colors.blue,
|
||||
size: 40.0,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10.0),
|
||||
SizedBox(
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
fontSize: 24.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Container(
|
||||
child: const Icon(
|
||||
Icons.add_circle_outline,
|
||||
color: Colors.grey,
|
||||
size: 24.0,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
// Widget rectangleWidget(String text, Node node, BuildContext blocContext) {
|
||||
// String nodeName = '';
|
||||
// return InkWell(
|
||||
// onTap: () {
|
||||
// showDialog(
|
||||
// context: blocContext,
|
||||
// builder: (BuildContext context) {
|
||||
// return AlertDialog(
|
||||
// title: const Text('Add a child'),
|
||||
// content: TextField(
|
||||
// decoration:
|
||||
// const InputDecoration(hintText: 'Enter your text here'),
|
||||
// onChanged: (value) {
|
||||
// nodeName = value;
|
||||
// },
|
||||
// ),
|
||||
// actions: <Widget>[
|
||||
// TextButton(
|
||||
// onPressed: () {
|
||||
// Navigator.of(context).pop();
|
||||
// },
|
||||
// child: Text('Close'),
|
||||
// ),
|
||||
// TextButton(
|
||||
// onPressed: () {
|
||||
// if (nodeName.isNotEmpty) {
|
||||
// final newNode = Node.Id(nodeName);
|
||||
// blocContext.read<HomeBloc>().add(CreateNewNode(
|
||||
// sourceNode: node, destinationNode: newNode));
|
||||
// }
|
||||
// Navigator.of(context).pop();
|
||||
// },
|
||||
// child: Text('Add'),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// },
|
||||
// );
|
||||
// },
|
||||
// child: Container(
|
||||
// width: MediaQuery.of(blocContext).size.width * 0.2,
|
||||
// margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
|
||||
// padding: EdgeInsets.all(20.0),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// borderRadius: BorderRadius.circular(10.0),
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: Colors.grey.withOpacity(0.5),
|
||||
// spreadRadius: 2,
|
||||
// blurRadius: 5,
|
||||
// offset: Offset(0, 3), // changes position of shadow
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// const SizedBox(
|
||||
// child: Icon(
|
||||
// Icons.location_on,
|
||||
// color: Colors.blue,
|
||||
// size: 40.0,
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(width: 10.0),
|
||||
// SizedBox(
|
||||
// child: Text(
|
||||
// text,
|
||||
// style: const TextStyle(
|
||||
// fontSize: 24.0,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// const Spacer(),
|
||||
// Container(
|
||||
// child: const Icon(
|
||||
// Icons.add_circle_outline,
|
||||
// color: Colors.grey,
|
||||
// size: 24.0,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
@ -1,85 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/ac_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/one_gang_switch_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/three_gang_switch_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/two_gang_switch_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
|
||||
class DeviceDialogHelper {
|
||||
static Future<Map<String, dynamic>?> showDeviceDialog(
|
||||
BuildContext context,
|
||||
Map<String, dynamic> data, {
|
||||
required bool removeComparetors,
|
||||
}) async {
|
||||
final functions = data['functions'] as List<DeviceFunction>;
|
||||
|
||||
try {
|
||||
final result = await _getDialogForDeviceType(
|
||||
context,
|
||||
data['productType'],
|
||||
data,
|
||||
functions,
|
||||
removeComparetors: removeComparetors,
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Error: $e');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>?> _getDialogForDeviceType(
|
||||
BuildContext context,
|
||||
String productType,
|
||||
Map<String, dynamic> data,
|
||||
List<DeviceFunction> functions,
|
||||
{required bool removeComparetors}) async {
|
||||
final routineBloc = context.read<RoutineBloc>();
|
||||
final deviceSelectedFunctions =
|
||||
routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? [];
|
||||
|
||||
switch (productType) {
|
||||
case 'AC':
|
||||
return ACHelper.showACFunctionsDialog(
|
||||
context,
|
||||
functions,
|
||||
data['device'],
|
||||
deviceSelectedFunctions,
|
||||
data['uniqueCustomId'],
|
||||
removeComparetors);
|
||||
|
||||
case '1G':
|
||||
return OneGangSwitchHelper.showSwitchFunctionsDialog(
|
||||
context,
|
||||
functions,
|
||||
data['device'],
|
||||
deviceSelectedFunctions,
|
||||
data['uniqueCustomId'],
|
||||
removeComparetors);
|
||||
case '2G':
|
||||
return TwoGangSwitchHelper.showSwitchFunctionsDialog(
|
||||
context,
|
||||
functions,
|
||||
data['device'],
|
||||
deviceSelectedFunctions,
|
||||
data['uniqueCustomId'],
|
||||
removeComparetors);
|
||||
case '3G':
|
||||
return ThreeGangSwitchHelper.showSwitchFunctionsDialog(
|
||||
context,
|
||||
functions,
|
||||
data['device'],
|
||||
deviceSelectedFunctions,
|
||||
data['uniqueCustomId'],
|
||||
removeComparetors);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/view/create_new_routine_view.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/fetch_routine_scenes_automation.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/routine_view_card.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class RoutinesView extends StatefulWidget {
|
||||
const RoutinesView({super.key});
|
||||
|
||||
@override
|
||||
State<RoutinesView> createState() => _RoutinesViewState();
|
||||
}
|
||||
|
||||
class _RoutinesViewState extends State<RoutinesView> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<RoutineBloc>().add(FetchDevicesInRoutine());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, state) {
|
||||
if (state.createRoutineView) {
|
||||
return const CreateNewRoutineView();
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Create New Routines",
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
RoutineViewCard(
|
||||
onTap: () {
|
||||
context.read<RoutineBloc>().add(
|
||||
(ResetRoutineState()),
|
||||
);
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(createRoutineView: true),
|
||||
);
|
||||
},
|
||||
icon: Icons.add,
|
||||
textString: '',
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
const Expanded(child: FetchRoutineScenesAutomation()),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/main_routine_view/routine_view_card.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class FetchRoutineScenesAutomation extends StatefulWidget {
|
||||
const FetchRoutineScenesAutomation({super.key});
|
||||
|
||||
@override
|
||||
State<FetchRoutineScenesAutomation> createState() => _FetchRoutineScenesState();
|
||||
}
|
||||
|
||||
class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
||||
with HelperResponsiveLayout {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<RoutineBloc>()
|
||||
..add(const LoadScenes(spaceId, communityId))
|
||||
..add(const LoadAutomation(spaceId));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, state) {
|
||||
return state.isLoading
|
||||
? const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"Scenes (Tab to Run)",
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
if (state.scenes.isEmpty)
|
||||
Text(
|
||||
"No scenes found",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
if (state.scenes.isNotEmpty)
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: isSmallScreenSize(context) ? 160 : 170,
|
||||
),
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: state.scenes.length,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||
),
|
||||
child: RoutineViewCard(
|
||||
onTap: () {
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(createRoutineView: true),
|
||||
);
|
||||
context.read<RoutineBloc>().add(
|
||||
GetSceneDetails(
|
||||
sceneId: state.scenes[index].id,
|
||||
isTabToRun: true,
|
||||
isUpdate: true,
|
||||
),
|
||||
);
|
||||
},
|
||||
textString: state.scenes[index].name,
|
||||
icon: state.scenes[index].icon ?? Assets.logoHorizontal,
|
||||
isFromScenes: true,
|
||||
iconInBytes: state.scenes[index].iconInBytes,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Text(
|
||||
"Automations",
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
if (state.automations.isEmpty)
|
||||
Text(
|
||||
"No automations found",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
if (state.automations.isNotEmpty)
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: isSmallScreenSize(context) ? 160 : 170,
|
||||
),
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: state.automations.length,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||
),
|
||||
child: RoutineViewCard(
|
||||
onTap: () {
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(createRoutineView: true),
|
||||
);
|
||||
context.read<RoutineBloc>().add(
|
||||
GetAutomationDetails(
|
||||
automationId: state.automations[index].id,
|
||||
isAutomation: true,
|
||||
isUpdate: true),
|
||||
);
|
||||
},
|
||||
textString: state.automations[index].name,
|
||||
icon: state.automations[index].icon ?? Assets.automation,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_web/utils/constants/app_enum.dart';
|
||||
|
||||
class EffectPeriodBloc extends Bloc<EffectPeriodEvent, EffectPeriodState> {
|
@ -1,5 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/utils/constants/app_enum.dart';
|
||||
|
||||
abstract class EffectPeriodEvent extends Equatable {
|
@ -2,7 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
|
||||
part 'functions_bloc_event.dart';
|
||||
part 'functions_bloc_state.dart';
|
||||
@ -26,8 +26,7 @@ class FunctionBloc extends Bloc<FunctionBlocEvent, FunctionBlocState> {
|
||||
functionCode: event.functionData.functionCode,
|
||||
operationName: event.functionData.operationName,
|
||||
value: event.functionData.value ?? existingData.value,
|
||||
valueDescription: event.functionData.valueDescription ??
|
||||
existingData.valueDescription,
|
||||
valueDescription: event.functionData.valueDescription ?? existingData.valueDescription,
|
||||
condition: event.functionData.condition ?? existingData.condition,
|
||||
);
|
||||
} else {
|
||||
@ -59,10 +58,8 @@ class FunctionBloc extends Bloc<FunctionBlocEvent, FunctionBlocState> {
|
||||
);
|
||||
}
|
||||
|
||||
FutureOr<void> _onSelectFunction(
|
||||
SelectFunction event, Emitter<FunctionBlocState> emit) {
|
||||
FutureOr<void> _onSelectFunction(SelectFunction event, Emitter<FunctionBlocState> emit) {
|
||||
emit(state.copyWith(
|
||||
selectedFunction: event.functionCode,
|
||||
selectedOperationName: event.operationName));
|
||||
selectedFunction: event.functionCode, selectedOperationName: event.operationName));
|
||||
}
|
||||
}
|
@ -4,12 +4,12 @@ import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/delay/delay_fucntions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/routine_details_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/delay/delay_fucntions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/routine_details_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/routine_model.dart';
|
||||
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||
import 'package:syncrow_web/services/routines_api.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
@ -19,8 +19,8 @@ import 'package:uuid/uuid.dart';
|
||||
part 'routine_event.dart';
|
||||
part 'routine_state.dart';
|
||||
|
||||
const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
||||
const communityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9';
|
||||
String spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
||||
String communityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9';
|
||||
|
||||
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
RoutineBloc() : super(const RoutineState()) {
|
||||
@ -57,8 +57,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
emit(state.copyWith(routineTab: event.isRoutineTab, createRoutineView: false));
|
||||
add(ResetRoutineState());
|
||||
if (event.isRoutineTab) {
|
||||
add(const LoadScenes(spaceId, communityId));
|
||||
add(const LoadAutomation(spaceId));
|
||||
add(LoadScenes(spaceId, communityId));
|
||||
add(LoadAutomation(spaceId));
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,7 +156,14 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||
|
||||
try {
|
||||
final scenes = await SceneApi.getScenesByUnitId(event.unitId, event.communityId);
|
||||
spaceId = event.spaceId;
|
||||
communityId = event.communityId;
|
||||
|
||||
List<ScenesModel> scenes = [];
|
||||
|
||||
if (communityId.isNotEmpty && spaceId.isNotEmpty) {
|
||||
scenes = await SceneApi.getScenes(event.spaceId, event.communityId);
|
||||
}
|
||||
emit(state.copyWith(
|
||||
scenes: scenes,
|
||||
isLoading: false,
|
||||
@ -167,7 +174,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
loadScenesErrorMessage: 'Failed to load scenes',
|
||||
errorMessage: '',
|
||||
loadAutomationErrorMessage: '',
|
||||
));
|
||||
scenes: []));
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,27 +182,22 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
emit(state.copyWith(isLoading: true, errorMessage: null));
|
||||
|
||||
try {
|
||||
final automations = await SceneApi.getAutomationByUnitId(event.unitId);
|
||||
if (automations.isNotEmpty) {
|
||||
spaceId = event.spaceId;
|
||||
List<ScenesModel> automations = [];
|
||||
if (spaceId.isNotEmpty) {
|
||||
automations = await SceneApi.getAutomation(event.spaceId);
|
||||
}
|
||||
emit(state.copyWith(
|
||||
automations: automations,
|
||||
isLoading: false,
|
||||
));
|
||||
} else {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
loadAutomationErrorMessage: 'Failed to load automations',
|
||||
errorMessage: '',
|
||||
loadScenesErrorMessage: '',
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
loadAutomationErrorMessage: 'Failed to load automations',
|
||||
errorMessage: '',
|
||||
loadScenesErrorMessage: '',
|
||||
));
|
||||
automations: []));
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,8 +292,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
final result = await SceneApi.createScene(createSceneModel);
|
||||
if (result['success']) {
|
||||
add(ResetRoutineState());
|
||||
add(const LoadScenes(spaceId, communityId));
|
||||
add(const LoadAutomation(spaceId));
|
||||
add(LoadScenes(spaceId, communityId));
|
||||
add(LoadAutomation(spaceId));
|
||||
} else {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
@ -419,8 +421,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
final result = await SceneApi.createAutomation(createAutomationModel);
|
||||
if (result['success']) {
|
||||
add(ResetRoutineState());
|
||||
add(const LoadAutomation(spaceId));
|
||||
add(const LoadScenes(spaceId, communityId));
|
||||
add(LoadAutomation(spaceId));
|
||||
add(LoadScenes(spaceId, communityId));
|
||||
} else {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
@ -785,8 +787,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
SceneApi.deleteAutomation(unitUuid: spaceId, automationId: state.automationId ?? '');
|
||||
}
|
||||
|
||||
add(const LoadScenes(spaceId, communityId));
|
||||
add(const LoadAutomation(spaceId));
|
||||
add(LoadScenes(spaceId, communityId));
|
||||
add(LoadAutomation(spaceId));
|
||||
add(ResetRoutineState());
|
||||
emit(state.copyWith(isLoading: false, createRoutineView: false));
|
||||
} catch (e) {
|
||||
@ -814,7 +816,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
FutureOr<void> _fetchDevices(FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
|
||||
emit(state.copyWith(isLoading: true));
|
||||
try {
|
||||
final devices = await DevicesManagementApi().fetchDevices();
|
||||
final devices = await DevicesManagementApi().fetchDevices(communityId, spaceId);
|
||||
|
||||
emit(state.copyWith(isLoading: false, devices: devices));
|
||||
} catch (e) {
|
||||
@ -892,8 +894,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
final result = await SceneApi.updateScene(createSceneModel, state.sceneId ?? '');
|
||||
if (result['success']) {
|
||||
add(ResetRoutineState());
|
||||
add(const LoadScenes(spaceId, communityId));
|
||||
add(const LoadAutomation(spaceId));
|
||||
add(LoadScenes(spaceId, communityId));
|
||||
add(LoadAutomation(spaceId));
|
||||
} else {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
||||
@ -1021,8 +1023,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
||||
|
||||
if (result['success']) {
|
||||
add(ResetRoutineState());
|
||||
add(const LoadAutomation(spaceId));
|
||||
add(const LoadScenes(spaceId, communityId));
|
||||
add(LoadAutomation(spaceId));
|
||||
add(LoadScenes(spaceId, communityId));
|
||||
} else {
|
||||
emit(state.copyWith(
|
||||
isLoading: false,
|
@ -27,22 +27,22 @@ class AddToThenContainer extends RoutineEvent {
|
||||
}
|
||||
|
||||
class LoadScenes extends RoutineEvent {
|
||||
final String unitId;
|
||||
final String spaceId;
|
||||
final String communityId;
|
||||
|
||||
const LoadScenes(this.unitId, this.communityId);
|
||||
const LoadScenes(this.spaceId, this.communityId);
|
||||
|
||||
@override
|
||||
List<Object> get props => [unitId, communityId];
|
||||
List<Object> get props => [spaceId, communityId];
|
||||
}
|
||||
|
||||
class LoadAutomation extends RoutineEvent {
|
||||
final String unitId;
|
||||
final String spaceId;
|
||||
|
||||
const LoadAutomation(this.unitId);
|
||||
const LoadAutomation(this.spaceId);
|
||||
|
||||
@override
|
||||
List<Object> get props => [unitId];
|
||||
List<Object> get props => [spaceId];
|
||||
}
|
||||
|
||||
class AddFunctionToRoutine extends RoutineEvent {
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_event.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_state.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/setting_bloc/setting_event.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/setting_bloc/setting_state.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/icon_model.dart';
|
||||
import 'package:syncrow_web/services/routines_api.dart';
|
||||
|
||||
class SettingBloc extends Bloc<SettingEvent, SettingState> {
|
@ -1,5 +1,5 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/icon_model.dart';
|
||||
|
||||
abstract class SettingState extends Equatable {
|
||||
const SettingState();
|
@ -0,0 +1,62 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ac_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/two_gang_switch_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
|
||||
class DeviceDialogHelper {
|
||||
static Future<Map<String, dynamic>?> showDeviceDialog(
|
||||
BuildContext context,
|
||||
Map<String, dynamic> data, {
|
||||
required bool removeComparetors,
|
||||
}) async {
|
||||
final functions = data['functions'] as List<DeviceFunction>;
|
||||
|
||||
try {
|
||||
final result = await _getDialogForDeviceType(
|
||||
context,
|
||||
data['productType'],
|
||||
data,
|
||||
functions,
|
||||
removeComparetors: removeComparetors,
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Error: $e');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>?> _getDialogForDeviceType(BuildContext context,
|
||||
String productType, Map<String, dynamic> data, List<DeviceFunction> functions,
|
||||
{required bool removeComparetors}) async {
|
||||
final routineBloc = context.read<RoutineBloc>();
|
||||
final deviceSelectedFunctions =
|
||||
routineBloc.state.selectedFunctions[data['uniqueCustomId']] ?? [];
|
||||
|
||||
switch (productType) {
|
||||
case 'AC':
|
||||
return ACHelper.showACFunctionsDialog(context, functions, data['device'],
|
||||
deviceSelectedFunctions, data['uniqueCustomId'], removeComparetors);
|
||||
|
||||
case '1G':
|
||||
return OneGangSwitchHelper.showSwitchFunctionsDialog(context, functions, data['device'],
|
||||
deviceSelectedFunctions, data['uniqueCustomId'], removeComparetors);
|
||||
case '2G':
|
||||
return TwoGangSwitchHelper.showSwitchFunctionsDialog(context, functions, data['device'],
|
||||
deviceSelectedFunctions, data['uniqueCustomId'], removeComparetors);
|
||||
case '3G':
|
||||
return ThreeGangSwitchHelper.showSwitchFunctionsDialog(context, functions, data['device'],
|
||||
deviceSelectedFunctions, data['uniqueCustomId'], removeComparetors);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,9 +3,9 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
@ -1,6 +1,6 @@
|
||||
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/ac/ac_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/ac/ac_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/utils/constants/app_enum.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class DelayFunction extends BaseSwitchFunction {
|
@ -1,5 +1,5 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
|
||||
|
||||
abstract class BaseSwitchFunction extends DeviceFunction<bool> {
|
||||
BaseSwitchFunction({
|
@ -1,5 +1,5 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class OneGangSwitchFunction extends BaseSwitchFunction {
|
@ -1,5 +1,5 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class ThreeGangSwitch1Function extends BaseSwitchFunction {
|
||||
@ -26,8 +26,7 @@ class ThreeGangSwitch1Function extends BaseSwitchFunction {
|
||||
}
|
||||
|
||||
class ThreeGangCountdown1Function extends BaseSwitchFunction {
|
||||
ThreeGangCountdown1Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
ThreeGangCountdown1Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_1',
|
||||
operationName: 'Light 1 Countdown',
|
||||
@ -71,8 +70,7 @@ class ThreeGangSwitch2Function extends BaseSwitchFunction {
|
||||
}
|
||||
|
||||
class ThreeGangCountdown2Function extends BaseSwitchFunction {
|
||||
ThreeGangCountdown2Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
ThreeGangCountdown2Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_2',
|
||||
operationName: 'Light 2 Countdown',
|
||||
@ -116,8 +114,7 @@ class ThreeGangSwitch3Function extends BaseSwitchFunction {
|
||||
}
|
||||
|
||||
class ThreeGangCountdown3Function extends BaseSwitchFunction {
|
||||
ThreeGangCountdown3Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
ThreeGangCountdown3Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_3',
|
||||
operationName: 'Light 3 Countdown',
|
@ -1,5 +1,5 @@
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class TwoGangSwitch1Function extends BaseSwitchFunction {
|
||||
@ -49,8 +49,7 @@ class TwoGangSwitch2Function extends BaseSwitchFunction {
|
||||
}
|
||||
|
||||
class TwoGangCountdown1Function extends BaseSwitchFunction {
|
||||
TwoGangCountdown1Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
TwoGangCountdown1Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_1',
|
||||
operationName: 'Light 1 Countdown',
|
||||
@ -71,8 +70,7 @@ class TwoGangCountdown1Function extends BaseSwitchFunction {
|
||||
}
|
||||
|
||||
class TwoGangCountdown2Function extends BaseSwitchFunction {
|
||||
TwoGangCountdown2Function(
|
||||
{required super.deviceId, required super.deviceName})
|
||||
TwoGangCountdown2Function({required super.deviceId, required super.deviceName})
|
||||
: super(
|
||||
code: 'countdown_2',
|
||||
operationName: 'Light 2 Countdown',
|
@ -1,7 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||
|
||||
class RoutineDetailsModel {
|
||||
final String spaceUuid;
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/conditions_routines_devices_view.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/if_container.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_search_and_buttons.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/then_container.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/conditions_routines_devices_view.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/if_container.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_search_and_buttons.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/then_container.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CreateNewRoutineView extends StatelessWidget {
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/effictive_period_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/period_option.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/repeat_days.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/period_option.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/repeat_days.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class EffectivePeriodView extends StatelessWidget {
|
98
lib/pages/routines/view/routines_view.dart
Normal file
98
lib/pages/routines/view/routines_view.dart
Normal file
@ -0,0 +1,98 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/view/create_new_routine_view.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/main_routine_view/fetch_routine_scenes_automation.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/main_routine_view/routine_view_card.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/view/side_tree_view.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/snack_bar.dart';
|
||||
|
||||
class RoutinesView extends StatefulWidget {
|
||||
const RoutinesView({super.key});
|
||||
|
||||
@override
|
||||
State<RoutinesView> createState() => _RoutinesViewState();
|
||||
}
|
||||
|
||||
class _RoutinesViewState extends State<RoutinesView> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<RoutineBloc>().add(FetchDevicesInRoutine());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, state) {
|
||||
if (state.createRoutineView) {
|
||||
return const CreateNewRoutineView();
|
||||
}
|
||||
return Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
child:
|
||||
// SideSpacesView(
|
||||
// onSelectAction: (String communityId, String spaceId) {
|
||||
// // context.read<RoutineBloc>()
|
||||
// // ..add(LoadScenes(spaceId, communityId))
|
||||
// // ..add(LoadAutomation(spaceId));
|
||||
// },
|
||||
// )
|
||||
SideTreeView()),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Create New Routines",
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
RoutineViewCard(
|
||||
onTap: () {
|
||||
if (context.read<SpaceTreeBloc>().selectedCommunityId.isNotEmpty &&
|
||||
context.read<SpaceTreeBloc>().selectedSpaceId.isNotEmpty) {
|
||||
context.read<RoutineBloc>().add(
|
||||
(ResetRoutineState()),
|
||||
);
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(createRoutineView: true),
|
||||
);
|
||||
} else {
|
||||
CustomSnackBar.redSnackBar('Please select a space');
|
||||
}
|
||||
},
|
||||
icon: Icons.add,
|
||||
textString: '',
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
const Expanded(child: FetchRoutineScenesAutomation()),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_devices.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routines_title_widget.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/scenes_and_automations.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/search_bar_condition_title.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_devices.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routines_title_widget.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/scenes_and_automations.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/search_bar_condition_title.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class ConditionsRoutinesDevicesView extends StatelessWidget {
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/common/custom_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class DeleteSceneWidget extends StatelessWidget {
|
@ -3,8 +3,8 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/helper/dialog_helper/device_dialog_helper.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
@ -26,9 +26,7 @@ class IfContainer extends StatelessWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('IF',
|
||||
style: TextStyle(
|
||||
fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const Text('IF', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
if (state.isAutomation && state.ifItems.isNotEmpty)
|
||||
AutomationOperatorSelector(
|
||||
selectedOperator: state.selectedAutomationOperator),
|
||||
@ -55,44 +53,34 @@ class IfContainer extends StatelessWidget {
|
||||
(index) => GestureDetector(
|
||||
onTap: () async {
|
||||
if (!state.isTabToRun) {
|
||||
final result = await DeviceDialogHelper
|
||||
.showDeviceDialog(
|
||||
final result = await DeviceDialogHelper.showDeviceDialog(
|
||||
context, state.ifItems[index],
|
||||
removeComparetors: false);
|
||||
|
||||
if (result != null) {
|
||||
context.read<RoutineBloc>().add(
|
||||
AddToIfContainer(
|
||||
state.ifItems[index], false));
|
||||
} else if (![
|
||||
'AC',
|
||||
'1G',
|
||||
'2G',
|
||||
'3G'
|
||||
].contains(
|
||||
state.ifItems[index]['productType'])) {
|
||||
context.read<RoutineBloc>().add(
|
||||
AddToIfContainer(
|
||||
state.ifItems[index], false));
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(AddToIfContainer(state.ifItems[index], false));
|
||||
} else if (!['AC', '1G', '2G', '3G']
|
||||
.contains(state.ifItems[index]['productType'])) {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(AddToIfContainer(state.ifItems[index], false));
|
||||
}
|
||||
}
|
||||
},
|
||||
child: DraggableCard(
|
||||
imagePath:
|
||||
state.ifItems[index]['imagePath'] ?? '',
|
||||
imagePath: state.ifItems[index]['imagePath'] ?? '',
|
||||
title: state.ifItems[index]['title'] ?? '',
|
||||
deviceData: state.ifItems[index],
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4, vertical: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
|
||||
isFromThen: false,
|
||||
isFromIf: true,
|
||||
onRemove: () {
|
||||
context.read<RoutineBloc>().add(
|
||||
RemoveDragCard(
|
||||
context.read<RoutineBloc>().add(RemoveDragCard(
|
||||
index: index,
|
||||
isFromThen: false,
|
||||
key: state.ifItems[index]
|
||||
['uniqueCustomId']));
|
||||
key: state.ifItems[index]['uniqueCustomId']));
|
||||
},
|
||||
),
|
||||
)),
|
||||
@ -113,23 +101,15 @@ class IfContainer extends StatelessWidget {
|
||||
|
||||
if (!state.isTabToRun) {
|
||||
if (mutableData['deviceId'] == 'tab_to_run') {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(AddToIfContainer(mutableData, true));
|
||||
context.read<RoutineBloc>().add(AddToIfContainer(mutableData, true));
|
||||
} else {
|
||||
final result = await DeviceDialogHelper.showDeviceDialog(
|
||||
context, mutableData,
|
||||
final result = await DeviceDialogHelper.showDeviceDialog(context, mutableData,
|
||||
removeComparetors: false);
|
||||
|
||||
if (result != null) {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(AddToIfContainer(mutableData, false));
|
||||
} else if (!['AC', '1G', '2G', '3G']
|
||||
.contains(mutableData['productType'])) {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(AddToIfContainer(mutableData, false));
|
||||
context.read<RoutineBloc>().add(AddToIfContainer(mutableData, false));
|
||||
} else if (!['AC', '1G', '2G', '3G'].contains(mutableData['productType'])) {
|
||||
context.read<RoutineBloc>().add(AddToIfContainer(mutableData, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,9 +155,7 @@ class AutomationOperatorSelector extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(const ChangeAutomationOperator(operator: 'or'));
|
||||
context.read<RoutineBloc>().add(const ChangeAutomationOperator(operator: 'or'));
|
||||
},
|
||||
),
|
||||
Container(
|
||||
@ -203,9 +181,7 @@ class AutomationOperatorSelector extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
context
|
||||
.read<RoutineBloc>()
|
||||
.add(const ChangeAutomationOperator(operator: 'and'));
|
||||
context.read<RoutineBloc>().add(const ChangeAutomationOperator(operator: 'and'));
|
||||
},
|
||||
),
|
||||
],
|
@ -0,0 +1,143 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/main_routine_view/routine_view_card.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class FetchRoutineScenesAutomation extends StatefulWidget {
|
||||
const FetchRoutineScenesAutomation({super.key});
|
||||
|
||||
@override
|
||||
State<FetchRoutineScenesAutomation> createState() => _FetchRoutineScenesState();
|
||||
}
|
||||
|
||||
class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
||||
with HelperResponsiveLayout {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<RoutineBloc>()
|
||||
..add(LoadScenes(context.read<SpaceTreeBloc>().selectedSpaceId,
|
||||
context.read<SpaceTreeBloc>().selectedCommunityId))
|
||||
..add(LoadAutomation(context.read<SpaceTreeBloc>().selectedSpaceId));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||
builder: (context, state) {
|
||||
return state.isLoading
|
||||
? const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"Scenes (Tab to Run)",
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
if (state.scenes.isEmpty)
|
||||
Text(
|
||||
"No scenes found",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
if (state.scenes.isNotEmpty)
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: isSmallScreenSize(context) ? 160 : 170,
|
||||
maxWidth: MediaQuery.sizeOf(context).width * 0.7),
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: state.scenes.length,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||
),
|
||||
child: RoutineViewCard(
|
||||
onTap: () {
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(createRoutineView: true),
|
||||
);
|
||||
context.read<RoutineBloc>().add(
|
||||
GetSceneDetails(
|
||||
sceneId: state.scenes[index].id,
|
||||
isTabToRun: true,
|
||||
isUpdate: true,
|
||||
),
|
||||
);
|
||||
},
|
||||
textString: state.scenes[index].name,
|
||||
icon: state.scenes[index].icon ?? Assets.logoHorizontal,
|
||||
isFromScenes: true,
|
||||
iconInBytes: state.scenes[index].iconInBytes,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Text(
|
||||
"Automations",
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
if (state.automations.isEmpty)
|
||||
Text(
|
||||
"No automations found",
|
||||
style: context.textTheme.bodyMedium?.copyWith(
|
||||
color: ColorsManager.grayColor,
|
||||
),
|
||||
),
|
||||
if (state.automations.isNotEmpty)
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: isSmallScreenSize(context) ? 160 : 170,
|
||||
maxWidth: MediaQuery.sizeOf(context).width * 0.7),
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: state.automations.length,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: EdgeInsets.only(
|
||||
right: isSmallScreenSize(context) ? 4.0 : 8.0,
|
||||
),
|
||||
child: RoutineViewCard(
|
||||
onTap: () {
|
||||
BlocProvider.of<RoutineBloc>(context).add(
|
||||
const CreateNewRoutineViewEvent(createRoutineView: true),
|
||||
);
|
||||
context.read<RoutineBloc>().add(
|
||||
GetAutomationDetails(
|
||||
automationId: state.automations[index].id,
|
||||
isAutomation: true,
|
||||
isUpdate: true),
|
||||
);
|
||||
},
|
||||
textString: state.automations[index].name,
|
||||
icon: state.automations[index].icon ?? Assets.automation,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -70,15 +70,13 @@ class RoutineViewCard extends StatelessWidget with HelperResponsiveLayout {
|
||||
height: iconSize,
|
||||
width: iconSize,
|
||||
child: (isFromScenes ?? false)
|
||||
? (iconInBytes != null &&
|
||||
iconInBytes?.isNotEmpty == true)
|
||||
? (iconInBytes != null && iconInBytes?.isNotEmpty == true)
|
||||
? Image.memory(
|
||||
iconInBytes!,
|
||||
height: iconSize,
|
||||
width: iconSize,
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (context, error, stackTrace) =>
|
||||
Image.asset(
|
||||
errorBuilder: (context, error, stackTrace) => Image.asset(
|
||||
Assets.logo,
|
||||
height: iconSize,
|
||||
width: iconSize,
|
@ -1,9 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/effictive_period_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/effictive_period_dialog.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/app_enum.dart';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class RepeatDays extends StatelessWidget {
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
||||
|
||||
class RoutineDevices extends StatelessWidget {
|
||||
const RoutineDevices({super.key});
|
||||
@ -35,9 +35,7 @@ class RoutineDevices extends StatelessWidget {
|
||||
children: deviceList.asMap().entries.map((entry) {
|
||||
final device = entry.value;
|
||||
if (state.searchText != null && state.searchText!.isNotEmpty) {
|
||||
return device.name!
|
||||
.toLowerCase()
|
||||
.contains(state.searchText!.toLowerCase())
|
||||
return device.name!.toLowerCase().contains(state.searchText!.toLowerCase())
|
||||
? DraggableCard(
|
||||
imagePath: device.getDefaultIcon(device.productType),
|
||||
title: device.name ?? '',
|
@ -1,16 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/ac/ac_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/ac/ac_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/ac/ac_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/ac/ac_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||
|
||||
class ACHelper {
|
||||
static Future<Map<String, dynamic>?> showACFunctionsDialog(
|
||||
@ -27,16 +27,15 @@ class ACHelper {
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => FunctionBloc()
|
||||
..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||
create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||
child: AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: BlocBuilder<FunctionBloc, FunctionBlocState>(
|
||||
builder: (context, state) {
|
||||
final selectedFunction = state.selectedFunction;
|
||||
final selectedOperationName = state.selectedOperationName;
|
||||
final selectedFunctionData = state.addedFunctions
|
||||
.firstWhere((f) => f.functionCode == selectedFunction,
|
||||
final selectedFunctionData =
|
||||
state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction,
|
||||
orElse: () => DeviceFunctionData(
|
||||
entityId: '',
|
||||
functionCode: selectedFunction ?? '',
|
||||
@ -66,10 +65,8 @@ class ACHelper {
|
||||
child: _buildFunctionsList(
|
||||
context: context,
|
||||
acFunctions: acFunctions,
|
||||
onFunctionSelected:
|
||||
(functionCode, operationName) => context
|
||||
.read<FunctionBloc>()
|
||||
.add(SelectFunction(
|
||||
onFunctionSelected: (functionCode, operationName) =>
|
||||
context.read<FunctionBloc>().add(SelectFunction(
|
||||
functionCode: functionCode,
|
||||
operationName: operationName,
|
||||
)),
|
||||
@ -184,7 +181,7 @@ class ACHelper {
|
||||
bool? removeComparators,
|
||||
}) {
|
||||
if (selectedFunction == 'temp_set' || selectedFunction == 'temp_current') {
|
||||
final initialValue = selectedFunctionData?.value ?? 200;
|
||||
final initialValue = selectedFunctionData?.value ?? 250;
|
||||
return _buildTemperatureSelector(
|
||||
context: context,
|
||||
initialValue: initialValue,
|
||||
@ -197,8 +194,7 @@ class ACHelper {
|
||||
);
|
||||
}
|
||||
|
||||
final selectedFn =
|
||||
acFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final selectedFn = acFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final values = selectedFn.getOperationalValues();
|
||||
|
||||
return _buildOperationalValuesList(
|
||||
@ -294,8 +290,7 @@ class ACHelper {
|
||||
minHeight: 40.0,
|
||||
minWidth: 40.0,
|
||||
),
|
||||
isSelected:
|
||||
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||
isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||
children: conditions.map((c) => Text(c)).toList(),
|
||||
);
|
||||
}
|
||||
@ -333,10 +328,10 @@ class ACHelper {
|
||||
String selectCode,
|
||||
) {
|
||||
return Slider(
|
||||
value: initialValue is int ? initialValue.toDouble() : 160.0,
|
||||
min: 160,
|
||||
value: initialValue is int ? initialValue.toDouble() : 200.0,
|
||||
min: 200,
|
||||
max: 300,
|
||||
divisions: 14,
|
||||
divisions: 10,
|
||||
label: '${((initialValue ?? 160) / 10).toInt()}°C',
|
||||
onChanged: (value) {
|
||||
context.read<FunctionBloc>().add(
|
||||
@ -389,13 +384,9 @@ class ACHelper {
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: Icon(
|
||||
isSelected
|
||||
? Icons.radio_button_checked
|
||||
: Icons.radio_button_unchecked,
|
||||
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
|
||||
size: 24,
|
||||
color: isSelected
|
||||
? ColorsManager.primaryColorWithOpacity
|
||||
: ColorsManager.textGray,
|
||||
color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
if (!isSelected) {
|
||||
@ -407,8 +398,7 @@ class ACHelper {
|
||||
operationName: operationName,
|
||||
value: value.value,
|
||||
condition: selectedFunctionData?.condition,
|
||||
valueDescription:
|
||||
selectedFunctionData?.valueDescription,
|
||||
valueDescription: selectedFunctionData?.valueDescription,
|
||||
),
|
||||
),
|
||||
);
|
@ -1,10 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class AutomationDialog extends StatefulWidget {
|
||||
@ -31,10 +31,8 @@ class _AutomationDialogState extends State<AutomationDialog> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
List<DeviceFunctionData>? functions = context
|
||||
.read<RoutineBloc>()
|
||||
.state
|
||||
.selectedFunctions[widget.uniqueCustomId];
|
||||
List<DeviceFunctionData>? functions =
|
||||
context.read<RoutineBloc>().state.selectedFunctions[widget.uniqueCustomId];
|
||||
for (DeviceFunctionData data in functions ?? []) {
|
||||
if (data.entityId == widget.automationId) {
|
||||
selectedAutomationActionExecutor = data.value;
|
||||
@ -67,8 +65,7 @@ class _AutomationDialogState extends State<AutomationDialog> {
|
||||
}),
|
||||
),
|
||||
ListTile(
|
||||
leading:
|
||||
SvgPicture.asset(Assets.acPowerOff, width: 24, height: 24),
|
||||
leading: SvgPicture.asset(Assets.acPowerOff, width: 24, height: 24),
|
||||
title: const Text('Disable'),
|
||||
trailing: Radio<String?>(
|
||||
value: 'rule_disable',
|
@ -1,10 +1,10 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
||||
|
||||
class DelayHelper {
|
||||
static Future<Map<String, dynamic>?> showDelayPickerDialog(
|
@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/app_enum.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
@ -2,14 +2,14 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/duration_format_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/helper/duration_format_helper.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
@ -22,23 +22,21 @@ class OneGangSwitchHelper {
|
||||
String uniqueCustomId,
|
||||
bool removeComparetors,
|
||||
) async {
|
||||
List<BaseSwitchFunction> acFunctions =
|
||||
functions.whereType<BaseSwitchFunction>().toList();
|
||||
List<BaseSwitchFunction> acFunctions = functions.whereType<BaseSwitchFunction>().toList();
|
||||
|
||||
return showDialog<Map<String, dynamic>?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => FunctionBloc()
|
||||
..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||
create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||
child: AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: BlocBuilder<FunctionBloc, FunctionBlocState>(
|
||||
builder: (context, state) {
|
||||
final selectedFunction = state.selectedFunction;
|
||||
final selectedOperationName = state.selectedOperationName;
|
||||
final selectedFunctionData = state.addedFunctions
|
||||
.firstWhere((f) => f.functionCode == selectedFunction,
|
||||
final selectedFunctionData =
|
||||
state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction,
|
||||
orElse: () => DeviceFunctionData(
|
||||
entityId: '',
|
||||
functionCode: selectedFunction ?? '',
|
||||
@ -85,12 +83,9 @@ class OneGangSwitchHelper {
|
||||
color: ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
context
|
||||
.read<FunctionBloc>()
|
||||
.add(SelectFunction(
|
||||
context.read<FunctionBloc>().add(SelectFunction(
|
||||
functionCode: function.code,
|
||||
operationName:
|
||||
function.operationName,
|
||||
operationName: function.operationName,
|
||||
));
|
||||
},
|
||||
);
|
||||
@ -180,8 +175,7 @@ class OneGangSwitchHelper {
|
||||
);
|
||||
}
|
||||
|
||||
final selectedFn =
|
||||
acFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final selectedFn = acFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final values = selectedFn.getOperationalValues();
|
||||
|
||||
return _buildOperationalValuesList(
|
||||
@ -218,11 +212,11 @@ class OneGangSwitchHelper {
|
||||
selectedFunctionData,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
_buildCountDownDisplay(context, initialValue, device, operationName,
|
||||
selectedFunctionData, selectCode),
|
||||
_buildCountDownDisplay(
|
||||
context, initialValue, device, operationName, selectedFunctionData, selectCode),
|
||||
const SizedBox(height: 20),
|
||||
_buildCountDownSlider(context, initialValue, device, operationName,
|
||||
selectedFunctionData, selectCode),
|
||||
_buildCountDownSlider(
|
||||
context, initialValue, device, operationName, selectedFunctionData, selectCode),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -263,8 +257,7 @@ class OneGangSwitchHelper {
|
||||
minHeight: 40.0,
|
||||
minWidth: 40.0,
|
||||
),
|
||||
isSelected:
|
||||
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||
isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||
children: conditions.map((c) => Text(c)).toList(),
|
||||
);
|
||||
}
|
||||
@ -312,8 +305,7 @@ class OneGangSwitchHelper {
|
||||
value: (initialValue ?? 0).toDouble(),
|
||||
min: operationalValues.minValue?.toDouble() ?? 0.0,
|
||||
max: operationalValues.maxValue?.toDouble() ?? 0.0,
|
||||
divisions: (((operationalValues.maxValue ?? 0) -
|
||||
(operationalValues.minValue ?? 0)) /
|
||||
divisions: (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) /
|
||||
(operationalValues.stepValue ?? 1))
|
||||
.round(),
|
||||
onChanged: (value) {
|
||||
@ -365,13 +357,9 @@ class OneGangSwitchHelper {
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: Icon(
|
||||
isSelected
|
||||
? Icons.radio_button_checked
|
||||
: Icons.radio_button_unchecked,
|
||||
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
|
||||
size: 24,
|
||||
color: isSelected
|
||||
? ColorsManager.primaryColorWithOpacity
|
||||
: ColorsManager.textGray,
|
||||
color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
if (!isSelected) {
|
||||
@ -383,8 +371,7 @@ class OneGangSwitchHelper {
|
||||
operationName: operationName,
|
||||
value: value.value,
|
||||
condition: selectedFunctionData?.condition,
|
||||
valueDescription:
|
||||
selectedFunctionData?.valueDescription,
|
||||
valueDescription: selectedFunctionData?.valueDescription,
|
||||
),
|
||||
),
|
||||
);
|
@ -1,17 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_event.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/setting_bloc/setting_state.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/view/effective_period_view.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/delete_scene.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_event.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/effective_period/effect_period_state.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/setting_bloc/setting_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/setting_bloc/setting_event.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/setting_bloc/setting_state.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/icon_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/view/effective_period_view.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/delete_scene.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
@ -2,14 +2,14 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/duration_format_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/helper/duration_format_helper.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
@ -22,23 +22,21 @@ class ThreeGangSwitchHelper {
|
||||
String uniqueCustomId,
|
||||
bool removeComparetors,
|
||||
) async {
|
||||
List<BaseSwitchFunction> switchFunctions =
|
||||
functions.whereType<BaseSwitchFunction>().toList();
|
||||
List<BaseSwitchFunction> switchFunctions = functions.whereType<BaseSwitchFunction>().toList();
|
||||
|
||||
return showDialog<Map<String, dynamic>?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => FunctionBloc()
|
||||
..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||
create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||
child: AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: BlocBuilder<FunctionBloc, FunctionBlocState>(
|
||||
builder: (context, state) {
|
||||
final selectedFunction = state.selectedFunction;
|
||||
final selectedOperationName = state.selectedOperationName;
|
||||
final selectedFunctionData = state.addedFunctions
|
||||
.firstWhere((f) => f.functionCode == selectedFunction,
|
||||
final selectedFunctionData =
|
||||
state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction,
|
||||
orElse: () => DeviceFunctionData(
|
||||
entityId: '',
|
||||
functionCode: selectedFunction ?? '',
|
||||
@ -85,12 +83,9 @@ class ThreeGangSwitchHelper {
|
||||
color: ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
context
|
||||
.read<FunctionBloc>()
|
||||
.add(SelectFunction(
|
||||
context.read<FunctionBloc>().add(SelectFunction(
|
||||
functionCode: function.code,
|
||||
operationName:
|
||||
function.operationName,
|
||||
operationName: function.operationName,
|
||||
));
|
||||
},
|
||||
);
|
||||
@ -182,8 +177,7 @@ class ThreeGangSwitchHelper {
|
||||
);
|
||||
}
|
||||
|
||||
final selectedFn =
|
||||
switchFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final selectedFn = switchFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final values = selectedFn.getOperationalValues();
|
||||
|
||||
return _buildOperationalValuesList(
|
||||
@ -220,11 +214,11 @@ class ThreeGangSwitchHelper {
|
||||
selectedFunctionData,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
_buildCountDownDisplay(context, initialValue, device, operationName,
|
||||
selectedFunctionData, selectCode),
|
||||
_buildCountDownDisplay(
|
||||
context, initialValue, device, operationName, selectedFunctionData, selectCode),
|
||||
const SizedBox(height: 20),
|
||||
_buildCountDownSlider(context, initialValue, device, operationName,
|
||||
selectedFunctionData, selectCode),
|
||||
_buildCountDownSlider(
|
||||
context, initialValue, device, operationName, selectedFunctionData, selectCode),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -265,8 +259,7 @@ class ThreeGangSwitchHelper {
|
||||
minHeight: 40.0,
|
||||
minWidth: 40.0,
|
||||
),
|
||||
isSelected:
|
||||
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||
isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||
children: conditions.map((c) => Text(c)).toList(),
|
||||
);
|
||||
}
|
||||
@ -314,8 +307,7 @@ class ThreeGangSwitchHelper {
|
||||
value: (initialValue ?? 0).toDouble(),
|
||||
min: operationalValues.minValue?.toDouble() ?? 0.0,
|
||||
max: operationalValues.maxValue?.toDouble() ?? 0.0,
|
||||
divisions: (((operationalValues.maxValue ?? 0) -
|
||||
(operationalValues.minValue ?? 0)) /
|
||||
divisions: (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) /
|
||||
(operationalValues.stepValue ?? 1))
|
||||
.round(),
|
||||
onChanged: (value) {
|
||||
@ -367,13 +359,9 @@ class ThreeGangSwitchHelper {
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: Icon(
|
||||
isSelected
|
||||
? Icons.radio_button_checked
|
||||
: Icons.radio_button_unchecked,
|
||||
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
|
||||
size: 24,
|
||||
color: isSelected
|
||||
? ColorsManager.primaryColorWithOpacity
|
||||
: ColorsManager.textGray,
|
||||
color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
if (!isSelected) {
|
||||
@ -385,8 +373,7 @@ class ThreeGangSwitchHelper {
|
||||
operationName: operationName,
|
||||
value: value.value,
|
||||
condition: selectedFunctionData?.condition,
|
||||
valueDescription:
|
||||
selectedFunctionData?.valueDescription,
|
||||
valueDescription: selectedFunctionData?.valueDescription,
|
||||
),
|
||||
),
|
||||
);
|
@ -2,14 +2,14 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/duration_format_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/helper/duration_format_helper.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/base_switch_function.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/gang_switches/switch_operational_value.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
|
||||
@ -22,23 +22,21 @@ class TwoGangSwitchHelper {
|
||||
String uniqueCustomId,
|
||||
bool removeComparetors,
|
||||
) async {
|
||||
List<BaseSwitchFunction> switchFunctions =
|
||||
functions.whereType<BaseSwitchFunction>().toList();
|
||||
List<BaseSwitchFunction> switchFunctions = functions.whereType<BaseSwitchFunction>().toList();
|
||||
|
||||
return showDialog<Map<String, dynamic>?>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => FunctionBloc()
|
||||
..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||
create: (_) => FunctionBloc()..add(InitializeFunctions(deviceSelectedFunctions ?? [])),
|
||||
child: AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: BlocBuilder<FunctionBloc, FunctionBlocState>(
|
||||
builder: (context, state) {
|
||||
final selectedFunction = state.selectedFunction;
|
||||
final selectedOperationName = state.selectedOperationName;
|
||||
final selectedFunctionData = state.addedFunctions
|
||||
.firstWhere((f) => f.functionCode == selectedFunction,
|
||||
final selectedFunctionData =
|
||||
state.addedFunctions.firstWhere((f) => f.functionCode == selectedFunction,
|
||||
orElse: () => DeviceFunctionData(
|
||||
entityId: '',
|
||||
functionCode: selectedFunction ?? '',
|
||||
@ -85,12 +83,9 @@ class TwoGangSwitchHelper {
|
||||
color: ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
context
|
||||
.read<FunctionBloc>()
|
||||
.add(SelectFunction(
|
||||
context.read<FunctionBloc>().add(SelectFunction(
|
||||
functionCode: function.code,
|
||||
operationName:
|
||||
function.operationName,
|
||||
operationName: function.operationName,
|
||||
));
|
||||
},
|
||||
);
|
||||
@ -166,8 +161,7 @@ class TwoGangSwitchHelper {
|
||||
required String operationName,
|
||||
required bool removeComparetors,
|
||||
}) {
|
||||
if (selectedFunction == 'countdown_1' ||
|
||||
selectedFunction == 'countdown_2') {
|
||||
if (selectedFunction == 'countdown_1' || selectedFunction == 'countdown_2') {
|
||||
final initialValue = selectedFunctionData?.value ?? 200;
|
||||
return _buildTemperatureSelector(
|
||||
context: context,
|
||||
@ -181,8 +175,7 @@ class TwoGangSwitchHelper {
|
||||
);
|
||||
}
|
||||
|
||||
final selectedFn =
|
||||
switchFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final selectedFn = switchFunctions.firstWhere((f) => f.code == selectedFunction);
|
||||
final values = selectedFn.getOperationalValues();
|
||||
|
||||
return _buildOperationalValuesList(
|
||||
@ -219,11 +212,11 @@ class TwoGangSwitchHelper {
|
||||
selectedFunctionData,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
_buildCountDownDisplay(context, initialValue, device, operationName,
|
||||
selectedFunctionData, selectCode),
|
||||
_buildCountDownDisplay(
|
||||
context, initialValue, device, operationName, selectedFunctionData, selectCode),
|
||||
const SizedBox(height: 20),
|
||||
_buildCountDownSlider(context, initialValue, device, operationName,
|
||||
selectedFunctionData, selectCode),
|
||||
_buildCountDownSlider(
|
||||
context, initialValue, device, operationName, selectedFunctionData, selectCode),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -264,8 +257,7 @@ class TwoGangSwitchHelper {
|
||||
minHeight: 40.0,
|
||||
minWidth: 40.0,
|
||||
),
|
||||
isSelected:
|
||||
conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||
isSelected: conditions.map((c) => c == (currentCondition ?? "==")).toList(),
|
||||
children: conditions.map((c) => Text(c)).toList(),
|
||||
);
|
||||
}
|
||||
@ -313,8 +305,7 @@ class TwoGangSwitchHelper {
|
||||
value: (initialValue ?? 0).toDouble(),
|
||||
min: operationalValues.minValue?.toDouble() ?? 0.0,
|
||||
max: operationalValues.maxValue?.toDouble() ?? 0.0,
|
||||
divisions: (((operationalValues.maxValue ?? 0) -
|
||||
(operationalValues.minValue ?? 0)) /
|
||||
divisions: (((operationalValues.maxValue ?? 0) - (operationalValues.minValue ?? 0)) /
|
||||
(operationalValues.stepValue ?? 1))
|
||||
.round(),
|
||||
onChanged: (value) {
|
||||
@ -366,13 +357,9 @@ class TwoGangSwitchHelper {
|
||||
style: context.textTheme.bodyMedium,
|
||||
),
|
||||
trailing: Icon(
|
||||
isSelected
|
||||
? Icons.radio_button_checked
|
||||
: Icons.radio_button_unchecked,
|
||||
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
|
||||
size: 24,
|
||||
color: isSelected
|
||||
? ColorsManager.primaryColorWithOpacity
|
||||
: ColorsManager.textGray,
|
||||
color: isSelected ? ColorsManager.primaryColorWithOpacity : ColorsManager.textGray,
|
||||
),
|
||||
onTap: () {
|
||||
if (!isSelected) {
|
||||
@ -384,8 +371,7 @@ class TwoGangSwitchHelper {
|
||||
operationName: operationName,
|
||||
value: value.value,
|
||||
condition: selectedFunctionData?.condition,
|
||||
valueDescription:
|
||||
selectedFunctionData?.valueDescription,
|
||||
valueDescription: selectedFunctionData?.valueDescription,
|
||||
),
|
||||
),
|
||||
);
|
@ -1,10 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/save_routine_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/discard_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/setting_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/helper/save_routine_helper.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/discard_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/setting_dialog.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class ScenesAndAutomations extends StatefulWidget {
|
||||
@ -18,8 +19,9 @@ class _ScenesAndAutomationsState extends State<ScenesAndAutomations> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
context.read<RoutineBloc>()
|
||||
..add(const LoadScenes(spaceId, communityId))
|
||||
..add(const LoadAutomation(spaceId));
|
||||
..add(LoadScenes(context.read<SpaceTreeBloc>().selectedSpaceId,
|
||||
context.read<SpaceTreeBloc>().selectedCommunityId))
|
||||
..add(LoadAutomation(context.read<SpaceTreeBloc>().selectedSpaceId));
|
||||
}
|
||||
|
||||
@override
|
||||
@ -34,9 +36,7 @@ class _ScenesAndAutomationsState extends State<ScenesAndAutomations> {
|
||||
children: scenes.asMap().entries.map((entry) {
|
||||
final scene = entry.value;
|
||||
if (state.searchText != null && state.searchText!.isNotEmpty) {
|
||||
return scene.name
|
||||
.toLowerCase()
|
||||
.contains(state.searchText!.toLowerCase())
|
||||
return scene.name.toLowerCase().contains(state.searchText!.toLowerCase())
|
||||
? DraggableCard(
|
||||
imagePath: scene.icon ?? Assets.loginLogo,
|
||||
title: scene.name,
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/common/text_field/custom_text_field.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routines_title_widget.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routines_title_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/automation_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/routine_dialogs/delay_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routiens/helper/dialog_helper/device_dialog_helper.dart';
|
||||
import 'package:syncrow_web/pages/routiens/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/automation_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/delay_dialog.dart';
|
||||
import 'package:syncrow_web/pages/routines/helper/dialog_helper/device_dialog_helper.dart';
|
||||
import 'package:syncrow_web/pages/routines/widgets/dragable_card.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
209
lib/pages/space_tree/bloc/space_tree_bloc.dart
Normal file
209
lib/pages/space_tree/bloc/space_tree_bloc.dart
Normal file
@ -0,0 +1,209 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||
|
||||
class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
||||
String selectedCommunityId = '';
|
||||
String selectedSpaceId = '';
|
||||
|
||||
SpaceTreeBloc() : super(const SpaceTreeState()) {
|
||||
on<InitialEvent>(_fetchSpaces);
|
||||
on<OnCommunityExpanded>(_onCommunityExpanded);
|
||||
on<OnSpaceExpanded>(_onSpaceExpanded);
|
||||
on<OnCommunitySelected>(_onCommunitySelected);
|
||||
on<OnSpaceSelected>(_onSpaceSelected);
|
||||
on<SearchQueryEvent>(_onSearch);
|
||||
}
|
||||
|
||||
_fetchSpaces(InitialEvent event, Emitter<SpaceTreeState> emit) async {
|
||||
emit(SpaceTreeLoadingState());
|
||||
try {
|
||||
List<CommunityModel> communities = await CommunitySpaceManagementApi().fetchCommunities();
|
||||
|
||||
List<CommunityModel> updatedCommunities = await Future.wait(
|
||||
communities.map((community) async {
|
||||
List<SpaceModel> spaces =
|
||||
await CommunitySpaceManagementApi().getSpaceHierarchy(community.uuid);
|
||||
|
||||
return CommunityModel(
|
||||
uuid: community.uuid,
|
||||
createdAt: community.createdAt,
|
||||
updatedAt: community.updatedAt,
|
||||
name: community.name,
|
||||
description: community.description,
|
||||
spaces: spaces,
|
||||
region: community.region,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
|
||||
emit(state.copyWith(
|
||||
communitiesList: updatedCommunities, expandedCommunity: [], expandedSpaces: []));
|
||||
} catch (e) {
|
||||
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
_onCommunityExpanded(OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async {
|
||||
try {
|
||||
List<String> updatedExpandedCommunityList = List.from(state.expandedCommunities);
|
||||
|
||||
if (updatedExpandedCommunityList.contains(event.communityId)) {
|
||||
updatedExpandedCommunityList.remove(event.communityId);
|
||||
} else {
|
||||
updatedExpandedCommunityList.add(event.communityId);
|
||||
}
|
||||
|
||||
emit(state.copyWith(
|
||||
expandedCommunity: updatedExpandedCommunityList,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||
}
|
||||
}
|
||||
|
||||
_onSpaceExpanded(OnSpaceExpanded event, Emitter<SpaceTreeState> emit) async {
|
||||
try {
|
||||
List<String> updatedExpandedSpacesList = List.from(state.expandedSpaces);
|
||||
|
||||
if (updatedExpandedSpacesList.contains(event.spaceId)) {
|
||||
updatedExpandedSpacesList.remove(event.spaceId);
|
||||
} else {
|
||||
updatedExpandedSpacesList.add(event.spaceId);
|
||||
}
|
||||
|
||||
emit(state.copyWith(expandedSpaces: updatedExpandedSpacesList));
|
||||
} catch (e) {
|
||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||
}
|
||||
}
|
||||
|
||||
_onCommunitySelected(OnCommunitySelected event, Emitter<SpaceTreeState> emit) async {
|
||||
try {
|
||||
List<String> updatedSelectedCommunities = List.from(state.selectedCommunities);
|
||||
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces);
|
||||
List<String> updatedSoldChecks = List.from(state.soldCheck);
|
||||
|
||||
List<String> childrenIds = _getAllChildIds(event.children);
|
||||
|
||||
if (!updatedSelectedCommunities.contains(event.communityId)) {
|
||||
// Select the community and all its children
|
||||
updatedSelectedCommunities.add(event.communityId);
|
||||
updatedSelectedSpaces.addAll(childrenIds);
|
||||
} else {
|
||||
// Unselect the community and all its children
|
||||
updatedSelectedCommunities.remove(event.communityId);
|
||||
updatedSelectedSpaces.removeWhere(childrenIds.contains);
|
||||
updatedSoldChecks.removeWhere(childrenIds.contains);
|
||||
}
|
||||
|
||||
emit(state.copyWith(
|
||||
selectedCommunities: updatedSelectedCommunities,
|
||||
selectedSpaces: updatedSelectedSpaces,
|
||||
soldCheck: updatedSoldChecks));
|
||||
} catch (e) {
|
||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||
}
|
||||
}
|
||||
|
||||
_onSpaceSelected(OnSpaceSelected event, Emitter<SpaceTreeState> emit) async {
|
||||
try {
|
||||
List<String> updatedSelectedCommunities = List.from(state.selectedCommunities);
|
||||
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces);
|
||||
List<String> updatedSoldChecks = List.from(state.soldCheck);
|
||||
|
||||
List<String> childrenIds = _getAllChildIds(event.children);
|
||||
|
||||
// List<String> childrenIds = _getAllChildSpaceIds(event.communityId);
|
||||
|
||||
if (!updatedSelectedSpaces.contains(event.spaceId) &&
|
||||
!updatedSoldChecks.contains(event.spaceId)) {
|
||||
// First click: Select the space and all its children
|
||||
updatedSelectedSpaces.add(event.spaceId);
|
||||
updatedSelectedCommunities.add(event.communityId);
|
||||
if (childrenIds.isNotEmpty) {
|
||||
updatedSelectedSpaces.addAll(childrenIds);
|
||||
}
|
||||
} else if (!updatedSoldChecks.contains(event.spaceId) && childrenIds.isNotEmpty) {
|
||||
// Second click: Unselect space but keep children
|
||||
updatedSelectedSpaces.remove(event.spaceId);
|
||||
updatedSoldChecks.add(event.spaceId);
|
||||
} else {
|
||||
// Third click: Unselect space and all its children
|
||||
if (!_anySpacesSelectedInCommunity(event.communityId)) {
|
||||
updatedSelectedCommunities.remove(event.communityId);
|
||||
}
|
||||
updatedSelectedSpaces.remove(event.spaceId);
|
||||
if (childrenIds.isNotEmpty) {
|
||||
updatedSelectedSpaces.removeWhere(childrenIds.contains);
|
||||
}
|
||||
updatedSoldChecks.remove(event.spaceId);
|
||||
}
|
||||
|
||||
emit(state.copyWith(
|
||||
selectedCommunities: updatedSelectedCommunities,
|
||||
selectedSpaces: updatedSelectedSpaces,
|
||||
soldCheck: updatedSoldChecks));
|
||||
emit(state.copyWith(selectedSpaces: updatedSelectedSpaces));
|
||||
} catch (e) {
|
||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||
}
|
||||
}
|
||||
|
||||
_onSearch(SearchQueryEvent event, Emitter<SpaceTreeState> emit) async {
|
||||
try {
|
||||
List<CommunityModel> communities = List.from(state.communityList);
|
||||
List<CommunityModel> filteredCommunity = [];
|
||||
|
||||
// Filter communities and expand only those that match the query
|
||||
filteredCommunity = communities.where((community) {
|
||||
final containsQueryInCommunity =
|
||||
community.name.toLowerCase().contains(event.searchQuery.toLowerCase());
|
||||
final containsQueryInSpaces =
|
||||
community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase()));
|
||||
|
||||
return containsQueryInCommunity || containsQueryInSpaces;
|
||||
}).toList();
|
||||
|
||||
emit(state.copyWith(
|
||||
filteredCommunity: filteredCommunity, isSearching: event.searchQuery.isNotEmpty));
|
||||
} catch (e) {
|
||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to determine if any space or its children match the search query
|
||||
bool _containsQuery(SpaceModel space, String query) {
|
||||
final matchesSpace = space.name.toLowerCase().contains(query);
|
||||
final matchesChildren =
|
||||
space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
|
||||
|
||||
return matchesSpace || matchesChildren;
|
||||
}
|
||||
|
||||
List<String> _getAllChildIds(List<SpaceModel> spaces) {
|
||||
List<String> ids = [];
|
||||
for (var child in spaces) {
|
||||
ids.add(child.uuid!);
|
||||
ids.addAll(_getAllChildIds(child.children));
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
bool _anySpacesSelectedInCommunity(String communityId) {
|
||||
bool result = false;
|
||||
for (var community in state.communityList) {
|
||||
if (community.uuid == communityId) {
|
||||
List<String> ids = _getAllChildIds(community.spaces);
|
||||
for (var id in ids) {
|
||||
result = state.selectedSpaces.contains(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
69
lib/pages/space_tree/bloc/space_tree_event.dart
Normal file
69
lib/pages/space_tree/bloc/space_tree_event.dart
Normal file
@ -0,0 +1,69 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||
|
||||
class SpaceTreeEvent extends Equatable {
|
||||
const SpaceTreeEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class InitialEvent extends SpaceTreeEvent {}
|
||||
|
||||
class SearchForSpace extends SpaceTreeEvent {
|
||||
final String searchQuery;
|
||||
|
||||
const SearchForSpace(this.searchQuery);
|
||||
|
||||
@override
|
||||
List<Object> get props => [searchQuery];
|
||||
}
|
||||
|
||||
class OnCommunityExpanded extends SpaceTreeEvent {
|
||||
final String communityId;
|
||||
|
||||
const OnCommunityExpanded(this.communityId);
|
||||
|
||||
@override
|
||||
List<Object> get props => [communityId];
|
||||
}
|
||||
|
||||
class OnCommunitySelected extends SpaceTreeEvent {
|
||||
final String communityId;
|
||||
final List<SpaceModel> children;
|
||||
|
||||
const OnCommunitySelected(this.communityId, this.children);
|
||||
|
||||
@override
|
||||
List<Object> get props => [communityId, children];
|
||||
}
|
||||
|
||||
class OnSpaceExpanded extends SpaceTreeEvent {
|
||||
final String communityId;
|
||||
final String spaceId;
|
||||
|
||||
const OnSpaceExpanded(this.communityId, this.spaceId);
|
||||
|
||||
@override
|
||||
List<Object> get props => [communityId, spaceId];
|
||||
}
|
||||
|
||||
class OnSpaceSelected extends SpaceTreeEvent {
|
||||
final String communityId;
|
||||
final String spaceId;
|
||||
final List<SpaceModel> children;
|
||||
|
||||
const OnSpaceSelected(this.communityId, this.spaceId, this.children);
|
||||
|
||||
@override
|
||||
List<Object> get props => [communityId, spaceId, children];
|
||||
}
|
||||
|
||||
class SearchQueryEvent extends SpaceTreeEvent {
|
||||
final String searchQuery;
|
||||
|
||||
const SearchQueryEvent(this.searchQuery);
|
||||
|
||||
@override
|
||||
List<Object> get props => [searchQuery];
|
||||
}
|
65
lib/pages/space_tree/bloc/space_tree_state.dart
Normal file
65
lib/pages/space_tree/bloc/space_tree_state.dart
Normal file
@ -0,0 +1,65 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||
|
||||
class SpaceTreeState extends Equatable {
|
||||
final List<CommunityModel> communityList;
|
||||
final List<CommunityModel> filteredCommunity;
|
||||
final List<String> expandedCommunities;
|
||||
final List<String> expandedSpaces;
|
||||
final List<String> selectedCommunities;
|
||||
final List<String> selectedSpaces;
|
||||
final List<String> soldCheck;
|
||||
final bool isSearching;
|
||||
|
||||
const SpaceTreeState(
|
||||
{this.communityList = const [],
|
||||
this.filteredCommunity = const [],
|
||||
this.expandedCommunities = const [],
|
||||
this.expandedSpaces = const [],
|
||||
this.selectedCommunities = const [],
|
||||
this.selectedSpaces = const [],
|
||||
this.soldCheck = const [],
|
||||
this.isSearching = false});
|
||||
|
||||
SpaceTreeState copyWith(
|
||||
{List<CommunityModel>? communitiesList,
|
||||
List<CommunityModel>? filteredCommunity,
|
||||
List<String>? expandedSpaces,
|
||||
List<String>? expandedCommunity,
|
||||
List<String>? selectedCommunities,
|
||||
List<String>? selectedSpaces,
|
||||
List<String>? soldCheck,
|
||||
bool? isSearching}) {
|
||||
return SpaceTreeState(
|
||||
communityList: communitiesList ?? this.communityList,
|
||||
filteredCommunity: filteredCommunity ?? this.filteredCommunity,
|
||||
expandedSpaces: expandedSpaces ?? this.expandedSpaces,
|
||||
expandedCommunities: expandedCommunity ?? this.expandedCommunities,
|
||||
selectedCommunities: selectedCommunities ?? this.selectedCommunities,
|
||||
selectedSpaces: selectedSpaces ?? this.selectedSpaces,
|
||||
soldCheck: soldCheck ?? this.soldCheck,
|
||||
isSearching: isSearching ?? this.isSearching);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
communityList,
|
||||
filteredCommunity,
|
||||
expandedSpaces,
|
||||
expandedCommunities,
|
||||
selectedCommunities,
|
||||
selectedSpaces,
|
||||
soldCheck,
|
||||
isSearching
|
||||
];
|
||||
}
|
||||
|
||||
class SpaceTreeLoadingState extends SpaceTreeState {}
|
||||
|
||||
class SpaceTreeErrorState extends SpaceTreeState {
|
||||
final String message;
|
||||
const SpaceTreeErrorState(this.message);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [message];
|
||||
}
|
99
lib/pages/space_tree/view/custom_expansion.dart
Normal file
99
lib/pages/space_tree/view/custom_expansion.dart
Normal file
@ -0,0 +1,99 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CustomExpansionTileSpaceTree extends StatelessWidget {
|
||||
final String? spaceId;
|
||||
final String title;
|
||||
final List<Widget>? children;
|
||||
final bool isSelected;
|
||||
final bool isSoldCheck;
|
||||
final bool isExpanded;
|
||||
final Function? onExpansionChanged;
|
||||
final Function? onItemSelected;
|
||||
|
||||
const CustomExpansionTileSpaceTree(
|
||||
{super.key,
|
||||
this.spaceId,
|
||||
required this.title,
|
||||
this.children,
|
||||
this.isExpanded = false,
|
||||
this.onExpansionChanged,
|
||||
this.onItemSelected,
|
||||
required this.isSelected,
|
||||
this.isSoldCheck = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Checkbox(
|
||||
value: isSoldCheck ? null : isSelected,
|
||||
onChanged: (bool? value) {
|
||||
if (onItemSelected != null) {
|
||||
onItemSelected!();
|
||||
}
|
||||
},
|
||||
tristate: true,
|
||||
side: WidgetStateBorderSide.resolveWith((states) {
|
||||
return const BorderSide(color: ColorsManager.grayBorder);
|
||||
}),
|
||||
fillColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return ColorsManager.blue1;
|
||||
} else {
|
||||
return ColorsManager.checkBoxFillColor;
|
||||
}
|
||||
}),
|
||||
checkColor: ColorsManager.whiteColors,
|
||||
),
|
||||
if (children != null && children!.isNotEmpty)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
if (onExpansionChanged != null) {
|
||||
onExpansionChanged!();
|
||||
}
|
||||
},
|
||||
child: Icon(
|
||||
isExpanded ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_right,
|
||||
color: ColorsManager.lightGrayColor,
|
||||
size: 16.0,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
if (onItemSelected != null) {
|
||||
onItemSelected!();
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
_capitalizeFirstLetter(title),
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
color: isSelected
|
||||
? ColorsManager.blackColor // Change color to black when selected
|
||||
: ColorsManager.lightGrayColor, // Gray when not selected
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isExpanded && children != null && children!.isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 48.0),
|
||||
child: Column(
|
||||
children: children ?? [],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
String _capitalizeFirstLetter(String text) {
|
||||
if (text.isEmpty) return text;
|
||||
return text[0].toUpperCase() + text.substring(1);
|
||||
}
|
||||
}
|
120
lib/pages/space_tree/view/side_tree_view.dart
Normal file
120
lib/pages/space_tree/view/side_tree_view.dart
Normal file
@ -0,0 +1,120 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/common/widgets/search_bar.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/view/custom_expansion.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/style.dart';
|
||||
|
||||
class SideTreeView extends StatelessWidget {
|
||||
const SideTreeView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SpaceTreeBloc, SpaceTreeState>(builder: (context, state) {
|
||||
List<CommunityModel> list = state.isSearching ? state.filteredCommunity : state.communityList;
|
||||
return Container(
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: subSectionContainerDecoration,
|
||||
// padding: const EdgeInsets.all(16.0),
|
||||
child: state is SpaceTreeLoadingState
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Column(
|
||||
children: [
|
||||
CustomSearchBar(
|
||||
onSearchChanged: (query) {
|
||||
context.read<SpaceTreeBloc>().add(SearchQueryEvent(query));
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: list.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
'No results found',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
color: ColorsManager.lightGrayColor, // Gray when not selected
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
)
|
||||
: ListView(
|
||||
shrinkWrap: true,
|
||||
children: list
|
||||
.map(
|
||||
(community) => CustomExpansionTileSpaceTree(
|
||||
title: community.name,
|
||||
isSelected:
|
||||
state.selectedCommunities.contains(community.uuid),
|
||||
isSoldCheck:
|
||||
state.selectedCommunities.contains(community.uuid),
|
||||
onExpansionChanged: () {
|
||||
context
|
||||
.read<SpaceTreeBloc>()
|
||||
.add(OnCommunityExpanded(community.uuid));
|
||||
},
|
||||
isExpanded:
|
||||
state.expandedCommunities.contains(community.uuid),
|
||||
onItemSelected: () {
|
||||
context.read<SpaceTreeBloc>().add(
|
||||
OnCommunitySelected(community.uuid, community.spaces));
|
||||
},
|
||||
children: community.spaces.map((space) {
|
||||
return CustomExpansionTileSpaceTree(
|
||||
title: space.name,
|
||||
isExpanded: state.expandedSpaces.contains(space.uuid),
|
||||
onItemSelected: () {
|
||||
context.read<SpaceTreeBloc>().add(OnSpaceSelected(
|
||||
community.uuid, space.uuid ?? '', space.children));
|
||||
},
|
||||
onExpansionChanged: () {
|
||||
context.read<SpaceTreeBloc>().add(
|
||||
OnSpaceExpanded(community.uuid, space.uuid ?? ''));
|
||||
},
|
||||
isSelected: state.selectedSpaces.contains(space.uuid) ||
|
||||
state.soldCheck.contains(space.uuid),
|
||||
isSoldCheck: state.soldCheck.contains(space.uuid),
|
||||
children: _buildNestedSpaces(
|
||||
context, state, space, community.uuid),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
List<Widget> _buildNestedSpaces(
|
||||
BuildContext context, SpaceTreeState state, SpaceModel space, String communityId) {
|
||||
return space.children.map((child) {
|
||||
return CustomExpansionTileSpaceTree(
|
||||
isSelected:
|
||||
state.selectedSpaces.contains(child.uuid) || state.soldCheck.contains(child.uuid),
|
||||
isSoldCheck: state.soldCheck.contains(child.uuid),
|
||||
title: child.name,
|
||||
isExpanded: state.expandedSpaces.contains(child.uuid),
|
||||
onItemSelected: () {
|
||||
context
|
||||
.read<SpaceTreeBloc>()
|
||||
.add(OnSpaceSelected(communityId, child.uuid ?? '', child.children));
|
||||
},
|
||||
onExpansionChanged: () {
|
||||
context.read<SpaceTreeBloc>().add(OnSpaceExpanded(communityId, child.uuid ?? ''));
|
||||
},
|
||||
children: _buildNestedSpaces(context, state, child, communityId),
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/common/custom_expansion_tile.dart';
|
||||
import 'package:syncrow_web/common/widgets/custom_expansion_tile.dart';
|
||||
|
||||
class CommunityTile extends StatelessWidget {
|
||||
final String title;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_web/common/search_bar.dart';
|
||||
import 'package:syncrow_web/common/widgets/search_bar.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||
@ -36,8 +36,7 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedId = widget
|
||||
.selectedSpaceUuid; // Initialize with the passed selected space UUID
|
||||
_selectedId = widget.selectedSpaceUuid; // Initialize with the passed selected space UUID
|
||||
}
|
||||
|
||||
@override
|
||||
@ -62,8 +61,8 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
||||
return widget.communities.where((community) {
|
||||
final containsQueryInCommunity =
|
||||
community.name.toLowerCase().contains(_searchQuery.toLowerCase());
|
||||
final containsQueryInSpaces = community.spaces
|
||||
.any((space) => _containsQuery(space, _searchQuery.toLowerCase()));
|
||||
final containsQueryInSpaces =
|
||||
community.spaces.any((space) => _containsQuery(space, _searchQuery.toLowerCase()));
|
||||
|
||||
return containsQueryInCommunity || containsQueryInSpaces;
|
||||
}).toList();
|
||||
@ -72,8 +71,8 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
||||
// Helper function to determine if any space or its children match the search query
|
||||
bool _containsQuery(SpaceModel space, String query) {
|
||||
final matchesSpace = space.name.toLowerCase().contains(query);
|
||||
final matchesChildren = space.children.any((child) =>
|
||||
_containsQuery(child, query)); // Recursive check for children
|
||||
final matchesChildren =
|
||||
space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
|
||||
|
||||
// If the space or any of its children match the query, expand this space
|
||||
if (matchesSpace || matchesChildren) {
|
||||
@ -107,8 +106,7 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
||||
width: 300,
|
||||
decoration: subSectionContainerDecoration,
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures the Column only takes necessary height
|
||||
mainAxisSize: MainAxisSize.min, // Ensures the Column only takes necessary height
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Communities title with the add button
|
||||
@ -224,14 +222,11 @@ class _SidebarWidgetState extends State<SidebarWidget> {
|
||||
});
|
||||
|
||||
context.read<SpaceManagementBloc>().add(
|
||||
SelectSpaceEvent(
|
||||
selectedCommunity: community, selectedSpace: space),
|
||||
SelectSpaceEvent(selectedCommunity: community, selectedSpace: space),
|
||||
);
|
||||
},
|
||||
children: space.children.isNotEmpty
|
||||
? space.children
|
||||
.map((childSpace) => _buildSpaceTile(childSpace, community))
|
||||
.toList()
|
||||
? space.children.map((childSpace) => _buildSpaceTile(childSpace, community)).toList()
|
||||
: [], // Recursively render child spaces if available
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/common/custom_expansion_tile.dart';
|
||||
import 'package:syncrow_web/common/widgets/custom_expansion_tile.dart';
|
||||
|
||||
class SpaceTile extends StatefulWidget {
|
||||
final String title;
|
||||
|
@ -9,12 +9,18 @@ import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_
|
||||
import 'package:syncrow_web/pages/visitor_password/model/device_model.dart';
|
||||
import 'package:syncrow_web/services/api/http_service.dart';
|
||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||
import 'package:syncrow_web/utils/constants/temp_const.dart';
|
||||
|
||||
class DevicesManagementApi {
|
||||
Future<List<AllDevicesModel>> fetchDevices() async {
|
||||
Future<List<AllDevicesModel>> fetchDevices(String communityId, String spaceId) async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.getAllDevices,
|
||||
path: communityId.isNotEmpty && spaceId.isNotEmpty
|
||||
? ApiEndpoints.getSpaceDevices
|
||||
.replaceAll('{spaceUuid}', spaceId)
|
||||
.replaceAll('{communityUuid}', communityId)
|
||||
.replaceAll('{projectId}', TempConst.projectId)
|
||||
: ApiEndpoints.getAllDevices,
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
List<dynamic> jsonData = json;
|
||||
@ -85,8 +91,7 @@ class DevicesManagementApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deviceBatchControl(
|
||||
List<String> uuids, String code, dynamic value) async {
|
||||
Future<bool> deviceBatchControl(List<String> uuids, String code, dynamic value) async {
|
||||
try {
|
||||
final body = {
|
||||
'devicesUuid': uuids,
|
||||
@ -110,8 +115,7 @@ class DevicesManagementApi {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
||||
String gatewayId) async {
|
||||
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
||||
showServerMessage: false,
|
||||
@ -145,9 +149,7 @@ class DevicesManagementApi {
|
||||
String code,
|
||||
) async {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.getDeviceLogs
|
||||
.replaceAll('{uuid}', uuid)
|
||||
.replaceAll('{code}', code),
|
||||
path: ApiEndpoints.getDeviceLogs.replaceAll('{uuid}', uuid).replaceAll('{code}', code),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return DeviceReport.fromJson(json);
|
||||
@ -220,8 +222,7 @@ class DevicesManagementApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> addScheduleRecord(
|
||||
ScheduleEntry sendSchedule, String uuid) async {
|
||||
Future<bool> addScheduleRecord(ScheduleEntry sendSchedule, String uuid) async {
|
||||
try {
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
||||
@ -238,8 +239,7 @@ class DevicesManagementApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<ScheduleModel>> getDeviceSchedules(
|
||||
String uuid, String category) async {
|
||||
Future<List<ScheduleModel>> getDeviceSchedules(String uuid, String category) async {
|
||||
try {
|
||||
final response = await HTTPService().get(
|
||||
path: ApiEndpoints.getScheduleByDeviceId
|
||||
@ -262,9 +262,7 @@ class DevicesManagementApi {
|
||||
}
|
||||
|
||||
Future<bool> updateScheduleRecord(
|
||||
{required bool enable,
|
||||
required String uuid,
|
||||
required String scheduleId}) async {
|
||||
{required bool enable, required String uuid, required String scheduleId}) async {
|
||||
try {
|
||||
final response = await HTTPService().put(
|
||||
path: ApiEndpoints.updateScheduleByDeviceId
|
||||
@ -285,8 +283,7 @@ class DevicesManagementApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> editScheduleRecord(
|
||||
String uuid, ScheduleEntry newSchedule) async {
|
||||
Future<bool> editScheduleRecord(String uuid, ScheduleEntry newSchedule) async {
|
||||
try {
|
||||
final response = await HTTPService().put(
|
||||
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
||||
|
@ -1,9 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/routine_details_model.dart';
|
||||
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_automation_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/create_scene_and_autoamtion/create_scene_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/icon_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/routine_details_model.dart';
|
||||
import 'package:syncrow_web/pages/routines/models/routine_model.dart';
|
||||
import 'package:syncrow_web/services/api/http_service.dart';
|
||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||
import 'package:syncrow_web/utils/constants/temp_const.dart';
|
||||
@ -12,8 +12,7 @@ class SceneApi {
|
||||
static final HTTPService _httpService = HTTPService();
|
||||
|
||||
// //create scene
|
||||
static Future<Map<String, dynamic>> createScene(
|
||||
CreateSceneModel createSceneModel) async {
|
||||
static Future<Map<String, dynamic>> createScene(CreateSceneModel createSceneModel) async {
|
||||
try {
|
||||
debugPrint('create scene model: ${createSceneModel.toMap()}');
|
||||
final response = await _httpService.post(
|
||||
@ -70,13 +69,12 @@ class SceneApi {
|
||||
|
||||
//get scenes by community id and space id
|
||||
|
||||
static Future<List<ScenesModel>> getScenesByUnitId(
|
||||
String unitId, String communityId,
|
||||
static Future<List<ScenesModel>> getScenes(String spaceId, String communityId,
|
||||
{showInDevice = false}) async {
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getUnitScenes
|
||||
.replaceAll('{spaceUuid}', unitId)
|
||||
.replaceAll('{spaceUuid}', spaceId)
|
||||
.replaceAll('{communityUuid}', communityId)
|
||||
.replaceAll('{projectId}', TempConst.projectId),
|
||||
queryParameters: {'showInHomePage': showInDevice},
|
||||
@ -99,10 +97,10 @@ class SceneApi {
|
||||
|
||||
//getAutomation
|
||||
|
||||
static Future<List<ScenesModel>> getAutomationByUnitId(String unitId) async {
|
||||
static Future<List<ScenesModel>> getAutomation(String spaceId) async {
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getSpaceAutomation.replaceAll('{unitUuid}', unitId),
|
||||
path: ApiEndpoints.getSpaceAutomation.replaceAll('{spaceUuid}', spaceId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
List<ScenesModel> scenes = [];
|
||||
@ -132,12 +130,10 @@ class SceneApi {
|
||||
// }
|
||||
|
||||
//automation details
|
||||
static Future<RoutineDetailsModel> getAutomationDetails(
|
||||
String automationId) async {
|
||||
static Future<RoutineDetailsModel> getAutomationDetails(String automationId) async {
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getAutomationDetails
|
||||
.replaceAll('{automationId}', automationId),
|
||||
path: ApiEndpoints.getAutomationDetails.replaceAll('{automationId}', automationId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => RoutineDetailsModel.fromMap(json),
|
||||
);
|
||||
@ -152,8 +148,7 @@ class SceneApi {
|
||||
try {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.updateScene.replaceAll('{sceneId}', sceneId),
|
||||
body: createSceneModel
|
||||
.toJson(sceneId.isNotEmpty == true ? sceneId : null),
|
||||
body: createSceneModel.toJson(sceneId.isNotEmpty == true ? sceneId : null),
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
@ -165,14 +160,11 @@ class SceneApi {
|
||||
}
|
||||
|
||||
//update automation
|
||||
static updateAutomation(
|
||||
CreateAutomationModel createAutomationModel, String automationId) async {
|
||||
static updateAutomation(CreateAutomationModel createAutomationModel, String automationId) async {
|
||||
try {
|
||||
final response = await _httpService.put(
|
||||
path: ApiEndpoints.updateAutomation
|
||||
.replaceAll('{automationId}', automationId),
|
||||
body: createAutomationModel
|
||||
.toJson(automationId.isNotEmpty == true ? automationId : null),
|
||||
path: ApiEndpoints.updateAutomation.replaceAll('{automationId}', automationId),
|
||||
body: createAutomationModel.toJson(automationId.isNotEmpty == true ? automationId : null),
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
@ -189,8 +181,7 @@ class SceneApi {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.getScene.replaceAll('{sceneId}', sceneId),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) =>
|
||||
RoutineDetailsModel.fromMap(json['data']),
|
||||
expectedResponseModel: (json) => RoutineDetailsModel.fromMap(json['data']),
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
@ -199,8 +190,7 @@ class SceneApi {
|
||||
}
|
||||
|
||||
//delete Scene
|
||||
static Future<bool> deleteScene(
|
||||
{required String unitUuid, required String sceneId}) async {
|
||||
static Future<bool> deleteScene({required String unitUuid, required String sceneId}) async {
|
||||
try {
|
||||
final response = await _httpService.delete(
|
||||
path: ApiEndpoints.deleteScene
|
||||
|
@ -12,14 +12,12 @@ abstract class ApiEndpoints {
|
||||
static const String visitorPassword = '/visitor-password';
|
||||
static const String getDevices = '/visitor-password/devices';
|
||||
|
||||
static const String sendOnlineOneTime =
|
||||
'/visitor-password/temporary-password/online/one-time';
|
||||
static const String sendOnlineOneTime = '/visitor-password/temporary-password/online/one-time';
|
||||
static const String sendOnlineMultipleTime =
|
||||
'/visitor-password/temporary-password/online/multiple-time';
|
||||
|
||||
//offline Password
|
||||
static const String sendOffLineOneTime =
|
||||
'/visitor-password/temporary-password/offline/one-time';
|
||||
static const String sendOffLineOneTime = '/visitor-password/temporary-password/offline/one-time';
|
||||
static const String sendOffLineMultipleTime =
|
||||
'/visitor-password/temporary-password/offline/multiple-time';
|
||||
|
||||
@ -28,6 +26,8 @@ abstract class ApiEndpoints {
|
||||
////// Devices Management ////////////////
|
||||
|
||||
static const String getAllDevices = '/device';
|
||||
static const String getSpaceDevices =
|
||||
'/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
|
||||
static const String getDeviceStatus = '/device/{uuid}/functions/status';
|
||||
static const String getBatchStatus = '/device/status/batch';
|
||||
|
||||
@ -39,57 +39,43 @@ abstract class ApiEndpoints {
|
||||
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
||||
|
||||
// Space Module
|
||||
static const String createSpace =
|
||||
'/projects/{projectId}/communities/{communityId}/spaces';
|
||||
static const String listSpaces =
|
||||
'/projects/{projectId}/communities/{communityId}/spaces';
|
||||
static const String createSpace = '/projects/{projectId}/communities/{communityId}/spaces';
|
||||
static const String listSpaces = '/projects/{projectId}/communities/{communityId}/spaces';
|
||||
static const String deleteSpace =
|
||||
'/projects/{projectId}/communities/{communityId}/spaces/{spaceId}';
|
||||
static const String updateSpace =
|
||||
'/projects/{projectId}/communities/{communityId}/spaces/{spaceId}';
|
||||
static const String getSpace =
|
||||
'/projects/{projectId}/communities/{communityId}/spaces/{spaceId}';
|
||||
static const String getSpaceHierarchy =
|
||||
'/projects/{projectId}/communities/{communityId}/spaces';
|
||||
static const String getSpace = '/projects/{projectId}/communities/{communityId}/spaces/{spaceId}';
|
||||
static const String getSpaceHierarchy = '/projects/{projectId}/communities/{communityId}/spaces';
|
||||
|
||||
// Community Module
|
||||
static const String createCommunity = '/projects/{projectId}/communities';
|
||||
static const String getCommunityList = '/projects/{projectId}/communities';
|
||||
static const String getCommunityById =
|
||||
'/projects/{projectId}/communities/{communityId}';
|
||||
static const String updateCommunity =
|
||||
'/projects/{projectId}/communities/{communityId}';
|
||||
static const String deleteCommunity =
|
||||
'/projects/{projectId}communities/{communityId}';
|
||||
static const String getUserCommunities =
|
||||
'/projects/{projectId}/communities/user/{userUuid}';
|
||||
static const String createUserCommunity =
|
||||
'/projects/{projectId}/communities/user';
|
||||
static const String getCommunityById = '/projects/{projectId}/communities/{communityId}';
|
||||
static const String updateCommunity = '/projects/{projectId}/communities/{communityId}';
|
||||
static const String deleteCommunity = '/projects/{projectId}communities/{communityId}';
|
||||
static const String getUserCommunities = '/projects/{projectId}/communities/user/{userUuid}';
|
||||
static const String createUserCommunity = '/projects/{projectId}/communities/user';
|
||||
static const String getDeviceLogsByDate =
|
||||
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
||||
|
||||
static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
|
||||
static const String getScheduleByDeviceId =
|
||||
'/schedule/{deviceUuid}?category={category}';
|
||||
static const String deleteScheduleByDeviceId =
|
||||
'/schedule/{deviceUuid}/{scheduleUuid}';
|
||||
static const String updateScheduleByDeviceId =
|
||||
'/schedule/enable/{deviceUuid}';
|
||||
static const String getScheduleByDeviceId = '/schedule/{deviceUuid}?category={category}';
|
||||
static const String deleteScheduleByDeviceId = '/schedule/{deviceUuid}/{scheduleUuid}';
|
||||
static const String updateScheduleByDeviceId = '/schedule/enable/{deviceUuid}';
|
||||
static const String factoryReset = '/device/factory/reset/{deviceUuid}';
|
||||
static const String powerClamp =
|
||||
'/device/{powerClampUuid}/power-clamp/status';
|
||||
static const String powerClamp = '/device/{powerClampUuid}/power-clamp/status';
|
||||
|
||||
//product
|
||||
static const String listProducts = '/products';
|
||||
static const String getSpaceScenes = '/scene/tap-to-run/{unitUuid}';
|
||||
static const String getSpaceAutomation = '/automation/{unitUuid}';
|
||||
static const String getSpaceScenes = '/scene/tap-to-run/{spaceUuid}';
|
||||
static const String getSpaceAutomation = '/automation/{spaceUuid}';
|
||||
static const String getIconScene = '/scene/icon';
|
||||
static const String createScene = '/scene/tap-to-run';
|
||||
static const String createAutomation = '/automation';
|
||||
static const String getUnitScenes =
|
||||
'/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
|
||||
static const String getAutomationDetails =
|
||||
'/automation/details/{automationId}';
|
||||
static const String getAutomationDetails = '/automation/details/{automationId}';
|
||||
static const String getScene = '/scene/tap-to-run/{sceneId}';
|
||||
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
|
||||
|
||||
@ -101,10 +87,8 @@ abstract class ApiEndpoints {
|
||||
//space model
|
||||
static const String listSpaceModels = '/projects/{projectId}/space-models';
|
||||
static const String createSpaceModel = '/projects/{projectId}/space-models';
|
||||
static const String getSpaceModel =
|
||||
'/projects/{projectId}/space-models/{spaceModelUuid}';
|
||||
static const String updateSpaceModel =
|
||||
'/projects/{projectId}/space-models/{spaceModelUuid}';
|
||||
static const String getSpaceModel = '/projects/{projectId}/space-models/{spaceModelUuid}';
|
||||
static const String updateSpaceModel = '/projects/{projectId}/space-models/{spaceModelUuid}';
|
||||
|
||||
static const String roleTypes = '/role/types';
|
||||
static const String permission = '/permission/{roleUuid}';
|
||||
@ -115,8 +99,7 @@ abstract class ApiEndpoints {
|
||||
static const String getUserById = '/projects/${projectUuid}/user/{userUuid}';
|
||||
static const String editUser = '/invite-user/{inviteUserUuid}';
|
||||
static const String deleteUser = '/invite-user/{inviteUserUuid}';
|
||||
static const String changeUserStatus =
|
||||
'/invite-user/{invitedUserUuid}/disable';
|
||||
static const String changeUserStatus = '/invite-user/{invitedUserUuid}/disable';
|
||||
static const String terms = '/terms';
|
||||
static const String policy = '/policy';
|
||||
static const String userAgreements = '/user/agreements/web/{userUuid}';
|
||||
|
138
pubspec.lock
138
pubspec.lock
@ -53,10 +53,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -65,6 +65,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.6"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.17.3"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -182,6 +190,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.0"
|
||||
flutter_html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_html
|
||||
sha256: "02ad69e813ecfc0728a455e4bf892b9379983e050722b1dce00192ee2e41d1ee"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0-beta.2"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -280,6 +296,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.4"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -324,18 +348,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.4"
|
||||
version: "10.0.7"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
version: "3.0.8"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -352,6 +376,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
list_counter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: list_counter
|
||||
sha256: c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -372,18 +404,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.0"
|
||||
version: "0.11.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
|
||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.0"
|
||||
version: "1.15.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -556,7 +588,7 @@ packages:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
version: "0.0.0"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -577,10 +609,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.12.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -593,10 +625,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -609,10 +641,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0"
|
||||
version: "0.7.3"
|
||||
time_picker_spinner:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -629,6 +661,70 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
url_launcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: url_launcher
|
||||
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.1"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.14"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.2"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_linux
|
||||
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
url_launcher_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
url_launcher_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_platform_interface
|
||||
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
url_launcher_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_windows
|
||||
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
uuid:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -673,10 +769,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.1"
|
||||
version: "14.3.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -710,5 +806,5 @@ packages:
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
sdks:
|
||||
dart: ">=3.4.0 <4.0.0"
|
||||
flutter: ">=3.22.0"
|
||||
dart: ">=3.6.0 <4.0.0"
|
||||
flutter: ">=3.27.0"
|
||||
|
Reference in New Issue
Block a user