Compare commits

..

30 Commits

Author SHA1 Message Date
1567f10827 Revert "enhanced ci/cd by not running the deply jobs on the PR itself… (#237)
…, and now we only deploy when we merged a PR to `dev` or `main`, and
created a separate GitHub action that only builds and install
dependencies, which only runs on the PR itself."

This reverts commit f19120c754.

<!--
  Thanks for contributing!

Provide a description of your changes below and a general summary in the
title

Please look at the following checklist to ensure that your PR can be
accepted quickly:
-->

## Description

<!--- Describe your changes in detail -->

## Type of Change

<!--- Put an `x` in all the boxes that apply: -->

- [ ]  New feature (non-breaking change which adds functionality)
- [ ] 🛠️ Bug fix (non-breaking change which fixes an issue)
- [ ]  Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] 🧹 Code refactor
- [ ]  Build configuration change
- [ ] 📝 Documentation
- [x] 🗑️ Chore
2025-06-11 09:53:19 +03:00
cdbd90b54c Revert "enhanced ci/cd by not running the deply jobs on the PR itself, and now we only deploy when we merged a PR to dev or main, and created a separate GitHub action that only builds and install dependencies, which only runs on the PR itself."
This reverts commit f19120c754.
2025-06-11 09:52:08 +03:00
03f5c869c6 chore/add-dependabot (#232)
<!--
  Thanks for contributing!

Provide a description of your changes below and a general summary in the
title

Please look at the following checklist to ensure that your PR can be
accepted quickly:
-->

## Description

Added `dependabot` configuration, which notifies us of any updated
dependencies, and if there is security aspects that we'd need to take
care of.

## Type of Change

<!--- Put an `x` in all the boxes that apply: -->

- [x] 🗑️ Chore
2025-06-04 16:41:42 +03:00
4f98891902 Created dependabot.yaml 2025-06-04 13:13:07 +03:00
7002bbfa04 CI/CD Enhancements (#230)
<!--
  Thanks for contributing!

Provide a description of your changes below and a general summary in the
title

Please look at the following checklist to ensure that your PR can be
accepted quickly:
-->
## Description

enhanced CI/CD by not running the deploy jobs on the PR itself, and now
we only deploy when we merged a PR to `dev` or `main`, and created a
separate GitHub action that only builds and install dependencies, which
only runs on the PR itself.


## Type of Change

<!--- Put an `x` in all the boxes that apply: -->

- [ ]  New feature (non-breaking change which adds functionality)
- [ ] 🛠️ Bug fix (non-breaking change which fixes an issue)
- [ ]  Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] 🧹 Code refactor
- [ ]  Build configuration change
- [ ] 📝 Documentation
- [x] 🗑️ Chore
2025-06-04 10:41:26 +03:00
f19120c754 enhanced ci/cd by not running the deply jobs on the PR itself, and now we only deploy when we merged a PR to dev or main, and created a separate GitHub action that only builds and install dependencies, which only runs on the PR itself. 2025-06-04 10:12:19 +03:00
6b3eca23af Update pull_request_template.md 2025-05-28 16:46:24 +03:00
4f4f11c330 Merge branch 'main' of https://github.com/SyncrowIOT/web 2025-05-28 14:26:36 +03:00
8a25fa798c Created pull_request_template.md. 2025-05-28 14:26:33 +03:00
6612e91430 Merge pull request #177 from SyncrowIOT/merge_sprint_19_bugfixes
merged DEV into staging.
2025-05-08 14:32:54 +03:00
8d2d9dd0bb Merge branch 'dev' of https://github.com/SyncrowIOT/web 2025-04-29 10:39:54 +03:00
cfc68f1568 Merge pull request #116 from SyncrowIOT/dev
fix real time listenToChanges
2025-03-12 21:26:45 +03:00
02e08ad92f Merge pull request #115 from SyncrowIOT/dev
Dev
2025-03-12 14:21:13 +03:00
d7899a24f5 Merged with dev 2025-02-20 13:03:38 +03:00
800c0ba47f Merge pull request #101 from SyncrowIOT/bugfix/fix-endpoint
Main
2025-02-20 13:37:28 +04:00
fe4e775902 fixed endpoint 2025-02-20 13:35:59 +04:00
5247856cb4 Merge pull request #99 from SyncrowIOT:bugfix/add-tag-border
added back border of tag list
2025-02-20 11:50:07 +04:00
4a8b8a32ba added back border of tag list 2025-02-20 11:49:35 +04:00
2abce77eb5 Merge pull request #97 from SyncrowIOT/feat/fix-cursor-issue-in-main
Fixed cursor issue
2025-02-20 11:35:35 +04:00
7efd1c3c87 Fixed cursor issue 2025-02-20 11:34:24 +04:00
7a0d9aefb7 Merge pull request #95 from SyncrowIOT/bugfix/change-endpoint-prod
fix endpoints
2025-02-19 18:01:11 +04:00
21cc25cfc4 fix endpoints 2025-02-19 17:58:53 +04:00
e2ec4bbf31 Pulled main changes 2025-02-18 16:27:09 +03:00
51b46ae197 Merged with dev 2025-02-18 16:25:33 +03:00
36ee22603a fixes CommunityId and spaceUuid 2025-02-10 12:44:35 +03:00
b0abd42b0c projectId 2025-02-06 11:28:40 +03:00
ba4da78846 Merge branch 'dev' 2025-02-06 11:20:34 +03:00
dc20d69f20 Merge pull request #88 from SyncrowIOT/dev
Dev
2025-02-06 01:03:32 +03:00
cf6ec231dc Merged with dev 2025-02-06 00:57:29 +03:00
d0530f7fc3 Added staging space and community IDs 2024-12-04 09:57:29 +03:00
7 changed files with 139 additions and 69 deletions

10
.github/.github/dependabot.yaml vendored Normal file
View File

@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "pub"
directory: "/"
schedule:
interval: "daily"

26
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,26 @@
<!--
Thanks for contributing!
Provide a description of your changes below and a general summary in the title
Please look at the following checklist to ensure that your PR can be accepted quickly:
-->
## Jira Ticket
[SP-0000](https://syncrow.atlassian.net/browse/SP-0000)
## Description
<!--- Describe your changes in detail -->
## Type of Change
<!--- Put an `x` in all the boxes that apply: -->
- [ ] ✨ New feature (non-breaking change which adds functionality)
- [ ] 🛠️ Bug fix (non-breaking change which fixes an issue)
- [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change)
- [ ] 🧹 Code refactor
- [ ] ✅ Build configuration change
- [ ] 📝 Documentation
- [ ] 🗑️ Chore

View File

@ -19,7 +19,6 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.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/style.dart'; import 'package:syncrow_web/utils/style.dart';
class UsersPage extends StatelessWidget { class UsersPage extends StatelessWidget {
UsersPage({super.key}); UsersPage({super.key});

View File

@ -1,10 +1,9 @@
import 'dart:async'; import 'dart:async';
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/common/bloc/project_manager.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart'; import 'package:syncrow_web/pages/routines/bloc/automation_scene_trigger_bloc/automation_status_update.dart';
import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart'; import 'package:syncrow_web/pages/routines/bloc/create_routine_bloc/create_routine_bloc.dart';
@ -90,8 +89,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems); final updatedIfItems = List<Map<String, dynamic>>.from(state.ifItems);
// Find the index of the item in teh current itemsList // Find the index of the item in teh current itemsList
int index = int index = updatedIfItems
updatedIfItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); .indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
// Replace the map if the index is valid // Replace the map if the index is valid
if (index != -1) { if (index != -1) {
updatedIfItems[index] = event.item; updatedIfItems[index] = event.item;
@ -100,9 +99,11 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
if (event.isTabToRun) { if (event.isTabToRun) {
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: true, isAutomation: false)); emit(state.copyWith(
ifItems: updatedIfItems, isTabToRun: true, isAutomation: false));
} else { } else {
emit(state.copyWith(ifItems: updatedIfItems, isTabToRun: false, isAutomation: true)); emit(state.copyWith(
ifItems: updatedIfItems, isTabToRun: false, isAutomation: true));
} }
} }
@ -110,8 +111,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
final currentItems = List<Map<String, dynamic>>.from(state.thenItems); final currentItems = List<Map<String, dynamic>>.from(state.thenItems);
// Find the index of the item in teh current itemsList // Find the index of the item in teh current itemsList
int index = int index = currentItems
currentItems.indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']); .indexWhere((map) => map['uniqueCustomId'] == event.item['uniqueCustomId']);
// Replace the map if the index is valid // Replace the map if the index is valid
if (index != -1) { if (index != -1) {
currentItems[index] = event.item; currentItems[index] = event.item;
@ -122,7 +123,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
emit(state.copyWith(thenItems: currentItems)); emit(state.copyWith(thenItems: currentItems));
} }
void _onAddFunctionsToRoutine(AddFunctionToRoutine event, Emitter<RoutineState> emit) { void _onAddFunctionsToRoutine(
AddFunctionToRoutine event, Emitter<RoutineState> emit) {
try { try {
if (event.functions.isEmpty) return; if (event.functions.isEmpty) return;
@ -172,17 +174,20 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
BuildContext context = NavigationService.navigatorKey.currentContext!; BuildContext context = NavigationService.navigatorKey.currentContext!;
var createRoutineBloc = context.read<CreateRoutineBloc>(); var createRoutineBloc = context.read<CreateRoutineBloc>();
final projectUuid = await ProjectManager.getProjectUUID() ?? ''; final projectUuid = await ProjectManager.getProjectUUID() ?? '';
if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { if (createRoutineBloc.selectedSpaceId == '' &&
createRoutineBloc.selectedCommunityId == '') {
var spaceBloc = context.read<SpaceTreeBloc>(); var spaceBloc = context.read<SpaceTreeBloc>();
for (var communityId in spaceBloc.state.selectedCommunities) { for (var communityId in spaceBloc.state.selectedCommunities) {
List<String> spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; List<String> spacesList =
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
for (var spaceId in spacesList) { for (var spaceId in spacesList) {
scenes.addAll(await SceneApi.getScenes(spaceId, communityId, projectUuid)); scenes
.addAll(await SceneApi.getScenes(spaceId, communityId, projectUuid));
} }
} }
} else { } else {
scenes.addAll(await SceneApi.getScenes( scenes.addAll(await SceneApi.getScenes(createRoutineBloc.selectedSpaceId,
createRoutineBloc.selectedSpaceId, createRoutineBloc.selectedCommunityId, projectUuid)); createRoutineBloc.selectedCommunityId, projectUuid));
} }
emit(state.copyWith( emit(state.copyWith(
@ -199,7 +204,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
Future<void> _onLoadAutomation(LoadAutomation event, Emitter<RoutineState> emit) async { Future<void> _onLoadAutomation(
LoadAutomation event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null)); emit(state.copyWith(isLoading: true, errorMessage: null));
List<ScenesModel> automations = []; List<ScenesModel> automations = [];
final projectId = await ProjectManager.getProjectUUID() ?? ''; final projectId = await ProjectManager.getProjectUUID() ?? '';
@ -207,17 +213,22 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
BuildContext context = NavigationService.navigatorKey.currentContext!; BuildContext context = NavigationService.navigatorKey.currentContext!;
var createRoutineBloc = context.read<CreateRoutineBloc>(); var createRoutineBloc = context.read<CreateRoutineBloc>();
try { try {
if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { if (createRoutineBloc.selectedSpaceId == '' &&
createRoutineBloc.selectedCommunityId == '') {
var spaceBloc = context.read<SpaceTreeBloc>(); var spaceBloc = context.read<SpaceTreeBloc>();
for (var communityId in spaceBloc.state.selectedCommunities) { for (var communityId in spaceBloc.state.selectedCommunities) {
List<String> spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; List<String> spacesList =
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
for (var spaceId in spacesList) { for (var spaceId in spacesList) {
automations.addAll(await SceneApi.getAutomation(spaceId, communityId, projectId)); automations.addAll(
await SceneApi.getAutomation(spaceId, communityId, projectId));
} }
} }
} else { } else {
automations.addAll(await SceneApi.getAutomation( automations.addAll(await SceneApi.getAutomation(
createRoutineBloc.selectedSpaceId, createRoutineBloc.selectedCommunityId, projectId)); createRoutineBloc.selectedSpaceId,
createRoutineBloc.selectedCommunityId,
projectId));
} }
emit(state.copyWith( emit(state.copyWith(
automations: automations, automations: automations,
@ -233,14 +244,16 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onSearchRoutines(SearchRoutines event, Emitter<RoutineState> emit) async { FutureOr<void> _onSearchRoutines(
SearchRoutines event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true, errorMessage: null)); emit(state.copyWith(isLoading: true, errorMessage: null));
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
emit(state.copyWith(isLoading: false, errorMessage: null)); emit(state.copyWith(isLoading: false, errorMessage: null));
emit(state.copyWith(searchText: event.query)); emit(state.copyWith(searchText: event.query));
} }
FutureOr<void> _onAddSelectedIcon(AddSelectedIcon event, Emitter<RoutineState> emit) { FutureOr<void> _onAddSelectedIcon(
AddSelectedIcon event, Emitter<RoutineState> emit) {
emit(state.copyWith(selectedIcon: event.icon)); emit(state.copyWith(selectedIcon: event.icon));
} }
@ -254,7 +267,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
return actions.last['deviceId'] == 'delay'; return actions.last['deviceId'] == 'delay';
} }
Future<void> _onCreateScene(CreateSceneEvent event, Emitter<RoutineState> emit) async { Future<void> _onCreateScene(
CreateSceneEvent event, Emitter<RoutineState> emit) async {
try { try {
// Check if first action is delay // Check if first action is delay
// if (_isFirstActionDelay(state.thenItems)) { // if (_isFirstActionDelay(state.thenItems)) {
@ -343,7 +357,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
Future<void> _onCreateAutomation(CreateAutomationEvent event, Emitter<RoutineState> emit) async { Future<void> _onCreateAutomation(
CreateAutomationEvent event, Emitter<RoutineState> emit) async {
try { try {
final projectUuid = await ProjectManager.getProjectUUID() ?? ''; final projectUuid = await ProjectManager.getProjectUUID() ?? '';
if (state.routineName == null || state.routineName!.isEmpty) { if (state.routineName == null || state.routineName!.isEmpty) {
@ -456,7 +471,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
actions: actions, actions: actions,
); );
final result = await SceneApi.createAutomation(createAutomationModel, projectUuid); final result =
await SceneApi.createAutomation(createAutomationModel, projectUuid);
if (result['success']) { if (result['success']) {
add(ResetRoutineState()); add(ResetRoutineState());
add(const LoadAutomation()); add(const LoadAutomation());
@ -477,17 +493,21 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onRemoveDragCard(RemoveDragCard event, Emitter<RoutineState> emit) { FutureOr<void> _onRemoveDragCard(
RemoveDragCard event, Emitter<RoutineState> emit) {
if (event.isFromThen) { if (event.isFromThen) {
final thenItems = List<Map<String, dynamic>>.from(state.thenItems); final thenItems = List<Map<String, dynamic>>.from(state.thenItems);
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions); final selectedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
thenItems.removeAt(event.index); thenItems.removeAt(event.index);
selectedFunctions.remove(event.key); selectedFunctions.remove(event.key);
emit(state.copyWith(thenItems: thenItems, selectedFunctions: selectedFunctions)); emit(state.copyWith(
thenItems: thenItems, selectedFunctions: selectedFunctions));
} else { } else {
final ifItems = List<Map<String, dynamic>>.from(state.ifItems); final ifItems = List<Map<String, dynamic>>.from(state.ifItems);
final selectedFunctions = Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions); final selectedFunctions =
Map<String, List<DeviceFunctionData>>.from(state.selectedFunctions);
ifItems.removeAt(event.index); ifItems.removeAt(event.index);
selectedFunctions.remove(event.key); selectedFunctions.remove(event.key);
@ -510,11 +530,13 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
)); ));
} }
FutureOr<void> _onEffectiveTimeEvent(EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) { FutureOr<void> _onEffectiveTimeEvent(
EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
emit(state.copyWith(effectiveTime: event.effectiveTime)); emit(state.copyWith(effectiveTime: event.effectiveTime));
} }
FutureOr<void> _onSetRoutineName(SetRoutineName event, Emitter<RoutineState> emit) { FutureOr<void> _onSetRoutineName(
SetRoutineName event, Emitter<RoutineState> emit) {
emit(state.copyWith( emit(state.copyWith(
routineName: event.name, routineName: event.name,
)); ));
@ -641,7 +663,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
// return (thenItems, ifItems, currentFunctions); // return (thenItems, ifItems, currentFunctions);
// } // }
Future<void> _onGetSceneDetails(GetSceneDetails event, Emitter<RoutineState> emit) async { Future<void> _onGetSceneDetails(
GetSceneDetails event, Emitter<RoutineState> emit) async {
try { try {
emit(state.copyWith( emit(state.copyWith(
isLoading: true, isLoading: true,
@ -690,9 +713,10 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
deviceCards[deviceId] = { deviceCards[deviceId] = {
'entityId': action.entityId, 'entityId': action.entityId,
'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId, 'deviceId': action.actionExecutor == 'delay' ? 'delay' : action.entityId,
'uniqueCustomId': action.type == 'automation' || action.actionExecutor == 'delay' 'uniqueCustomId':
? action.entityId action.type == 'automation' || action.actionExecutor == 'delay'
: const Uuid().v4(), ? action.entityId
: const Uuid().v4(),
'title': action.actionExecutor == 'delay' 'title': action.actionExecutor == 'delay'
? 'Delay' ? 'Delay'
: action.type == 'automation' : action.type == 'automation'
@ -732,7 +756,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
), ),
); );
// emit(state.copyWith(automationActionExecutor: action.actionExecutor)); // emit(state.copyWith(automationActionExecutor: action.actionExecutor));
} else if (action.executorProperty != null && action.actionExecutor != 'delay') { } else if (action.executorProperty != null &&
action.actionExecutor != 'delay') {
final functions = matchingDevice?.functions ?? []; final functions = matchingDevice?.functions ?? [];
final functionCode = action.executorProperty?.functionCode; final functionCode = action.executorProperty?.functionCode;
for (DeviceFunction function in functions) { for (DeviceFunction function in functions) {
@ -798,7 +823,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onResetRoutineState(ResetRoutineState event, Emitter<RoutineState> emit) { FutureOr<void> _onResetRoutineState(
ResetRoutineState event, Emitter<RoutineState> emit) {
emit(state.copyWith( emit(state.copyWith(
ifItems: [], ifItems: [],
thenItems: [], thenItems: [],
@ -831,7 +857,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
var spaceBloc = context.read<SpaceTreeBloc>(); var spaceBloc = context.read<SpaceTreeBloc>();
if (state.isTabToRun) { if (state.isTabToRun) {
await SceneApi.deleteScene( await SceneApi.deleteScene(
unitUuid: spaceBloc.state.selectedSpaces[0], sceneId: state.sceneId ?? ''); unitUuid: spaceBloc.state.selectedSpaces[0],
sceneId: state.sceneId ?? '');
} else { } else {
await SceneApi.deleteAutomation( await SceneApi.deleteAutomation(
unitUuid: spaceBloc.state.selectedSpaces[0], unitUuid: spaceBloc.state.selectedSpaces[0],
@ -876,7 +903,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
// } // }
// } // }
FutureOr<void> _fetchDevices(FetchDevicesInRoutine event, Emitter<RoutineState> emit) async { FutureOr<void> _fetchDevices(
FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
emit(state.copyWith(isLoading: true)); emit(state.copyWith(isLoading: true));
try { try {
final projectUuid = await ProjectManager.getProjectUUID() ?? ''; final projectUuid = await ProjectManager.getProjectUUID() ?? '';
@ -885,17 +913,21 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
var createRoutineBloc = context.read<CreateRoutineBloc>(); var createRoutineBloc = context.read<CreateRoutineBloc>();
var spaceBloc = context.read<SpaceTreeBloc>(); var spaceBloc = context.read<SpaceTreeBloc>();
if (createRoutineBloc.selectedSpaceId == '' && createRoutineBloc.selectedCommunityId == '') { if (createRoutineBloc.selectedSpaceId == '' &&
createRoutineBloc.selectedCommunityId == '') {
for (var communityId in spaceBloc.state.selectedCommunities) { for (var communityId in spaceBloc.state.selectedCommunities) {
List<String> spacesList = spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? []; List<String> spacesList =
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
for (var spaceId in spacesList) { for (var spaceId in spacesList) {
devices.addAll( devices.addAll(await DevicesManagementApi()
await DevicesManagementApi().fetchDevices(communityId, spaceId, projectUuid)); .fetchDevices(communityId, spaceId, projectUuid));
} }
} }
} else { } else {
devices.addAll(await DevicesManagementApi().fetchDevices( devices.addAll(await DevicesManagementApi().fetchDevices(
createRoutineBloc.selectedCommunityId, createRoutineBloc.selectedSpaceId, projectUuid)); createRoutineBloc.selectedCommunityId,
createRoutineBloc.selectedSpaceId,
projectUuid));
} }
emit(state.copyWith(isLoading: false, devices: devices)); emit(state.copyWith(isLoading: false, devices: devices));
@ -904,7 +936,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onUpdateScene(UpdateScene event, Emitter<RoutineState> emit) async { FutureOr<void> _onUpdateScene(
UpdateScene event, Emitter<RoutineState> emit) async {
try { try {
// Check if first action is delay // Check if first action is delay
// if (_isFirstActionDelay(state.thenItems)) { // if (_isFirstActionDelay(state.thenItems)) {
@ -971,7 +1004,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
actions: actions, actions: actions,
); );
final result = await SceneApi.updateScene(createSceneModel, state.sceneId ?? ''); final result =
await SceneApi.updateScene(createSceneModel, state.sceneId ?? '');
if (result['success']) { if (result['success']) {
add(ResetRoutineState()); add(ResetRoutineState());
add(const LoadScenes()); add(const LoadScenes());
@ -990,7 +1024,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
FutureOr<void> _onUpdateAutomation(UpdateAutomation event, Emitter<RoutineState> emit) async { FutureOr<void> _onUpdateAutomation(
UpdateAutomation event, Emitter<RoutineState> emit) async {
try { try {
if (state.routineName == null || state.routineName!.isEmpty) { if (state.routineName == null || state.routineName!.isEmpty) {
emit(state.copyWith( emit(state.copyWith(
@ -1106,8 +1141,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
if (result['success']) { if (result['success']) {
add(ResetRoutineState()); add(ResetRoutineState());
add(LoadAutomation()); add(const LoadAutomation());
add(LoadScenes()); add(const LoadScenes());
} else { } else {
emit(state.copyWith( emit(state.copyWith(
isLoading: false, isLoading: false,
@ -1291,10 +1326,13 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
final ifItems = deviceIfCards.values.where((card) => card['type'] == 'condition').toList(); final ifItems =
deviceIfCards.values.where((card) => card['type'] == 'condition').toList();
final thenItems = deviceThenCards.values final thenItems = deviceThenCards.values
.where((card) => .where((card) =>
card['type'] == 'action' || card['type'] == 'automation' || card['type'] == 'scene') card['type'] == 'action' ||
card['type'] == 'automation' ||
card['type'] == 'scene')
.toList(); .toList();
emit(state.copyWith( emit(state.copyWith(
@ -1316,7 +1354,8 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} }
} }
Future<void> _onSceneTrigger(SceneTrigger event, Emitter<RoutineState> emit) async { Future<void> _onSceneTrigger(
SceneTrigger event, Emitter<RoutineState> emit) async {
emit(state.copyWith(loadingSceneId: event.sceneId)); emit(state.copyWith(loadingSceneId: event.sceneId));
try { try {
@ -1361,21 +1400,24 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
event.automationStatusUpdate.spaceUuid, event.communityId, projectId); event.automationStatusUpdate.spaceUuid, event.communityId, projectId);
// Remove from loading set safely // Remove from loading set safely
final updatedLoadingIds = {...state.loadingAutomationIds!}..remove(event.automationId); final updatedLoadingIds = {...state.loadingAutomationIds!}
..remove(event.automationId);
emit(state.copyWith( emit(state.copyWith(
automations: updatedAutomations, automations: updatedAutomations,
loadingAutomationIds: updatedLoadingIds, loadingAutomationIds: updatedLoadingIds,
)); ));
} else { } else {
final updatedLoadingIds = {...state.loadingAutomationIds!}..remove(event.automationId); final updatedLoadingIds = {...state.loadingAutomationIds!}
..remove(event.automationId);
emit(state.copyWith( emit(state.copyWith(
loadingAutomationIds: updatedLoadingIds, loadingAutomationIds: updatedLoadingIds,
errorMessage: 'Update failed', errorMessage: 'Update failed',
)); ));
} }
} catch (e) { } catch (e) {
final updatedLoadingIds = {...state.loadingAutomationIds!}..remove(event.automationId); final updatedLoadingIds = {...state.loadingAutomationIds!}
..remove(event.automationId);
emit(state.copyWith( emit(state.copyWith(
loadingAutomationIds: updatedLoadingIds, loadingAutomationIds: updatedLoadingIds,
errorMessage: 'Update error: ${e.toString()}', errorMessage: 'Update error: ${e.toString()}',

View File

@ -34,9 +34,8 @@ class UserPermissionApi {
path: ApiEndpoints.roleTypes, path: ApiEndpoints.roleTypes,
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
final List<RoleTypeModel> fetchedRoles = (json['data'] as List) final List<RoleTypeModel> fetchedRoles =
.map((item) => RoleTypeModel.fromJson(item)) (json['data'] as List).map((item) => RoleTypeModel.fromJson(item)).toList();
.toList();
return fetchedRoles; return fetchedRoles;
}, },
); );
@ -48,9 +47,7 @@ class UserPermissionApi {
path: ApiEndpoints.permission.replaceAll("roleUuid", roleUuid), path: ApiEndpoints.permission.replaceAll("roleUuid", roleUuid),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return (json as List) return (json as List).map((data) => PermissionOption.fromJson(data)).toList();
.map((data) => PermissionOption.fromJson(data))
.toList();
}, },
); );
return response ?? []; return response ?? [];
@ -195,14 +192,10 @@ class UserPermissionApi {
Future<bool> changeUserStatusById(userUuid, status, String projectUuid) async { Future<bool> changeUserStatusById(userUuid, status, String projectUuid) async {
try { try {
Map<String, dynamic> bodya = { Map<String, dynamic> bodya = {"disable": status, "projectUuid": projectUuid};
"disable": status,
"projectUuid": projectUuid
};
final response = await _httpService.put( final response = await _httpService.put(
path: ApiEndpoints.changeUserStatus path: ApiEndpoints.changeUserStatus.replaceAll("{invitedUserUuid}", userUuid),
.replaceAll("{invitedUserUuid}", userUuid),
body: bodya, body: bodya,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return json['success']; return json['success'];

View File

@ -1,7 +1,7 @@
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
abstract class ApiEndpoints { abstract class ApiEndpoints {
static const String projectUuid = "0e62577c-06fa-41b9-8a92-99a21fbaf51c"; static const String projectUuid = "bcda711e-9fc2-4168-a05e-171b4026d1ff";
static String baseUrl = dotenv.env['BASE_URL'] ?? ''; static String baseUrl = dotenv.env['BASE_URL'] ?? '';
static const String signUp = '/authentication/user/signup'; static const String signUp = '/authentication/user/signup';
static const String login = '/authentication/user/login'; static const String login = '/authentication/user/login';

View File

@ -1,3 +1,3 @@
class TempConst { class TempConst {
static const projectId = '0e62577c-06fa-41b9-8a92-99a21fbaf51c'; static const projectId = 'bcda711e-9fc2-4168-a05e-171b4026d1ff';
} }