mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-11-26 22:14:56 +00:00
added space model link to space dialog
This commit is contained in:
@ -7,8 +7,8 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_pr
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/hoverable_button.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/selected_products_button_widget.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
import 'package:syncrow_web/utils/constants/space_icon_const.dart';
|
||||
@ -23,6 +23,7 @@ class CreateSpaceDialog extends StatefulWidget {
|
||||
final List<SelectedProduct> selectedProducts;
|
||||
final SpaceModel? parentSpace;
|
||||
final SpaceModel? editSpace;
|
||||
final List<SpaceTemplateModel>? spaceModels;
|
||||
|
||||
const CreateSpaceDialog(
|
||||
{super.key,
|
||||
@ -33,7 +34,8 @@ class CreateSpaceDialog extends StatefulWidget {
|
||||
this.icon,
|
||||
this.isEdit = false,
|
||||
this.editSpace,
|
||||
this.selectedProducts = const []});
|
||||
this.selectedProducts = const [],
|
||||
this.spaceModels});
|
||||
|
||||
@override
|
||||
CreateSpaceDialogState createState() => CreateSpaceDialogState();
|
||||
@ -59,275 +61,289 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
||||
enteredName.isNotEmpty || nameController.text.isNotEmpty;
|
||||
}
|
||||
|
||||
@override
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
return AlertDialog(
|
||||
title: widget.isEdit
|
||||
? const Text('Edit Space')
|
||||
: const Text('Create New Space'),
|
||||
backgroundColor: ColorsManager.whiteColors,
|
||||
content: SizedBox(
|
||||
width: screenWidth * 0.5, // Limit dialog width
|
||||
width: screenWidth * 0.5,
|
||||
child: SingleChildScrollView(
|
||||
// Scrollable content to prevent overflow
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: screenWidth * 0.1, // Adjusted width
|
||||
height: screenWidth * 0.1, // Adjusted height
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
selectedIcon,
|
||||
width: screenWidth * 0.04,
|
||||
height: screenWidth * 0.04,
|
||||
),
|
||||
Positioned(
|
||||
top: 6,
|
||||
right: 6,
|
||||
child: InkWell(
|
||||
onTap: _showIconSelectionDialog,
|
||||
child: Container(
|
||||
width: screenWidth * 0.020,
|
||||
height: screenWidth * 0.020,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconEdit,
|
||||
width: screenWidth * 0.06,
|
||||
height: screenWidth * 0.06,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
// Ensure the text field expands responsively
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
TextField(
|
||||
controller: nameController,
|
||||
onChanged: (value) {
|
||||
enteredName = value.trim();
|
||||
setState(() {
|
||||
isNameFieldExist = false;
|
||||
isOkButtonEnabled = false;
|
||||
isNameFieldInvalid = value.isEmpty;
|
||||
|
||||
if (!isNameFieldInvalid) {
|
||||
if (_isNameConflict(value)) {
|
||||
isNameFieldExist = true;
|
||||
isOkButtonEnabled = false;
|
||||
} else {
|
||||
isNameFieldExist = false;
|
||||
isOkButtonEnabled = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Please enter the name',
|
||||
hintStyle: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: ColorsManager.lightGrayColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: ColorsManager.boxColor,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: isNameFieldInvalid || isNameFieldExist
|
||||
? ColorsManager.red
|
||||
: ColorsManager.boxColor,
|
||||
width: 1.5,
|
||||
Container(
|
||||
width: screenWidth * 0.1,
|
||||
height: screenWidth * 0.1,
|
||||
decoration: const BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
selectedIcon,
|
||||
width: screenWidth * 0.04,
|
||||
height: screenWidth * 0.04,
|
||||
),
|
||||
Positioned(
|
||||
top: 20,
|
||||
right: 20,
|
||||
child: InkWell(
|
||||
onTap: _showIconSelectionDialog,
|
||||
child: Container(
|
||||
width: 24,
|
||||
height: 24,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: const BorderSide(
|
||||
color: ColorsManager.boxColor,
|
||||
width: 1.5,
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconEdit,
|
||||
width: 16,
|
||||
height: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isNameFieldInvalid)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'*Space name should not be empty.',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
?.copyWith(color: ColorsManager.red),
|
||||
),
|
||||
),
|
||||
if (isNameFieldExist)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'*Name already exist',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
?.copyWith(color: ColorsManager.red),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
DefaultButton(
|
||||
onPressed: () {},
|
||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||
foregroundColor: Colors.black,
|
||||
borderColor: ColorsManager.neutralGray,
|
||||
borderRadius: 16.0,
|
||||
padding: 10.0, // Reduced padding for smaller size
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.addIcon,
|
||||
width: screenWidth *
|
||||
0.015, // Adjust icon size
|
||||
height: screenWidth * 0.015,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Link a space model',
|
||||
overflow: TextOverflow
|
||||
.ellipsis, // Prevent overflow
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
const SizedBox(height: 30),
|
||||
DefaultButton(
|
||||
onPressed: () {},
|
||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||
foregroundColor: Colors.black,
|
||||
borderColor: ColorsManager.neutralGray,
|
||||
borderRadius: 16.0,
|
||||
padding: 10.0, // Reduced padding for smaller size
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.addIcon,
|
||||
width: screenWidth *
|
||||
0.015, // Adjust icon size
|
||||
height: screenWidth * 0.015,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Create sub space',
|
||||
overflow: TextOverflow
|
||||
.ellipsis, // Prevent overflow
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
if (selectedProducts.isNotEmpty)
|
||||
SelectedProductsButtons(
|
||||
products: widget.products ?? [],
|
||||
selectedProducts: selectedProducts,
|
||||
onProductsUpdated: (updatedProducts) {
|
||||
setState(() {
|
||||
selectedProducts = updatedProducts;
|
||||
});
|
||||
},
|
||||
context: context,
|
||||
)
|
||||
else
|
||||
DefaultButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AddDeviceWidget(
|
||||
products: widget.products,
|
||||
onProductsSelected: (selectedProductsMap) {
|
||||
setState(() {
|
||||
selectedProducts = selectedProductsMap;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||
foregroundColor: Colors.black,
|
||||
borderColor: ColorsManager.neutralGray,
|
||||
borderRadius: 16.0,
|
||||
padding: 10.0, // Reduced padding for smaller size
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.addIcon,
|
||||
width: screenWidth *
|
||||
0.015, // Adjust icon size
|
||||
height: screenWidth * 0.015,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Add devices / Assign a space model',
|
||||
overflow: TextOverflow
|
||||
.ellipsis, // Prevent overflow
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextField(
|
||||
controller: nameController,
|
||||
onChanged: (value) {
|
||||
enteredName = value.trim();
|
||||
setState(() {
|
||||
isNameFieldExist = false;
|
||||
isOkButtonEnabled = false;
|
||||
isNameFieldInvalid = value.isEmpty;
|
||||
|
||||
if (!isNameFieldInvalid) {
|
||||
if (_isNameConflict(value)) {
|
||||
isNameFieldExist = true;
|
||||
isOkButtonEnabled = false;
|
||||
} else {
|
||||
isNameFieldExist = false;
|
||||
isOkButtonEnabled = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Please enter the name',
|
||||
hintStyle: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: ColorsManager.lightGrayColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: ColorsManager.boxColor,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: isNameFieldInvalid || isNameFieldExist
|
||||
? ColorsManager.red
|
||||
: ColorsManager.boxColor,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: const BorderSide(
|
||||
color: ColorsManager.boxColor,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isNameFieldInvalid)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'*Space name should not be empty.',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
?.copyWith(color: ColorsManager.red),
|
||||
),
|
||||
),
|
||||
if (isNameFieldExist)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'*Name already exist',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall
|
||||
?.copyWith(color: ColorsManager.red),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
DefaultButton(
|
||||
onPressed: () {
|
||||
_showLinkSpaceModelDialog(context);
|
||||
},
|
||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||
foregroundColor: Colors.black,
|
||||
borderColor: ColorsManager.neutralGray,
|
||||
borderRadius: 16.0,
|
||||
padding: 10.0, // Reduced padding for smaller size
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.link,
|
||||
width: screenWidth * 0.015, // Adjust icon size
|
||||
height: screenWidth * 0.015,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Link a space model',
|
||||
overflow:
|
||||
TextOverflow.ellipsis, // Prevent overflow
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
const Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Divider(
|
||||
color: ColorsManager.neutralGray,
|
||||
thickness: 1.0,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Text(
|
||||
'OR',
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Divider(
|
||||
color: ColorsManager.neutralGray,
|
||||
thickness: 1.0,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
DefaultButton(
|
||||
onPressed: () {},
|
||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||
foregroundColor: Colors.black,
|
||||
borderColor: ColorsManager.neutralGray,
|
||||
borderRadius: 16.0,
|
||||
padding: 10.0, // Reduced padding for smaller size
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.addIcon,
|
||||
width: screenWidth * 0.015, // Adjust icon size
|
||||
height: screenWidth * 0.015,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Create sub space',
|
||||
overflow:
|
||||
TextOverflow.ellipsis, // Prevent overflow
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
DefaultButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AddDeviceWidget(
|
||||
products: widget.products,
|
||||
onProductsSelected: (selectedProductsMap) {
|
||||
setState(() {
|
||||
selectedProducts = selectedProductsMap;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
||||
foregroundColor: Colors.black,
|
||||
borderColor: ColorsManager.neutralGray,
|
||||
borderRadius: 16.0,
|
||||
padding: 10.0, // Reduced padding for smaller size
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6.0),
|
||||
child: SvgPicture.asset(
|
||||
Assets.addIcon,
|
||||
width: screenWidth * 0.015, // Adjust icon size
|
||||
height: screenWidth * 0.015,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 3),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'Add devices',
|
||||
overflow:
|
||||
TextOverflow.ellipsis, // Prevent overflow
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -401,4 +417,22 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
||||
(widget.editSpace?.children.any((child) => child.name == value) ??
|
||||
false);
|
||||
}
|
||||
|
||||
void _showLinkSpaceModelDialog(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return LinkSpaceModelDialog(
|
||||
spaceModels: widget.spaceModels ?? [],
|
||||
onSave: (selectedModel) {
|
||||
if (selectedModel != null) {
|
||||
print('Selected Model: ${selectedModel.modelName}');
|
||||
} else {
|
||||
print('No model selected');
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user