Merge pull request #82 from SyncrowIOT/SP-951-FE-Link-Space-Model-Pop-Up

added edit space sibling conflict
This commit is contained in:
hannathkadher
2025-02-04 15:57:37 +04:00
committed by GitHub
3 changed files with 110 additions and 73 deletions

View File

@ -12,6 +12,7 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/helper/space_helper.dart';
import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.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';
@ -95,6 +96,10 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
@override
Widget build(BuildContext context) {
bool isSpaceModelDisabled = (tags != null && tags!.isNotEmpty ||
subspaces != null && subspaces!.isNotEmpty);
bool isTagsAndSubspaceModelDisabled = (selectedSpaceModel != null);
final screenWidth = MediaQuery.of(context).size.width;
return AlertDialog(
title: widget.isEdit
@ -173,7 +178,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
isNameFieldInvalid = value.isEmpty;
if (!isNameFieldInvalid) {
if (_isNameConflict(value)) {
if (SpaceHelper.isNameConflict(value, widget.parentSpace, widget.editSpace)) {
isNameFieldExist = true;
isOkButtonEnabled = false;
} else {
@ -240,11 +245,14 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
padding: EdgeInsets.zero,
),
onPressed: () {
_showLinkSpaceModelDialog(context);
isSpaceModelDisabled
? null
: _showLinkSpaceModelDialog(context);
},
child: const ButtonContentWidget(
child: ButtonContentWidget(
svgAssets: Assets.link,
label: 'Link a space model',
disabled: isSpaceModelDisabled,
),
)
: Container(
@ -333,12 +341,15 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
overlayColor: ColorsManager.transparentColor,
),
onPressed: () async {
_showSubSpaceDialog(context, enteredName, [],
false, widget.products, subspaces);
isTagsAndSubspaceModelDisabled
? null
: _showSubSpaceDialog(context, enteredName,
[], false, widget.products, subspaces);
},
child: const ButtonContentWidget(
child: ButtonContentWidget(
icon: Icons.add,
label: 'Create Sub Space',
disabled: isTagsAndSubspaceModelDisabled,
),
)
: SizedBox(
@ -492,7 +503,9 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
)
: TextButton(
onPressed: () {
_showTagCreateDialog(
isTagsAndSubspaceModelDisabled
? null
: _showTagCreateDialog(
context,
enteredName,
widget.isEdit,
@ -502,9 +515,10 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
),
child: const ButtonContentWidget(
child: ButtonContentWidget(
icon: Icons.add,
label: 'Add Devices',
disabled: isTagsAndSubspaceModelDisabled,
))
],
),
@ -578,25 +592,6 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
);
}
bool _isNameConflict(String value) {
final parentSpace = widget.parentSpace;
final editSpace = widget.editSpace;
final siblings = parentSpace?.children
.where((child) => child.uuid != editSpace?.uuid)
.toList() ??
[];
final siblingConflict = siblings.any((child) => child.name == value);
final parentConflict =
parentSpace?.name == value && parentSpace?.uuid != editSpace?.uuid;
final parentOfEditSpaceConflict = editSpace?.parent?.name == value &&
editSpace?.parent?.uuid != editSpace?.uuid;
final childConflict =
editSpace?.children.any((child) => child.name == value) ?? false;
return siblingConflict ||
parentConflict ||
parentOfEditSpaceConflict ||
childConflict;
}
void _showLinkSpaceModelDialog(BuildContext context) {
showDialog(

View File

@ -58,4 +58,37 @@ class SpaceHelper {
?.any((child) => child.internalId == space.internalId) ==
true;
}
static bool isNameConflict(
String value, SpaceModel? parentSpace, SpaceModel? editSpace) {
final siblings = parentSpace?.children
.where((child) => child.internalId != editSpace?.internalId)
.toList() ??
[];
final editSiblings = editSpace?.parent?.children
.where((child) => child.internalId != editSpace.internalId)
.toList() ??
[];
final editSiblingConflict =
editSiblings.any((child) => child.name == value);
final siblingConflict = siblings.any((child) => child.name == value);
final parentConflict = parentSpace?.name == value &&
parentSpace?.internalId != editSpace?.internalId;
final parentOfEditSpaceConflict = editSpace?.parent?.name == value &&
editSpace?.parent?.internalId != editSpace?.internalId;
final childConflict =
editSpace?.children.any((child) => child.name == value) ?? false;
return siblingConflict ||
parentConflict ||
editSiblingConflict ||
parentOfEditSpaceConflict ||
childConflict;
}
}

View File

@ -6,16 +6,23 @@ class ButtonContentWidget extends StatelessWidget {
final IconData? icon;
final String label;
final String? svgAssets;
final bool disabled;
const ButtonContentWidget(
{Key? key, this.icon, required this.label, this.svgAssets})
: super(key: key);
const ButtonContentWidget({
Key? key,
this.icon,
required this.label,
this.svgAssets,
this.disabled = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return SizedBox(
return Opacity(
opacity: disabled ? 0.5 : 1.0,
child: SizedBox(
width: screenWidth * 0.25,
child: Container(
decoration: BoxDecoration(
@ -27,7 +34,8 @@ class ButtonContentWidget extends StatelessWidget {
borderRadius: BorderRadius.circular(20),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
padding:
const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
child: Row(
children: [
if (icon != null)
@ -58,6 +66,7 @@ class ButtonContentWidget extends StatelessWidget {
),
),
),
),
);
}
}