mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
link space model api integration
This commit is contained in:
@ -1,36 +1,26 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_state.dart';
|
||||
import 'package:syncrow_web/services/space_model_mang_api.dart';
|
||||
import 'package:syncrow_web/utils/navigation_service.dart';
|
||||
|
||||
class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
|
||||
SpaceModelBloc() : super(SpaceModelInitial()) {
|
||||
on<SpaceModelSelectedIdsEvent>(_getSpaceIds);
|
||||
on<LinkSpaceModelEvent>(_handleLinkSpaceModel);
|
||||
on<ValidateSpaceModelEvent>(_validateLinkSpaceModel);
|
||||
on<SpaceModelSelectedEvent>((event, emit) {
|
||||
emit(SpaceModelSelectedState(event.selectedIndex));
|
||||
});
|
||||
}
|
||||
|
||||
// Future<void> getSpaceIds(
|
||||
// SpaceModelSelectedIdsEvent event, Emitter<SpaceModelState> emit) async {
|
||||
// try {
|
||||
// BuildContext context = NavigationService.navigatorKey.currentContext!;
|
||||
// var spaceBloc = context.read<SpaceTreeBloc>();
|
||||
// for (var communityId in spaceBloc.state.selectedCommunities) {
|
||||
// List<String> spacesList =
|
||||
// spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||
// for (var spaceId in spacesList) {
|
||||
// print('spaceId===$spaceId');
|
||||
// }
|
||||
// }
|
||||
// } catch (e) {
|
||||
// print('Error fetching space IDs: $e');
|
||||
// }
|
||||
// }
|
||||
|
||||
List<String> spacesListIds = [];
|
||||
bool hasSelectedSpaces = false;
|
||||
String validate = '';
|
||||
|
||||
Future<void> _getSpaceIds(
|
||||
SpaceModelSelectedIdsEvent event, Emitter<SpaceModelState> emit) async {
|
||||
@ -40,22 +30,17 @@ class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
|
||||
for (var communityId in spaceBloc.state.selectedCommunities) {
|
||||
List<String> spacesList =
|
||||
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||
spacesListIds = spacesList;
|
||||
for (var spaceId in spacesList) {
|
||||
print('spaceId===$spaceId');
|
||||
}
|
||||
}
|
||||
// Check if any community has selected spaces
|
||||
hasSelectedSpaces =
|
||||
spaceBloc.state.selectedCommunities.any((communityId) {
|
||||
List<String> spacesList =
|
||||
spaceBloc.state.selectedCommunityAndSpaces[communityId] ?? [];
|
||||
return spacesList.isNotEmpty;
|
||||
});
|
||||
|
||||
// Optionally, you could emit a state here if you want to rebuild the UI
|
||||
// emit(SpaceModelSelectionUpdatedState(hasSelectedSpaces));
|
||||
|
||||
// Debug output
|
||||
if (hasSelectedSpaces) {
|
||||
print("At least one space is selected.");
|
||||
} else {
|
||||
@ -65,4 +50,57 @@ class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
|
||||
print("Error in _getSpaceIds: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handleLinkSpaceModel(
|
||||
LinkSpaceModelEvent event,
|
||||
Emitter<SpaceModelState> emit,
|
||||
) async {
|
||||
emit(SpaceModelLoading());
|
||||
try {
|
||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||
await SpaceModelManagementApi().linkSpaceModel(
|
||||
spaceModelUuid: event.selectedSpaceMode!,
|
||||
projectId: projectUuid,
|
||||
spaceUuids: spacesListIds,
|
||||
isOverWrite: event.isOverWrite);
|
||||
emit(SpaceModelLinkSuccess());
|
||||
} on DioException catch (e) {
|
||||
final errorMessage = _parseDioError(e);
|
||||
emit(SpaceModelOperationFailure(errorMessage));
|
||||
} catch (e) {
|
||||
emit(SpaceModelOperationFailure('Unexpected error: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _validateLinkSpaceModel(
|
||||
ValidateSpaceModelEvent event,
|
||||
Emitter<SpaceModelState> emit,
|
||||
) async {
|
||||
emit(SpaceModelLoading());
|
||||
try {
|
||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||
await SpaceModelManagementApi().validateSpaceModel(
|
||||
projectUuid,
|
||||
spacesListIds,
|
||||
);
|
||||
emit(SpaceValidationSuccess());
|
||||
} on DioException catch (e) {
|
||||
final errorMessage = _parseDioError(e);
|
||||
if (errorMessage ==
|
||||
'Selected spaces already have linked space model / sub-spaces and devices') {
|
||||
emit(const AlreadyHaveLinkedState());
|
||||
} else {
|
||||
emit(SpaceModelOperationFailure(errorMessage));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(SpaceModelOperationFailure('Unexpected error: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
String _parseDioError(DioException e) {
|
||||
if (e.response?.data is Map<String, dynamic>) {
|
||||
return e.response!.data['error']['message'] ?? 'Unknown error occurred';
|
||||
}
|
||||
return e.message ?? 'Network request failed';
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class SpaceModelEvent {}
|
||||
|
||||
class SpaceModelSelectedEvent extends SpaceModelEvent {
|
||||
@ -6,8 +8,15 @@ class SpaceModelSelectedEvent extends SpaceModelEvent {
|
||||
SpaceModelSelectedEvent(this.selectedIndex);
|
||||
}
|
||||
|
||||
class SpaceModelSelectedIdsEvent extends SpaceModelEvent {}
|
||||
|
||||
|
||||
class SpaceModelSelectedIdsEvent extends SpaceModelEvent {
|
||||
|
||||
class LinkSpaceModelEvent extends SpaceModelEvent {
|
||||
final String? selectedSpaceMode;
|
||||
final bool isOverWrite;
|
||||
LinkSpaceModelEvent({this.selectedSpaceMode, this.isOverWrite = false});
|
||||
}
|
||||
|
||||
class ValidateSpaceModelEvent extends SpaceModelEvent {
|
||||
BuildContext? context;
|
||||
ValidateSpaceModelEvent({this.context});
|
||||
}
|
||||
|
@ -1,9 +1,35 @@
|
||||
abstract class SpaceModelState {}
|
||||
abstract class SpaceModelState {
|
||||
const SpaceModelState();
|
||||
}
|
||||
|
||||
class SpaceModelInitial extends SpaceModelState {}
|
||||
|
||||
class SpaceModelLoading extends SpaceModelState {}
|
||||
|
||||
class SpaceModelSelectedState extends SpaceModelState {
|
||||
final int selectedIndex;
|
||||
|
||||
SpaceModelSelectedState(this.selectedIndex);
|
||||
const SpaceModelSelectedState(this.selectedIndex);
|
||||
}
|
||||
|
||||
class SpaceModelSelectionUpdated extends SpaceModelState {
|
||||
final bool hasSelectedSpaces;
|
||||
const SpaceModelSelectionUpdated(this.hasSelectedSpaces);
|
||||
}
|
||||
|
||||
class SpaceValidationSuccess extends SpaceModelState {}
|
||||
|
||||
class SpaceModelLinkSuccess extends SpaceModelState {}
|
||||
|
||||
class ValidationError extends SpaceModelState {
|
||||
final String message;
|
||||
const ValidationError(this.message);
|
||||
}
|
||||
|
||||
class SpaceModelOperationFailure extends SpaceModelState {
|
||||
final String message;
|
||||
const SpaceModelOperationFailure(this.message);
|
||||
}
|
||||
|
||||
class AlreadyHaveLinkedState extends SpaceModelState {
|
||||
const AlreadyHaveLinkedState();
|
||||
}
|
||||
|
@ -1,16 +1,241 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
// import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||
// import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_bloc.dart';
|
||||
// import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_event.dart';
|
||||
// import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||
// import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart';
|
||||
// import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
// class LinkSpaceModelSpacesDialog extends StatefulWidget {
|
||||
// final SpaceTemplateModel spaceModel;
|
||||
// LinkSpaceModelSpacesDialog({super.key, required this.spaceModel});
|
||||
|
||||
// @override
|
||||
// State<LinkSpaceModelSpacesDialog> createState() =>
|
||||
// _LinkSpaceModelSpacesDialogState();
|
||||
// }
|
||||
|
||||
// class _LinkSpaceModelSpacesDialogState
|
||||
// extends State<LinkSpaceModelSpacesDialog> {
|
||||
// TextEditingController searchController = TextEditingController();
|
||||
|
||||
// @override
|
||||
// void initState() {
|
||||
// context.read<SpaceModelBloc>().add(SpaceModelSelectedIdsEvent());
|
||||
// super.initState();
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return AlertDialog(
|
||||
// contentPadding: EdgeInsets.zero,
|
||||
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
// backgroundColor: Colors.white,
|
||||
// content: SizedBox(
|
||||
// width: MediaQuery.of(context).size.width * 0.4,
|
||||
// child: Column(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.all(15.0),
|
||||
// child: Column(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// const Center(
|
||||
// child: Text(
|
||||
// "Link Space Model to Spaces",
|
||||
// style: TextStyle(
|
||||
// fontSize: 18,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// color: Colors.blueAccent,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// const Divider(),
|
||||
// const SizedBox(height: 16),
|
||||
// _buildDetailRow(
|
||||
// "Space model name:", widget.spaceModel.modelName),
|
||||
// _buildDetailRow("Creation date and time:",
|
||||
// widget.spaceModel.createdAt.toString()),
|
||||
// _buildDetailRow("Created by:", "Admin"),
|
||||
// const SizedBox(height: 12),
|
||||
// const Text(
|
||||
// "Link to:",
|
||||
// style: TextStyle(fontWeight: FontWeight.bold),
|
||||
// ),
|
||||
// const Text(
|
||||
// "Please select all the spaces where you would like to link the Routine.",
|
||||
// style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
// ),
|
||||
// const SizedBox(height: 8),
|
||||
// Expanded(
|
||||
// child: SizedBox(
|
||||
// child: Column(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// flex: 7,
|
||||
// child: Container(
|
||||
// color: ColorsManager.whiteColors,
|
||||
// child: SpaceTreeView(
|
||||
// isSide: true,
|
||||
// onSelect: () {
|
||||
// context.read<SpaceModelBloc>().add(
|
||||
// SpaceModelSelectedIdsEvent());
|
||||
// })))
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(
|
||||
// height: 20,
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// // Buttons
|
||||
// Row(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: Container(
|
||||
// height: 50,
|
||||
// decoration: const BoxDecoration(
|
||||
// border: Border(
|
||||
// right: BorderSide(
|
||||
// color: ColorsManager.grayColor,
|
||||
// width: 0.5,
|
||||
// ),
|
||||
// top: BorderSide(
|
||||
// color: ColorsManager.grayColor,
|
||||
// width: 1,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// child: _buildButton("Cancel", Colors.grey, () {
|
||||
// Navigator.of(context).pop();
|
||||
// }),
|
||||
// ),
|
||||
// ),
|
||||
// Expanded(
|
||||
// child: Container(
|
||||
// height: 50,
|
||||
// decoration: const BoxDecoration(
|
||||
// border: Border(
|
||||
// left: BorderSide(
|
||||
// color: ColorsManager.grayColor,
|
||||
// width: 0.5,
|
||||
// ),
|
||||
// top: BorderSide(
|
||||
// color: ColorsManager.grayColor,
|
||||
// width: 1.0,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// child: _buildButton(
|
||||
// "Confirm", ColorsManager.onSecondaryColor, () {
|
||||
// final spaceModelBloc = context.read<SpaceModelBloc>();
|
||||
// if (!spaceModelBloc.hasSelectedSpaces) {
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// const SnackBar(
|
||||
// content:
|
||||
// Text("Please select at least one space")),
|
||||
// );
|
||||
// return;
|
||||
// } else {
|
||||
// // spaceModelBloc.add(LinkSpaceModelEvent(
|
||||
// // selectedSpaceMode: widget.spaceModel.uuid));
|
||||
|
||||
// spaceModelBloc.add(ValidateSpaceModelEvent(context: context));
|
||||
// }
|
||||
|
||||
// Future.delayed(const Duration(seconds: 3), () {
|
||||
// Navigator.of(context).pop();
|
||||
// Navigator.of(context).pop();
|
||||
|
||||
// // showDialog(
|
||||
// // context: context,
|
||||
// // builder: (BuildContext dialogContext) {
|
||||
// // return const LinkingSuccessful();
|
||||
// // },
|
||||
// // );
|
||||
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (BuildContext dialogContext) {
|
||||
// return const ConfirmOverwriteDialog();
|
||||
// },
|
||||
// );
|
||||
// });
|
||||
// }),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
// // Method to build a detail row
|
||||
// Widget _buildDetailRow(String label, String value) {
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: Text(
|
||||
// label,
|
||||
// style: TextStyle(fontWeight: FontWeight.bold),
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(width: 8),
|
||||
// Expanded(
|
||||
// child: Text(
|
||||
// value,
|
||||
// style:
|
||||
// TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
// Widget _buildButton(String text, Color color, VoidCallback onPressed) {
|
||||
// return InkWell(
|
||||
// onTap: onPressed,
|
||||
// child: Center(
|
||||
// child: Text(
|
||||
// text,
|
||||
// style: TextStyle(
|
||||
// color: color, fontWeight: FontWeight.w400, fontSize: 14),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_state.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class LinkSpaceModelSpacesDialog extends StatefulWidget {
|
||||
final SpaceTemplateModel spaceModel;
|
||||
LinkSpaceModelSpacesDialog({super.key, required this.spaceModel});
|
||||
|
||||
const LinkSpaceModelSpacesDialog({super.key, required this.spaceModel});
|
||||
|
||||
@override
|
||||
State<LinkSpaceModelSpacesDialog> createState() =>
|
||||
@ -19,7 +244,8 @@ class LinkSpaceModelSpacesDialog extends StatefulWidget {
|
||||
|
||||
class _LinkSpaceModelSpacesDialogState
|
||||
extends State<LinkSpaceModelSpacesDialog> {
|
||||
TextEditingController searchController = TextEditingController();
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -34,6 +260,24 @@ class _LinkSpaceModelSpacesDialogState
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
backgroundColor: Colors.white,
|
||||
content: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.4,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildDialogContent(),
|
||||
_buildActionButtons(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDialogContent() {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(15.0),
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.4,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@ -98,9 +342,15 @@ class _LinkSpaceModelSpacesDialogState
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Buttons
|
||||
Row(
|
||||
Widget _buildActionButtons() {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
@ -138,80 +388,99 @@ class _LinkSpaceModelSpacesDialogState
|
||||
),
|
||||
),
|
||||
child: _buildButton(
|
||||
"Confirm", ColorsManager.onSecondaryColor, () {
|
||||
"Confirm",
|
||||
ColorsManager.onSecondaryColor,
|
||||
() {
|
||||
final spaceModelBloc = context.read<SpaceModelBloc>();
|
||||
if (!spaceModelBloc.hasSelectedSpaces) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content:
|
||||
Text("Please select at least one space")),
|
||||
content: Text("Please select at least one space")),
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
spaceModelBloc.add(ValidateSpaceModelEvent(context: context));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _handleConfirm() {
|
||||
final bloc = context.read<SpaceModelBloc>();
|
||||
if (!bloc.hasSelectedSpaces) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("Please select at least one space")),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger validation
|
||||
bloc.add(ValidateSpaceModelEvent());
|
||||
}
|
||||
|
||||
void _showLoadingDialog() {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
builder: (context) => const _LoadingDialog(),
|
||||
);
|
||||
}
|
||||
|
||||
void _handleValidationSuccess() {
|
||||
Navigator.of(context).pop(); // Close loading dialog
|
||||
|
||||
// Show overwrite confirmation
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => const ConfirmOverwriteDialog(),
|
||||
).then((_) {
|
||||
// Close main dialog after confirmation
|
||||
if (mounted) Navigator.of(context).pop();
|
||||
});
|
||||
}
|
||||
|
||||
void _handleValidationError(String message) {
|
||||
Navigator.of(context).pop(); // Close loading dialog
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(message)),
|
||||
);
|
||||
}
|
||||
|
||||
void _handleCancel() {
|
||||
if (mounted) Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
// Rest of your helper methods (_buildDetailRow, _buildButton, etc.)
|
||||
}
|
||||
|
||||
class _LoadingDialog extends StatelessWidget {
|
||||
const _LoadingDialog();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20)),
|
||||
elevation: 10,
|
||||
backgroundColor: Colors.white,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 30, horizontal: 50),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CustomLoadingIndicator(),
|
||||
const SizedBox(height: 20),
|
||||
const Text(
|
||||
"Linking in progress",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
).then(
|
||||
(value) {},
|
||||
);
|
||||
Future.delayed(const Duration(seconds: 3), () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (BuildContext dialogContext) {
|
||||
// return const LinkingSuccessful();
|
||||
// },
|
||||
// );
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext dialogContext) {
|
||||
return const ConfirmOverwriteDialog();
|
||||
},
|
||||
);
|
||||
});
|
||||
}),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(height: 16),
|
||||
Text("Linking in progress..."),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Method to build a detail row
|
||||
Widget _buildDetailRow(String label, String value) {
|
||||
// Method to build a detail row
|
||||
Widget _buildDetailRow(String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Row(
|
||||
@ -226,26 +495,23 @@ class _LinkSpaceModelSpacesDialogState
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style:
|
||||
TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
|
||||
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Button Widget
|
||||
Widget _buildButton(String text, Color color, VoidCallback onPressed) {
|
||||
Widget _buildButton(String text, Color color, VoidCallback onPressed) {
|
||||
return InkWell(
|
||||
onTap: onPressed,
|
||||
child: Center(
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
color: color, fontWeight: FontWeight.w400, fontSize: 14),
|
||||
style:
|
||||
TextStyle(color: color, fontWeight: FontWeight.w400, fontSize: 14),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,27 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||
|
||||
void showOverwriteDialog(BuildContext context) {
|
||||
void showOverwriteDialog(
|
||||
BuildContext context, SpaceModelBloc bloc, SpaceTemplateModel model) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return Container(
|
||||
return SizedBox(
|
||||
child: Dialog(
|
||||
shape:
|
||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
elevation: 10,
|
||||
backgroundColor: Colors.white,
|
||||
child: Container(
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.3,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 30, horizontal: 20),
|
||||
padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Title
|
||||
const Text(
|
||||
"Overwrite",
|
||||
style: TextStyle(
|
||||
@ -27,15 +30,13 @@ void showOverwriteDialog(BuildContext context) {
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
|
||||
// Description
|
||||
const SizedBox(height: 15),
|
||||
const Text(
|
||||
"Are you sure you want to overwrite?",
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
"Selected spaces already have linked space model / sub-spaces and devices",
|
||||
style: TextStyle(
|
||||
@ -44,25 +45,22 @@ void showOverwriteDialog(BuildContext context) {
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 25),
|
||||
|
||||
// Buttons
|
||||
const SizedBox(height: 25),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
// Cancel Button
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(vertical: 14),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
backgroundColor: Colors.grey[200],
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
elevation: 0,
|
||||
),
|
||||
child: Text(
|
||||
child: const Text(
|
||||
"Cancel",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
@ -72,24 +70,24 @@ void showOverwriteDialog(BuildContext context) {
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
|
||||
// OK Button
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
bloc.add(LinkSpaceModelEvent(
|
||||
isOverWrite: true,
|
||||
selectedSpaceMode: model.uuid));
|
||||
Navigator.of(context).pop();
|
||||
// Add action for OK button
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(vertical: 14),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
backgroundColor: Colors.blue,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
elevation: 3,
|
||||
),
|
||||
child: Text(
|
||||
child: const Text(
|
||||
"OK",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
|
@ -3,9 +3,13 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_state.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/link_space_model_spaces_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_attention_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/linking_successful.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
@ -74,15 +78,97 @@ class SpaceModelCardWidget extends StatelessWidget {
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext dialogContext) {
|
||||
return BlocProvider<SpaceModelBloc>(
|
||||
create: (_) => SpaceModelBloc(),
|
||||
child: BlocListener<SpaceModelBloc,
|
||||
SpaceModelState>(
|
||||
listener: (context, state) {
|
||||
final _bloc =
|
||||
BlocProvider.of<SpaceModelBloc>(
|
||||
context);
|
||||
if (state is SpaceModelLoading) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(20)),
|
||||
elevation: 10,
|
||||
backgroundColor: Colors.white,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(
|
||||
vertical: 30,
|
||||
horizontal: 50),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CustomLoadingIndicator(),
|
||||
const SizedBox(height: 20),
|
||||
const Text(
|
||||
"Linking in progress",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight:
|
||||
FontWeight.w500,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
} else if (state
|
||||
is AlreadyHaveLinkedState) {
|
||||
Navigator.of(dialogContext).pop();
|
||||
showOverwriteDialog(
|
||||
context, _bloc, model);
|
||||
} else if (state
|
||||
is SpaceValidationSuccess) {
|
||||
_bloc.add(LinkSpaceModelEvent(
|
||||
isOverWrite: false,
|
||||
selectedSpaceMode: model.uuid));
|
||||
|
||||
Future.delayed(const Duration(seconds: 1),
|
||||
() {
|
||||
Navigator.of(dialogContext).pop();
|
||||
Navigator.of(dialogContext).pop();
|
||||
Navigator.of(dialogContext).pop();
|
||||
});
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return BlocProvider<SpaceModelBloc>(
|
||||
create: (_) => SpaceModelBloc(),
|
||||
builder: (BuildContext dialogContext) {
|
||||
return const LinkingSuccessful();
|
||||
},
|
||||
).then((v) {
|
||||
Future.delayed(
|
||||
const Duration(seconds: 2), () {
|
||||
Navigator.of(dialogContext).pop();
|
||||
});
|
||||
});
|
||||
} else if (state is SpaceModelLinkSuccess) {
|
||||
Navigator.of(dialogContext).pop();
|
||||
Navigator.of(dialogContext).pop();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext dialogContext) {
|
||||
return const LinkingSuccessful();
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
child: LinkSpaceModelSpacesDialog(
|
||||
spaceModel: model,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -60,4 +60,40 @@ class SpaceModelManagementApi {
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future linkSpaceModel(
|
||||
{required String spaceModelUuid,
|
||||
required String projectId,
|
||||
required List<String> spaceUuids,
|
||||
required bool isOverWrite}) async {
|
||||
print(spaceModelUuid);
|
||||
print(projectId);
|
||||
print(spaceUuids);
|
||||
print(isOverWrite);
|
||||
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.linkSpaceModel
|
||||
.replaceAll('{projectId}', projectId)
|
||||
.replaceAll('{spaceModelUuid}', spaceModelUuid),
|
||||
showServerMessage: true,
|
||||
body: {"spaceUuids": spaceUuids, "overwrite": isOverWrite},
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future validateSpaceModel(String projectId, List<String> spaceUuids) async {
|
||||
final response = await HTTPService().post(
|
||||
path:
|
||||
ApiEndpoints.validateSpaceModel.replaceAll('{projectId}', projectId),
|
||||
showServerMessage: true,
|
||||
body: {"spacesUuids": spaceUuids},
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,19 @@ abstract class ApiEndpoints {
|
||||
static const String sendOtp = '/authentication/user/send-otp';
|
||||
static const String verifyOtp = '/authentication/user/verify-otp';
|
||||
static const String getRegion = '/region';
|
||||
static const String visitorPassword = '/projects/{projectId}/visitor-password';
|
||||
static const String getDevices = '/projects/{projectId}/visitor-password/devices';
|
||||
static const String visitorPassword =
|
||||
'/projects/{projectId}/visitor-password';
|
||||
static const String getDevices =
|
||||
'/projects/{projectId}/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';
|
||||
|
||||
@ -39,32 +43,45 @@ 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';
|
||||
@ -75,7 +92,8 @@ abstract class ApiEndpoints {
|
||||
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}';
|
||||
|
||||
@ -87,8 +105,15 @@ 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 linkSpaceModel =
|
||||
'/projects/{projectId}/space-models/{spaceModelUuid}/spaces/link';
|
||||
|
||||
static const String validateSpaceModel =
|
||||
'/projects/{projectId}/spaces/validate';
|
||||
|
||||
static const String roleTypes = '/role/types';
|
||||
static const String permission = '/permission/{roleUuid}';
|
||||
@ -99,7 +124,8 @@ 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}';
|
||||
|
Reference in New Issue
Block a user