mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
push calling create scene
This commit is contained in:
@ -18,6 +18,7 @@ class StatefulTextField extends StatefulWidget {
|
|||||||
this.padding,
|
this.padding,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.hintColor,
|
this.hintColor,
|
||||||
|
required this.onChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
@ -32,6 +33,7 @@ class StatefulTextField extends StatefulWidget {
|
|||||||
final double? padding;
|
final double? padding;
|
||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
final Color? hintColor;
|
final Color? hintColor;
|
||||||
|
final Function(String)? onChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulTextField> createState() => _StatefulTextFieldState();
|
State<StatefulTextField> createState() => _StatefulTextFieldState();
|
||||||
@ -59,6 +61,7 @@ class _StatefulTextFieldState extends State<StatefulTextField> {
|
|||||||
padding: widget.padding,
|
padding: widget.padding,
|
||||||
icon: widget.icon,
|
icon: widget.icon,
|
||||||
hintColor: widget.hintColor,
|
hintColor: widget.hintColor,
|
||||||
|
onChanged: widget.onChanged,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,6 +81,7 @@ class CustomTextField extends StatelessWidget {
|
|||||||
this.padding,
|
this.padding,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.hintColor,
|
this.hintColor,
|
||||||
|
required this.onChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
@ -92,6 +96,7 @@ class CustomTextField extends StatelessWidget {
|
|||||||
final double? padding;
|
final double? padding;
|
||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
final Color? hintColor;
|
final Color? hintColor;
|
||||||
|
final Function(String)? onChanged;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -120,14 +125,21 @@ class CustomTextField extends StatelessWidget {
|
|||||||
style: const TextStyle(color: Colors.black),
|
style: const TextStyle(color: Colors.black),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: hintText,
|
hintText: hintText,
|
||||||
hintStyle: TextStyle(fontSize: 12, color: hintColor ?? ColorsManager.blackColor),
|
hintStyle: TextStyle(
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: padding ?? 10),
|
fontSize: 12, color: hintColor ?? ColorsManager.blackColor),
|
||||||
|
contentPadding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 12, vertical: padding ?? 10),
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
suffixIcon: icon != null ? Icon(icon, color: ColorsManager.greyColor) : null,
|
suffixIcon: icon != null
|
||||||
|
? Icon(icon, color: ColorsManager.greyColor)
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
onFieldSubmitted: (_) {
|
onFieldSubmitted: (_) {
|
||||||
onSubmittedFun!();
|
onSubmittedFun!();
|
||||||
},
|
},
|
||||||
|
onChanged: (value) {
|
||||||
|
onChanged!(value);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -2,8 +2,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
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/bloc/device_mgmt_bloc/device_managment_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_bloc.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/bloc/switch_tabs/switch_tabs_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/device_managment/shared/navigate_home_grid_view.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/view/create_new_routine_view.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/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
@ -20,7 +22,8 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
create: (context) => DeviceManagementBloc()..add(FetchDevices()),
|
create: (context) => DeviceManagementBloc()..add(FetchDevices()),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => SwitchTabsBloc()..add(const TriggerSwitchTabsEvent(false)),
|
create: (context) =>
|
||||||
|
SwitchTabsBloc()..add(const TriggerSwitchTabsEvent(false)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: WebScaffold(
|
child: WebScaffold(
|
||||||
@ -30,7 +33,8 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
style: Theme.of(context).textTheme.headlineLarge,
|
style: Theme.of(context).textTheme.headlineLarge,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
centerBody: BlocBuilder<SwitchTabsBloc, SwitchTabsState>(builder: (context, state) {
|
centerBody: BlocBuilder<SwitchTabsBloc, SwitchTabsState>(
|
||||||
|
builder: (context, state) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
@ -39,16 +43,21 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
backgroundColor: null,
|
backgroundColor: null,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<SwitchTabsBloc>().add(const TriggerSwitchTabsEvent(false));
|
context
|
||||||
|
.read<SwitchTabsBloc>()
|
||||||
|
.add(const TriggerSwitchTabsEvent(false));
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Devices',
|
'Devices',
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
style: context.textTheme.titleMedium?.copyWith(
|
||||||
color: state is SelectedTabState && state.selectedTab == false
|
color:
|
||||||
? ColorsManager.whiteColors
|
state is SelectedTabState && state.selectedTab == false
|
||||||
: ColorsManager.grayColor,
|
? ColorsManager.whiteColors
|
||||||
fontWeight:
|
: ColorsManager.grayColor,
|
||||||
(state is SelectedTabState) && state.selectedTab == false ? FontWeight.w700 : FontWeight.w400,
|
fontWeight: (state is SelectedTabState) &&
|
||||||
|
state.selectedTab == false
|
||||||
|
? FontWeight.w700
|
||||||
|
: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -57,16 +66,21 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
backgroundColor: null,
|
backgroundColor: null,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<SwitchTabsBloc>().add(const TriggerSwitchTabsEvent(true));
|
context
|
||||||
|
.read<SwitchTabsBloc>()
|
||||||
|
.add(const TriggerSwitchTabsEvent(true));
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Routines',
|
'Routines',
|
||||||
style: context.textTheme.titleMedium?.copyWith(
|
style: context.textTheme.titleMedium?.copyWith(
|
||||||
color: (state is SelectedTabState) && state.selectedTab == true
|
color:
|
||||||
? ColorsManager.whiteColors
|
(state is SelectedTabState) && state.selectedTab == true
|
||||||
: ColorsManager.grayColor,
|
? ColorsManager.whiteColors
|
||||||
|
: ColorsManager.grayColor,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
(state is SelectedTabState) && state.selectedTab == true ? FontWeight.w700 : FontWeight.w400,
|
(state is SelectedTabState) && state.selectedTab == true
|
||||||
|
? FontWeight.w700
|
||||||
|
: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -74,30 +88,31 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
rightBody: const NavigateHomeGridView(),
|
rightBody: const NavigateHomeGridView(),
|
||||||
scaffoldBody: CreateNewRoutineView(),
|
scaffoldBody: BlocBuilder<SwitchTabsBloc, SwitchTabsState>(
|
||||||
// BlocBuilder<SwitchTabsBloc, SwitchTabsState>(builder: (context, state) {
|
builder: (context, state) {
|
||||||
// if (state is SelectedTabState && state.selectedTab) {
|
if (state is SelectedTabState && state.selectedTab) {
|
||||||
// return const RoutinesView();
|
return const RoutinesView();
|
||||||
// }
|
}
|
||||||
// if (state is ShowCreateRoutineState && state.showCreateRoutine) {
|
if (state is ShowCreateRoutineState && state.showCreateRoutine) {
|
||||||
// return const CreateNewRoutineView();
|
return const CreateNewRoutineView();
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
return BlocBuilder<DeviceManagementBloc, DeviceManagementState>(
|
||||||
// builder: (context, deviceState) {
|
builder: (context, deviceState) {
|
||||||
// if (deviceState is DeviceManagementLoading) {
|
if (deviceState is DeviceManagementLoading) {
|
||||||
// return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
// } else if (deviceState is DeviceManagementLoaded || deviceState is DeviceManagementFiltered) {
|
} else if (deviceState is DeviceManagementLoaded ||
|
||||||
// final devices =
|
deviceState is DeviceManagementFiltered) {
|
||||||
// (deviceState as dynamic).devices ?? (deviceState as DeviceManagementFiltered).filteredDevices;
|
final devices = (deviceState as dynamic).devices ??
|
||||||
//
|
(deviceState as DeviceManagementFiltered).filteredDevices;
|
||||||
// return DeviceManagementBody(devices: devices);
|
|
||||||
// } else {
|
return DeviceManagementBody(devices: devices);
|
||||||
// return const Center(child: Text('Error fetching Devices'));
|
} else {
|
||||||
// }
|
return const Center(child: Text('Error fetching Devices'));
|
||||||
// },
|
}
|
||||||
// );
|
},
|
||||||
// }),
|
);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ class DeviceSearchFilters extends StatefulWidget {
|
|||||||
State<DeviceSearchFilters> createState() => _DeviceSearchFiltersState();
|
State<DeviceSearchFilters> createState() => _DeviceSearchFiltersState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DeviceSearchFiltersState extends State<DeviceSearchFilters> with HelperResponsiveLayout {
|
class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
|
||||||
|
with HelperResponsiveLayout {
|
||||||
final TextEditingController communityController = TextEditingController();
|
final TextEditingController communityController = TextEditingController();
|
||||||
final TextEditingController unitNameController = TextEditingController();
|
final TextEditingController unitNameController = TextEditingController();
|
||||||
final TextEditingController productNameController = TextEditingController();
|
final TextEditingController productNameController = TextEditingController();
|
||||||
@ -34,7 +35,8 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters> with HelperRe
|
|||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
_buildSearchField("Space Name", unitNameController, 200),
|
_buildSearchField("Space Name", unitNameController, 200),
|
||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
_buildSearchField("Device Name / Product Name", productNameController, 300),
|
_buildSearchField(
|
||||||
|
"Device Name / Product Name", productNameController, 300),
|
||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
_buildSearchResetButtons(),
|
_buildSearchResetButtons(),
|
||||||
],
|
],
|
||||||
@ -59,7 +61,8 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters> with HelperRe
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSearchField(String title, TextEditingController controller, double width) {
|
Widget _buildSearchField(
|
||||||
|
String title, TextEditingController controller, double width) {
|
||||||
return Container(
|
return Container(
|
||||||
child: StatefulTextField(
|
child: StatefulTextField(
|
||||||
title: title,
|
title: title,
|
||||||
@ -73,6 +76,7 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters> with HelperRe
|
|||||||
community: communityController.text,
|
community: communityController.text,
|
||||||
searchField: true));
|
searchField: true));
|
||||||
},
|
},
|
||||||
|
onChanged: (p0) {},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/routiens/models/create_scene/create_scene_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
import 'package:syncrow_web/pages/routiens/models/device_functions.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
||||||
import 'package:syncrow_web/services/routines_api.dart';
|
import 'package:syncrow_web/services/routines_api.dart';
|
||||||
@ -20,6 +23,9 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
on<LoadScenes>(_onLoadScenes);
|
on<LoadScenes>(_onLoadScenes);
|
||||||
on<LoadAutomation>(_onLoadAutomation);
|
on<LoadAutomation>(_onLoadAutomation);
|
||||||
on<AddFunctionToRoutine>(_onAddFunctionsToRoutine);
|
on<AddFunctionToRoutine>(_onAddFunctionsToRoutine);
|
||||||
|
on<SearchRoutines>(_onSearchRoutines);
|
||||||
|
on<AddSelectedIcon>(_onAddSelectedIcon);
|
||||||
|
on<CreateSceneEvent>(_onCreateScene);
|
||||||
// on<RemoveFunction>(_onRemoveFunction);
|
// on<RemoveFunction>(_onRemoveFunction);
|
||||||
// on<ClearFunctions>(_onClearFunctions);
|
// on<ClearFunctions>(_onClearFunctions);
|
||||||
}
|
}
|
||||||
@ -40,8 +46,6 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
|
|
||||||
void _onAddFunctionsToRoutine(
|
void _onAddFunctionsToRoutine(
|
||||||
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
|
||||||
debugPrint('Adding functions to routine: ${event.functions}');
|
|
||||||
debugPrint('Unique Custom ID: ${event.uniqueCustomId}');
|
|
||||||
final currentSelectedFunctions =
|
final currentSelectedFunctions =
|
||||||
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
|
||||||
|
|
||||||
@ -52,7 +56,6 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
emit(state.copyWith(selectedFunctions: currentSelectedFunctions));
|
||||||
debugPrint('Updated selected functions: $currentSelectedFunctions');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// void _onRemoveFunction(RemoveFunction event, Emitter<RoutineState> emit) {
|
// void _onRemoveFunction(RemoveFunction event, Emitter<RoutineState> emit) {
|
||||||
@ -80,7 +83,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
errorMessage: 'Something went wrong',
|
errorMessage: 'Failed to load scenes',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,7 +101,97 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
errorMessage: 'Something went wrong',
|
errorMessage: 'Failed to load automations',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FutureOr<void> _onSearchRoutines(
|
||||||
|
SearchRoutines event, Emitter<RoutineState> emit) {
|
||||||
|
emit(state.copyWith(routineName: event.query));
|
||||||
|
}
|
||||||
|
|
||||||
|
FutureOr<void> _onAddSelectedIcon(
|
||||||
|
AddSelectedIcon event, Emitter<RoutineState> emit) {
|
||||||
|
emit(state.copyWith(selectedIcon: event.icon));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isFirstActionDelay(List<Map<String, dynamic>> actions) {
|
||||||
|
if (actions.isEmpty) return false;
|
||||||
|
return actions.first['deviceId'] == 'delay';
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onCreateScene(
|
||||||
|
CreateSceneEvent event, Emitter<RoutineState> emit) async {
|
||||||
|
try {
|
||||||
|
// Check if first action is delay
|
||||||
|
if (_isFirstActionDelay(state.thenItems)) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
errorMessage: 'Cannot have delay as the first action',
|
||||||
|
isLoading: false,
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(state.copyWith(isLoading: true));
|
||||||
|
|
||||||
|
final actions = state.thenItems
|
||||||
|
.map((item) {
|
||||||
|
final functions =
|
||||||
|
state.selectedFunctions[item['uniqueCustomId']] ?? [];
|
||||||
|
if (functions.isEmpty) return null;
|
||||||
|
|
||||||
|
final function = functions.first;
|
||||||
|
if (item['deviceId'] == 'delay') {
|
||||||
|
return CreateSceneAction(
|
||||||
|
entityId: function.entityId,
|
||||||
|
actionExecutor: 'delay',
|
||||||
|
executorProperty: CreateSceneExecutorProperty(
|
||||||
|
functionCode: '',
|
||||||
|
functionValue: '',
|
||||||
|
delaySeconds: function.value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateSceneAction(
|
||||||
|
entityId: function.entityId,
|
||||||
|
actionExecutor: 'device_issue',
|
||||||
|
executorProperty: CreateSceneExecutorProperty(
|
||||||
|
functionCode: function.functionCode.toString(),
|
||||||
|
functionValue: function.value,
|
||||||
|
delaySeconds: 0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.whereType<CreateSceneAction>()
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
final createSceneModel = CreateSceneModel(
|
||||||
|
spaceUuid: spaceId,
|
||||||
|
iconId: state.selectedIcon ?? '',
|
||||||
|
showInDevice: true,
|
||||||
|
sceneName: state.routineName ?? '',
|
||||||
|
decisionExpr: 'and',
|
||||||
|
actions: actions,
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await SceneApi.createScene(createSceneModel);
|
||||||
|
if (result['success']) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: null,
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: result['message'],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: e.toString(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,4 +59,24 @@ class RemoveFunction extends RoutineEvent {
|
|||||||
List<Object> get props => [function];
|
List<Object> get props => [function];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SearchRoutines extends RoutineEvent {
|
||||||
|
final String query;
|
||||||
|
const SearchRoutines(this.query);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [query];
|
||||||
|
}
|
||||||
|
|
||||||
|
class AddSelectedIcon extends RoutineEvent {
|
||||||
|
final String icon;
|
||||||
|
const AddSelectedIcon(this.icon);
|
||||||
|
@override
|
||||||
|
List<Object> get props => [icon];
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreateSceneEvent extends RoutineEvent {
|
||||||
|
const CreateSceneEvent();
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
class ClearFunctions extends RoutineEvent {}
|
class ClearFunctions extends RoutineEvent {}
|
||||||
|
@ -9,6 +9,8 @@ class RoutineState extends Equatable {
|
|||||||
final Map<String, List<DeviceFunctionData>> selectedFunctions;
|
final Map<String, List<DeviceFunctionData>> selectedFunctions;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
final String? errorMessage;
|
final String? errorMessage;
|
||||||
|
final String? routineName;
|
||||||
|
final String? selectedIcon;
|
||||||
|
|
||||||
const RoutineState({
|
const RoutineState({
|
||||||
this.ifItems = const [],
|
this.ifItems = const [],
|
||||||
@ -19,6 +21,8 @@ class RoutineState extends Equatable {
|
|||||||
this.selectedFunctions = const {},
|
this.selectedFunctions = const {},
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
this.errorMessage,
|
this.errorMessage,
|
||||||
|
this.routineName,
|
||||||
|
this.selectedIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
RoutineState copyWith({
|
RoutineState copyWith({
|
||||||
@ -29,6 +33,8 @@ class RoutineState extends Equatable {
|
|||||||
Map<String, List<DeviceFunctionData>>? selectedFunctions,
|
Map<String, List<DeviceFunctionData>>? selectedFunctions,
|
||||||
bool? isLoading,
|
bool? isLoading,
|
||||||
String? errorMessage,
|
String? errorMessage,
|
||||||
|
String? routineName,
|
||||||
|
String? selectedIcon,
|
||||||
}) {
|
}) {
|
||||||
return RoutineState(
|
return RoutineState(
|
||||||
ifItems: ifItems ?? this.ifItems,
|
ifItems: ifItems ?? this.ifItems,
|
||||||
@ -38,6 +44,8 @@ class RoutineState extends Equatable {
|
|||||||
selectedFunctions: selectedFunctions ?? this.selectedFunctions,
|
selectedFunctions: selectedFunctions ?? this.selectedFunctions,
|
||||||
isLoading: isLoading ?? this.isLoading,
|
isLoading: isLoading ?? this.isLoading,
|
||||||
errorMessage: errorMessage ?? this.errorMessage,
|
errorMessage: errorMessage ?? this.errorMessage,
|
||||||
|
routineName: routineName ?? this.routineName,
|
||||||
|
selectedIcon: selectedIcon ?? this.selectedIcon,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,5 +58,7 @@ class RoutineState extends Equatable {
|
|||||||
selectedFunctions,
|
selectedFunctions,
|
||||||
isLoading,
|
isLoading,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
|
routineName,
|
||||||
|
selectedIcon,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
132
lib/pages/routiens/helper/save_routine_helper.dart
Normal file
132
lib/pages/routiens/helper/save_routine_helper.dart
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
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/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
|
class SaveRoutineHelper {
|
||||||
|
static Future<void> showSaveRoutineDialog(BuildContext context) async {
|
||||||
|
return showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return BlocBuilder<RoutineBloc, RoutineState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return AlertDialog(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
content: Container(
|
||||||
|
width: 600,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
DialogHeader('Create a scene: ${state.routineName ?? ""}'),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Left side - IF
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'IF:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
if (context.read<RoutineBloc>().isTabToRun)
|
||||||
|
ListTile(
|
||||||
|
leading: SvgPicture.asset(
|
||||||
|
Assets.tabToRun,
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
title: const Text('Tab to run'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
// Right side - THEN items
|
||||||
|
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'THEN:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
...state.thenItems.map((item) {
|
||||||
|
final functions = state.selectedFunctions[
|
||||||
|
item['uniqueCustomId']] ??
|
||||||
|
[];
|
||||||
|
return ListTile(
|
||||||
|
leading: SvgPicture.asset(
|
||||||
|
item['imagePath'],
|
||||||
|
width: 22,
|
||||||
|
height: 22,
|
||||||
|
),
|
||||||
|
title: Text(item['title'],
|
||||||
|
style: const TextStyle(fontSize: 14)),
|
||||||
|
subtitle: Wrap(
|
||||||
|
children: functions
|
||||||
|
.map((f) => Text(
|
||||||
|
'${f.operationName}: ${f.value}, ',
|
||||||
|
style: const TextStyle(
|
||||||
|
color:
|
||||||
|
ColorsManager.grayColor,
|
||||||
|
fontSize: 8),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 3,
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (state.errorMessage != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
state.errorMessage!,
|
||||||
|
style: const TextStyle(color: Colors.red),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DialogFooter(
|
||||||
|
onCancel: () => Navigator.pop(context),
|
||||||
|
onConfirm: () {
|
||||||
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(const CreateSceneEvent());
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
isConfirmEnabled: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -10,13 +10,16 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
class SettingHelper {
|
class SettingHelper {
|
||||||
static Future<Map<String, dynamic>?> showSettingDialog(
|
static Future<String?> showSettingDialog(
|
||||||
{required BuildContext context, String? iconId, required bool isAutomation}) async {
|
{required BuildContext context,
|
||||||
return showDialog<Map<String, dynamic>?>(
|
String? iconId,
|
||||||
|
required bool isAutomation}) async {
|
||||||
|
return showDialog<String>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (_) => SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? '')),
|
create: (_) =>
|
||||||
|
SettingBloc()..add(InitialEvent(selectedIcon: iconId ?? '')),
|
||||||
child: AlertDialog(
|
child: AlertDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
content: BlocBuilder<SettingBloc, SettingState>(
|
content: BlocBuilder<SettingBloc, SettingState>(
|
||||||
@ -29,7 +32,9 @@ class SettingHelper {
|
|||||||
}
|
}
|
||||||
return Container(
|
return Container(
|
||||||
width: context.read<SettingBloc>().isExpanded ? 800 : 400,
|
width: context.read<SettingBloc>().isExpanded ? 800 : 400,
|
||||||
height: context.read<SettingBloc>().isExpanded && isAutomation ? 500 : 300,
|
height: context.read<SettingBloc>().isExpanded && isAutomation
|
||||||
|
? 500
|
||||||
|
: 300,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
@ -52,13 +57,18 @@ class SettingHelper {
|
|||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
top: 10, left: 10, right: 10, bottom: 10),
|
top: 10,
|
||||||
|
left: 10,
|
||||||
|
right: 10,
|
||||||
|
bottom: 10),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Validity',
|
'Validity',
|
||||||
@ -66,13 +76,18 @@ class SettingHelper {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager
|
||||||
fontWeight: FontWeight.w400,
|
.textPrimaryColor,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight
|
||||||
|
.w400,
|
||||||
fontSize: 14),
|
fontSize: 14),
|
||||||
),
|
),
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.arrow_forward_ios_outlined,
|
Icons
|
||||||
color: ColorsManager.textGray,
|
.arrow_forward_ios_outlined,
|
||||||
|
color: ColorsManager
|
||||||
|
.textGray,
|
||||||
size: 15,
|
size: 15,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -89,14 +104,18 @@ class SettingHelper {
|
|||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<SettingBloc>(context).add(
|
BlocProvider.of<SettingBloc>(
|
||||||
FetchIcons(
|
context)
|
||||||
|
.add(FetchIcons(
|
||||||
expanded: !context
|
expanded: !context
|
||||||
.read<SettingBloc>()
|
.read<
|
||||||
|
SettingBloc>()
|
||||||
.isExpanded));
|
.isExpanded));
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Effective Period',
|
'Effective Period',
|
||||||
@ -104,13 +123,18 @@ class SettingHelper {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager
|
||||||
fontWeight: FontWeight.w400,
|
.textPrimaryColor,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight
|
||||||
|
.w400,
|
||||||
fontSize: 14),
|
fontSize: 14),
|
||||||
),
|
),
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.arrow_forward_ios_outlined,
|
Icons
|
||||||
color: ColorsManager.textGray,
|
.arrow_forward_ios_outlined,
|
||||||
|
color: ColorsManager
|
||||||
|
.textGray,
|
||||||
size: 15,
|
size: 15,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -126,7 +150,9 @@ class SettingHelper {
|
|||||||
height: 5,
|
height: 5,
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Executed by',
|
'Executed by',
|
||||||
@ -134,8 +160,10 @@ class SettingHelper {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager
|
||||||
fontWeight: FontWeight.w400,
|
.textPrimaryColor,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight.w400,
|
||||||
fontSize: 14),
|
fontSize: 14),
|
||||||
),
|
),
|
||||||
Text('Cloud',
|
Text('Cloud',
|
||||||
@ -143,8 +171,12 @@ class SettingHelper {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: ColorsManager.textGray,
|
color:
|
||||||
fontWeight: FontWeight.w400,
|
ColorsManager
|
||||||
|
.textGray,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight
|
||||||
|
.w400,
|
||||||
fontSize: 14)),
|
fontSize: 14)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -157,19 +189,26 @@ class SettingHelper {
|
|||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
top: 10, left: 10, right: 10, bottom: 10),
|
top: 10,
|
||||||
|
left: 10,
|
||||||
|
right: 10,
|
||||||
|
bottom: 10),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<SettingBloc>(context).add(
|
BlocProvider.of<SettingBloc>(
|
||||||
FetchIcons(
|
context)
|
||||||
|
.add(FetchIcons(
|
||||||
expanded: !context
|
expanded: !context
|
||||||
.read<SettingBloc>()
|
.read<
|
||||||
|
SettingBloc>()
|
||||||
.isExpanded));
|
.isExpanded));
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Icons',
|
'Icons',
|
||||||
@ -177,13 +216,18 @@ class SettingHelper {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager
|
||||||
fontWeight: FontWeight.w400,
|
.textPrimaryColor,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight
|
||||||
|
.w400,
|
||||||
fontSize: 14),
|
fontSize: 14),
|
||||||
),
|
),
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.arrow_forward_ios_outlined,
|
Icons
|
||||||
color: ColorsManager.textGray,
|
.arrow_forward_ios_outlined,
|
||||||
|
color: ColorsManager
|
||||||
|
.textGray,
|
||||||
size: 15,
|
size: 15,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -199,7 +243,9 @@ class SettingHelper {
|
|||||||
height: 5,
|
height: 5,
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Show on devices page',
|
'Show on devices page',
|
||||||
@ -207,17 +253,21 @@ class SettingHelper {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager
|
||||||
fontWeight: FontWeight.w400,
|
.textPrimaryColor,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight.w400,
|
||||||
fontSize: 14),
|
fontSize: 14),
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
height: 30,
|
height: 30,
|
||||||
width: 1,
|
width: 1,
|
||||||
color: ColorsManager.graysColor,
|
color: ColorsManager
|
||||||
|
.graysColor,
|
||||||
),
|
),
|
||||||
Transform.scale(
|
Transform.scale(
|
||||||
scale: .8,
|
scale: .8,
|
||||||
@ -241,7 +291,9 @@ class SettingHelper {
|
|||||||
height: 5,
|
height: 5,
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Executed by',
|
'Executed by',
|
||||||
@ -249,8 +301,10 @@ class SettingHelper {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: ColorsManager.textPrimaryColor,
|
color: ColorsManager
|
||||||
fontWeight: FontWeight.w400,
|
.textPrimaryColor,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight.w400,
|
||||||
fontSize: 14),
|
fontSize: 14),
|
||||||
),
|
),
|
||||||
Text('Cloud',
|
Text('Cloud',
|
||||||
@ -258,8 +312,12 @@ class SettingHelper {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: ColorsManager.textGray,
|
color:
|
||||||
fontWeight: FontWeight.w400,
|
ColorsManager
|
||||||
|
.textGray,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight
|
||||||
|
.w400,
|
||||||
fontSize: 14)),
|
fontSize: 14)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -268,12 +326,14 @@ class SettingHelper {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (context.read<SettingBloc>().isExpanded && !isAutomation)
|
if (context.read<SettingBloc>().isExpanded &&
|
||||||
|
!isAutomation)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 150,
|
height: 150,
|
||||||
child: state is LoadingState
|
child: state is LoadingState
|
||||||
? const Center(child: CircularProgressIndicator())
|
? const Center(
|
||||||
|
child: CircularProgressIndicator())
|
||||||
: GridView.builder(
|
: GridView.builder(
|
||||||
gridDelegate:
|
gridDelegate:
|
||||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
@ -290,7 +350,8 @@ class SettingHelper {
|
|||||||
height: 35,
|
height: 35,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
BlocProvider.of<SettingBloc>(context)
|
BlocProvider.of<SettingBloc>(
|
||||||
|
context)
|
||||||
.add(SelectIcon(
|
.add(SelectIcon(
|
||||||
iconId: iconModel.uuid,
|
iconId: iconModel.uuid,
|
||||||
));
|
));
|
||||||
@ -299,12 +360,16 @@ class SettingHelper {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
child: ClipOval(
|
child: ClipOval(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.all(1),
|
padding:
|
||||||
|
const EdgeInsets.all(1),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: selectedIcon == iconModel.uuid
|
color: selectedIcon ==
|
||||||
? ColorsManager.primaryColorWithOpacity
|
iconModel.uuid
|
||||||
: Colors.transparent,
|
? ColorsManager
|
||||||
|
.primaryColorWithOpacity
|
||||||
|
: Colors
|
||||||
|
.transparent,
|
||||||
width: 2,
|
width: 2,
|
||||||
),
|
),
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
@ -319,8 +384,12 @@ class SettingHelper {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
if (context.read<SettingBloc>().isExpanded && isAutomation)
|
if (context.read<SettingBloc>().isExpanded &&
|
||||||
const SizedBox(height: 350, width: 400, child: EffectivePeriodView())
|
isAutomation)
|
||||||
|
const SizedBox(
|
||||||
|
height: 350,
|
||||||
|
width: 400,
|
||||||
|
child: EffectivePeriodView())
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
@ -344,14 +413,20 @@ class SettingHelper {
|
|||||||
alignment: AlignmentDirectional.center,
|
alignment: AlignmentDirectional.center,
|
||||||
child: Text(
|
child: Text(
|
||||||
'Cancel',
|
'Cancel',
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(
|
||||||
color: ColorsManager.textGray,
|
color: ColorsManager.textGray,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(width: 1, height: 50, color: ColorsManager.greyColor),
|
Container(
|
||||||
|
width: 1,
|
||||||
|
height: 50,
|
||||||
|
color: ColorsManager.greyColor),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -361,8 +436,12 @@ class SettingHelper {
|
|||||||
alignment: AlignmentDirectional.center,
|
alignment: AlignmentDirectional.center,
|
||||||
child: Text(
|
child: Text(
|
||||||
'Confirm',
|
'Confirm',
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
style: Theme.of(context)
|
||||||
color: ColorsManager.primaryColorWithOpacity,
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(
|
||||||
|
color: ColorsManager
|
||||||
|
.primaryColorWithOpacity,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
230
lib/pages/routiens/models/create_scene/create_scene_model.dart
Normal file
230
lib/pages/routiens/models/create_scene/create_scene_model.dart
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
class CreateSceneModel {
|
||||||
|
String spaceUuid;
|
||||||
|
String iconId;
|
||||||
|
bool showInDevice;
|
||||||
|
String sceneName;
|
||||||
|
String decisionExpr;
|
||||||
|
List<CreateSceneAction> actions;
|
||||||
|
|
||||||
|
CreateSceneModel({
|
||||||
|
required this.spaceUuid,
|
||||||
|
required this.iconId,
|
||||||
|
required this.showInDevice,
|
||||||
|
required this.sceneName,
|
||||||
|
required this.decisionExpr,
|
||||||
|
required this.actions,
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateSceneModel copyWith({
|
||||||
|
String? spaceUuid,
|
||||||
|
String? iconId,
|
||||||
|
bool? showInDevice,
|
||||||
|
String? sceneName,
|
||||||
|
String? decisionExpr,
|
||||||
|
List<CreateSceneAction>? actions,
|
||||||
|
bool? showInHomePage,
|
||||||
|
}) {
|
||||||
|
return CreateSceneModel(
|
||||||
|
spaceUuid: spaceUuid ?? this.spaceUuid,
|
||||||
|
iconId: iconId ?? this.iconId,
|
||||||
|
showInDevice: showInDevice ?? this.showInDevice,
|
||||||
|
sceneName: sceneName ?? this.sceneName,
|
||||||
|
decisionExpr: decisionExpr ?? this.decisionExpr,
|
||||||
|
actions: actions ?? this.actions,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap([String? sceneId]) {
|
||||||
|
return {
|
||||||
|
if (sceneId == null) 'spaceUuid': spaceUuid,
|
||||||
|
if (iconId.isNotEmpty) 'iconUuid': iconId,
|
||||||
|
'showInHomePage': showInDevice,
|
||||||
|
'sceneName': sceneName,
|
||||||
|
'decisionExpr': decisionExpr,
|
||||||
|
'actions': actions.map((x) => x.toMap()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory CreateSceneModel.fromMap(Map<String, dynamic> map) {
|
||||||
|
return CreateSceneModel(
|
||||||
|
spaceUuid: map['spaceUuid'] ?? '',
|
||||||
|
showInDevice: map['showInHomePage'] ?? false,
|
||||||
|
iconId: map['iconUuid'] ?? '',
|
||||||
|
sceneName: map['sceneName'] ?? '',
|
||||||
|
decisionExpr: map['decisionExpr'] ?? '',
|
||||||
|
actions: List<CreateSceneAction>.from(
|
||||||
|
map['actions']?.map((x) => CreateSceneAction.fromMap(x))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toJson([String? sceneId]) => json.encode(toMap(sceneId));
|
||||||
|
|
||||||
|
factory CreateSceneModel.fromJson(String source) =>
|
||||||
|
CreateSceneModel.fromMap(json.decode(source));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'CreateSceneModel(unitUuid: $spaceUuid, sceneName: $sceneName, decisionExpr: $decisionExpr, actions: $actions)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is CreateSceneModel &&
|
||||||
|
other.spaceUuid == spaceUuid &&
|
||||||
|
other.iconId == iconId &&
|
||||||
|
other.showInDevice == showInDevice &&
|
||||||
|
other.sceneName == sceneName &&
|
||||||
|
other.decisionExpr == decisionExpr &&
|
||||||
|
listEquals(other.actions, actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return spaceUuid.hashCode ^
|
||||||
|
sceneName.hashCode ^
|
||||||
|
decisionExpr.hashCode ^
|
||||||
|
actions.hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreateSceneAction {
|
||||||
|
String entityId;
|
||||||
|
String actionExecutor;
|
||||||
|
CreateSceneExecutorProperty? executorProperty;
|
||||||
|
|
||||||
|
CreateSceneAction({
|
||||||
|
required this.entityId,
|
||||||
|
required this.actionExecutor,
|
||||||
|
required this.executorProperty,
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateSceneAction copyWith({
|
||||||
|
String? entityId,
|
||||||
|
String? actionExecutor,
|
||||||
|
CreateSceneExecutorProperty? executorProperty,
|
||||||
|
}) {
|
||||||
|
return CreateSceneAction(
|
||||||
|
entityId: entityId ?? this.entityId,
|
||||||
|
actionExecutor: actionExecutor ?? this.actionExecutor,
|
||||||
|
executorProperty: executorProperty ?? this.executorProperty,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
if (executorProperty != null) {
|
||||||
|
return {
|
||||||
|
'entityId': entityId,
|
||||||
|
'actionExecutor': actionExecutor,
|
||||||
|
'executorProperty': executorProperty?.toMap(actionExecutor),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
'entityId': entityId,
|
||||||
|
'actionExecutor': actionExecutor,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
factory CreateSceneAction.fromMap(Map<String, dynamic> map) {
|
||||||
|
return CreateSceneAction(
|
||||||
|
entityId: map['entityId'] ?? '',
|
||||||
|
actionExecutor: map['actionExecutor'] ?? '',
|
||||||
|
executorProperty:
|
||||||
|
CreateSceneExecutorProperty.fromMap(map['executorProperty']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toJson() => json.encode(toMap());
|
||||||
|
|
||||||
|
factory CreateSceneAction.fromJson(String source) =>
|
||||||
|
CreateSceneAction.fromMap(json.decode(source));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'CreateSceneAction(entityId: $entityId, actionExecutor: $actionExecutor, executorProperty: $executorProperty)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is CreateSceneAction &&
|
||||||
|
other.entityId == entityId &&
|
||||||
|
other.actionExecutor == actionExecutor &&
|
||||||
|
other.executorProperty == executorProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
entityId.hashCode ^ actionExecutor.hashCode ^ executorProperty.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreateSceneExecutorProperty {
|
||||||
|
String functionCode;
|
||||||
|
dynamic functionValue;
|
||||||
|
int delaySeconds;
|
||||||
|
|
||||||
|
CreateSceneExecutorProperty({
|
||||||
|
required this.functionCode,
|
||||||
|
required this.functionValue,
|
||||||
|
required this.delaySeconds,
|
||||||
|
});
|
||||||
|
|
||||||
|
CreateSceneExecutorProperty copyWith({
|
||||||
|
String? functionCode,
|
||||||
|
dynamic functionValue,
|
||||||
|
int? delaySeconds,
|
||||||
|
}) {
|
||||||
|
return CreateSceneExecutorProperty(
|
||||||
|
functionCode: functionCode ?? this.functionCode,
|
||||||
|
functionValue: functionValue ?? this.functionValue,
|
||||||
|
delaySeconds: delaySeconds ?? this.delaySeconds,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap(String actionExecutor) {
|
||||||
|
final map = <String, dynamic>{};
|
||||||
|
if (functionCode.isNotEmpty) map['functionCode'] = functionCode;
|
||||||
|
if (functionValue != null) map['functionValue'] = functionValue;
|
||||||
|
if (actionExecutor == 'delay' && delaySeconds > 0) {
|
||||||
|
map['delaySeconds'] = delaySeconds;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory CreateSceneExecutorProperty.fromMap(Map<String, dynamic> map) {
|
||||||
|
return CreateSceneExecutorProperty(
|
||||||
|
functionCode: map['functionCode'] ?? '',
|
||||||
|
functionValue: map['functionValue'] ?? '',
|
||||||
|
delaySeconds: map['delaySeconds']?.toInt() ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toJson(String actionExecutor) => json.encode(toMap(actionExecutor));
|
||||||
|
|
||||||
|
factory CreateSceneExecutorProperty.fromJson(String source) =>
|
||||||
|
CreateSceneExecutorProperty.fromMap(json.decode(source));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'CreateSceneExecutorProperty(functionCode: $functionCode, functionValue: $functionValue, delaySeconds: $delaySeconds)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is CreateSceneExecutorProperty &&
|
||||||
|
other.functionCode == functionCode &&
|
||||||
|
other.functionValue == functionValue &&
|
||||||
|
other.delaySeconds == delaySeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
functionCode.hashCode ^ functionValue.hashCode ^ delaySeconds.hashCode;
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/main.dart';
|
||||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
import 'package:syncrow_web/pages/common/text_field/custom_text_field.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/helper/save_routine_helper.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/helper/setting_helper.dart';
|
import 'package:syncrow_web/pages/routiens/helper/setting_helper.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
@ -28,7 +32,9 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxWidth: constraints.maxWidth > 700 ? 450 : constraints.maxWidth - 32),
|
maxWidth: constraints.maxWidth > 700
|
||||||
|
? 450
|
||||||
|
: constraints.maxWidth - 32),
|
||||||
child: StatefulTextField(
|
child: StatefulTextField(
|
||||||
title: 'Routine Name',
|
title: 'Routine Name',
|
||||||
height: 40,
|
height: 40,
|
||||||
@ -38,6 +44,11 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
width: 450,
|
width: 450,
|
||||||
|
onChanged: (value) {
|
||||||
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(SearchRoutines(value));
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(constraints.maxWidth <= 1000)
|
(constraints.maxWidth <= 1000)
|
||||||
@ -48,8 +59,17 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
|||||||
child: Center(
|
child: Center(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final result = await SettingHelper.showSettingDialog(
|
final result =
|
||||||
context: context, isAutomation: true);
|
await SettingHelper.showSettingDialog(
|
||||||
|
context: context,
|
||||||
|
isAutomation: context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.isAutomation);
|
||||||
|
if (result != null) {
|
||||||
|
context
|
||||||
|
.read<RoutineBloc>()
|
||||||
|
.add(AddSelectedIcon(result));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
@ -100,7 +120,9 @@ class RoutineSearchAndButtons extends StatelessWidget {
|
|||||||
width: 200,
|
width: 200,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
SaveRoutineHelper.showSaveRoutineDialog(context);
|
||||||
|
},
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
backgroundColor: ColorsManager.primaryColor,
|
backgroundColor: ColorsManager.primaryColor,
|
||||||
|
@ -4,7 +4,8 @@ import 'package:syncrow_web/pages/routiens/widgets/routines_title_widget.dart';
|
|||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
|
|
||||||
class ConditionTitleAndSearchBar extends StatelessWidget with HelperResponsiveLayout {
|
class ConditionTitleAndSearchBar extends StatelessWidget
|
||||||
|
with HelperResponsiveLayout {
|
||||||
const ConditionTitleAndSearchBar({
|
const ConditionTitleAndSearchBar({
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
@ -33,6 +34,7 @@ class ConditionTitleAndSearchBar extends StatelessWidget with HelperResponsiveLa
|
|||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
),
|
),
|
||||||
controller: TextEditingController(),
|
controller: TextEditingController(),
|
||||||
|
onChanged: (value) {},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -55,6 +57,7 @@ class ConditionTitleAndSearchBar extends StatelessWidget with HelperResponsiveLa
|
|||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
),
|
),
|
||||||
controller: TextEditingController(),
|
controller: TextEditingController(),
|
||||||
|
onChanged: (value) {},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:syncrow_web/pages/routiens/models/create_scene/create_scene_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/icon_model.dart';
|
||||||
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
import 'package:syncrow_web/pages/routiens/models/routine_model.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
@ -7,22 +8,22 @@ class SceneApi {
|
|||||||
static final HTTPService _httpService = HTTPService();
|
static final HTTPService _httpService = HTTPService();
|
||||||
|
|
||||||
// //create scene
|
// //create scene
|
||||||
// static Future<Map<String, dynamic>> createScene(
|
static Future<Map<String, dynamic>> createScene(
|
||||||
// CreateSceneModel createSceneModel) async {
|
CreateSceneModel createSceneModel) async {
|
||||||
// try {
|
try {
|
||||||
// final response = await _httpService.post(
|
final response = await _httpService.post(
|
||||||
// path: ApiEndpoints.createScene,
|
path: ApiEndpoints.createScene,
|
||||||
// body: createSceneModel.toMap(),
|
body: createSceneModel.toMap(),
|
||||||
// showServerMessage: false,
|
showServerMessage: false,
|
||||||
// expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
// return json;
|
return json;
|
||||||
// },
|
},
|
||||||
// );
|
);
|
||||||
// return response;
|
return response;
|
||||||
// } catch (e) {
|
} catch (e) {
|
||||||
// rethrow;
|
rethrow;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
//
|
||||||
// // create automation
|
// // create automation
|
||||||
// static Future<Map<String, dynamic>> createAutomation(
|
// static Future<Map<String, dynamic>> createAutomation(
|
||||||
|
@ -11,12 +11,14 @@ abstract class ApiEndpoints {
|
|||||||
static const String visitorPassword = '/visitor-password';
|
static const String visitorPassword = '/visitor-password';
|
||||||
static const String getDevices = '/visitor-password/devices';
|
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 =
|
static const String sendOnlineMultipleTime =
|
||||||
'/visitor-password/temporary-password/online/multiple-time';
|
'/visitor-password/temporary-password/online/multiple-time';
|
||||||
|
|
||||||
//offline Password
|
//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 =
|
static const String sendOffLineMultipleTime =
|
||||||
'/visitor-password/temporary-password/offline/multiple-time';
|
'/visitor-password/temporary-password/offline/multiple-time';
|
||||||
|
|
||||||
@ -38,13 +40,18 @@ abstract class ApiEndpoints {
|
|||||||
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
||||||
|
|
||||||
static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
|
static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
|
||||||
static const String getScheduleByDeviceId = '/schedule/{deviceUuid}?category={category}';
|
static const String getScheduleByDeviceId =
|
||||||
static const String deleteScheduleByDeviceId = '/schedule/{deviceUuid}/{scheduleUuid}';
|
'/schedule/{deviceUuid}?category={category}';
|
||||||
static const String updateScheduleByDeviceId = '/schedule/enable/{deviceUuid}';
|
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 factoryReset = '/device/factory/reset/{deviceUuid}';
|
||||||
static const String powerClamp = '/device/{powerClampUuid}/power-clamp/status';
|
static const String powerClamp =
|
||||||
|
'/device/{powerClampUuid}/power-clamp/status';
|
||||||
static const String getSpaceScenes = '/scene/tap-to-run/{unitUuid}';
|
static const String getSpaceScenes = '/scene/tap-to-run/{unitUuid}';
|
||||||
static const String getSpaceAutomation = '/automation/{unitUuid}';
|
static const String getSpaceAutomation = '/automation/{unitUuid}';
|
||||||
static const String getIconScene = '/scene/icon';
|
static const String getIconScene = '/scene/icon';
|
||||||
|
static const String createScene = '/scene/tap-to-run';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user