mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
added tags and subspace to update space
This commit is contained in:
@ -5,12 +5,15 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_mod
|
|||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_state.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_body_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_body_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart';
|
||||||
import 'package:syncrow_web/services/product_api.dart';
|
import 'package:syncrow_web/services/product_api.dart';
|
||||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||||
import 'package:syncrow_web/services/space_model_mang_api.dart';
|
import 'package:syncrow_web/services/space_model_mang_api.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/action_enum.dart';
|
||||||
|
|
||||||
class SpaceManagementBloc
|
class SpaceManagementBloc
|
||||||
extends Bloc<SpaceManagementEvent, SpaceManagementState> {
|
extends Bloc<SpaceManagementEvent, SpaceManagementState> {
|
||||||
@ -341,7 +344,7 @@ class SpaceManagementBloc
|
|||||||
products: _cachedProducts ?? [],
|
products: _cachedProducts ?? [],
|
||||||
selectedCommunity: selectedCommunity,
|
selectedCommunity: selectedCommunity,
|
||||||
selectedSpace: selectedSpace,
|
selectedSpace: selectedSpace,
|
||||||
spaceModels: spaceModels ?? []));
|
spaceModels: spaceModels));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(SpaceManagementError('Error updating state: $e'));
|
emit(SpaceManagementError('Error updating state: $e'));
|
||||||
@ -428,16 +431,72 @@ class SpaceManagementBloc
|
|||||||
for (var space in orderedSpaces) {
|
for (var space in orderedSpaces) {
|
||||||
try {
|
try {
|
||||||
if (space.uuid != null && space.uuid!.isNotEmpty) {
|
if (space.uuid != null && space.uuid!.isNotEmpty) {
|
||||||
final response = await _api.updateSpace(
|
final prevSpace = await _api.getSpace(communityUuid, space.uuid!);
|
||||||
communityId: communityUuid,
|
final List<UpdateSubspaceTemplateModel> subspaceUpdates = [];
|
||||||
spaceId: space.uuid!,
|
final List<SubspaceModel>? prevSubspaces = prevSpace?.subspaces;
|
||||||
name: space.name,
|
final List<SubspaceModel>? newSubspaces = space.subspaces;
|
||||||
parentId: space.parent?.uuid,
|
|
||||||
isPrivate: space.isPrivate,
|
if (prevSubspaces != null || newSubspaces != null) {
|
||||||
position: space.position,
|
if (prevSubspaces != null && newSubspaces != null) {
|
||||||
icon: space.icon,
|
for (var prevSubspace in prevSubspaces) {
|
||||||
direction: space.incomingConnection?.direction,
|
final existsInNew = newSubspaces
|
||||||
);
|
.any((subspace) => subspace.uuid == prevSubspace.uuid);
|
||||||
|
if (!existsInNew) {
|
||||||
|
subspaceUpdates.add(UpdateSubspaceTemplateModel(
|
||||||
|
action: Action.delete, uuid: prevSubspace.uuid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (prevSubspaces != null && newSubspaces == null) {
|
||||||
|
for (var prevSubspace in prevSubspaces) {
|
||||||
|
subspaceUpdates.add(UpdateSubspaceTemplateModel(
|
||||||
|
action: Action.delete, uuid: prevSubspace.uuid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newSubspaces != null) {
|
||||||
|
for (var newSubspace in newSubspaces) {
|
||||||
|
// Tag without UUID
|
||||||
|
if ((newSubspace.uuid == null || newSubspace.uuid!.isEmpty)) {
|
||||||
|
final List<TagModelUpdate> tagUpdates = [];
|
||||||
|
|
||||||
|
if (newSubspace.tags != null) {
|
||||||
|
for (var tag in newSubspace.tags!) {
|
||||||
|
tagUpdates.add(TagModelUpdate(
|
||||||
|
action: Action.add,
|
||||||
|
uuid: tag.uuid == '' ? null : tag.uuid,
|
||||||
|
tag: tag.tag,
|
||||||
|
productUuid: tag.product?.uuid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subspaceUpdates.add(UpdateSubspaceTemplateModel(
|
||||||
|
action: Action.add,
|
||||||
|
subspaceName: newSubspace.subspaceName,
|
||||||
|
tags: tagUpdates));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevSubspaces != null && newSubspaces != null) {
|
||||||
|
final newSubspaceMap = {
|
||||||
|
for (var subspace in newSubspaces) subspace.uuid: subspace
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var prevSubspace in prevSubspaces) {
|
||||||
|
final newSubspace = newSubspaceMap[prevSubspace.uuid];
|
||||||
|
|
||||||
|
if (newSubspace != null) {
|
||||||
|
final List<TagModelUpdate> tagSubspaceUpdates =
|
||||||
|
processTagUpdates(prevSubspace.tags, newSubspace.tags);
|
||||||
|
subspaceUpdates.add(UpdateSubspaceTemplateModel(
|
||||||
|
action: Action.update,
|
||||||
|
uuid: newSubspace.uuid,
|
||||||
|
subspaceName: newSubspace.subspaceName,
|
||||||
|
tags: tagSubspaceUpdates));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Call create if the space does not have a UUID
|
// Call create if the space does not have a UUID
|
||||||
final List<CreateTagBodyModel> tagBodyModels = space.tags != null
|
final List<CreateTagBodyModel> tagBodyModels = space.tags != null
|
||||||
@ -455,6 +514,7 @@ class SpaceManagementBloc
|
|||||||
}).toList() ??
|
}).toList() ??
|
||||||
[];
|
[];
|
||||||
|
|
||||||
|
|
||||||
final response = await _api.createSpace(
|
final response = await _api.createSpace(
|
||||||
communityId: communityUuid,
|
communityId: communityUuid,
|
||||||
name: space.name,
|
name: space.name,
|
||||||
@ -535,4 +595,80 @@ class SpaceManagementBloc
|
|||||||
emit(SpaceManagementError('Error loading communities and spaces: $e'));
|
emit(SpaceManagementError('Error loading communities and spaces: $e'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<TagModelUpdate> processTagUpdates(
|
||||||
|
List<Tag>? prevTags,
|
||||||
|
List<Tag>? newTags,
|
||||||
|
) {
|
||||||
|
final List<TagModelUpdate> tagUpdates = [];
|
||||||
|
final processedTags = <String?>{};
|
||||||
|
|
||||||
|
if (prevTags == null && newTags != null) {
|
||||||
|
for (var newTag in newTags) {
|
||||||
|
tagUpdates.add(TagModelUpdate(
|
||||||
|
action: Action.add,
|
||||||
|
tag: newTag.tag,
|
||||||
|
uuid: newTag.uuid,
|
||||||
|
productUuid: newTag.product?.uuid,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return tagUpdates;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newTags != null || prevTags != null) {
|
||||||
|
// Case 1: Tags deleted
|
||||||
|
if (prevTags != null && newTags != null) {
|
||||||
|
for (var prevTag in prevTags) {
|
||||||
|
final existsInNew =
|
||||||
|
newTags.any((newTag) => newTag.uuid == prevTag.uuid);
|
||||||
|
if (!existsInNew) {
|
||||||
|
tagUpdates
|
||||||
|
.add(TagModelUpdate(action: Action.delete, uuid: prevTag.uuid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (prevTags != null && newTags == null) {
|
||||||
|
for (var prevTag in prevTags) {
|
||||||
|
tagUpdates
|
||||||
|
.add(TagModelUpdate(action: Action.delete, uuid: prevTag.uuid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2: Tags added
|
||||||
|
if (newTags != null) {
|
||||||
|
final prevTagUuids = prevTags?.map((t) => t.uuid).toSet() ?? {};
|
||||||
|
|
||||||
|
for (var newTag in newTags) {
|
||||||
|
// Tag without UUID
|
||||||
|
if ((newTag.uuid == null || !prevTagUuids.contains(newTag.uuid)) &&
|
||||||
|
!processedTags.contains(newTag.tag)) {
|
||||||
|
tagUpdates.add(TagModelUpdate(
|
||||||
|
action: Action.add,
|
||||||
|
tag: newTag.tag,
|
||||||
|
uuid: newTag.uuid == '' ? null : newTag.uuid,
|
||||||
|
productUuid: newTag.product?.uuid));
|
||||||
|
processedTags.add(newTag.tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 3: Tags updated
|
||||||
|
if (prevTags != null && newTags != null) {
|
||||||
|
final newTagMap = {for (var tag in newTags) tag.uuid: tag};
|
||||||
|
|
||||||
|
for (var prevTag in prevTags) {
|
||||||
|
final newTag = newTagMap[prevTag.uuid];
|
||||||
|
if (newTag != null) {
|
||||||
|
tagUpdates.add(TagModelUpdate(
|
||||||
|
action: Action.update,
|
||||||
|
uuid: newTag.uuid,
|
||||||
|
tag: newTag.tag,
|
||||||
|
));
|
||||||
|
} else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tagUpdates;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,8 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
widget.selectedProducts.isNotEmpty ? widget.selectedProducts : [];
|
widget.selectedProducts.isNotEmpty ? widget.selectedProducts : [];
|
||||||
isOkButtonEnabled =
|
isOkButtonEnabled =
|
||||||
enteredName.isNotEmpty || nameController.text.isNotEmpty;
|
enteredName.isNotEmpty || nameController.text.isNotEmpty;
|
||||||
|
tags = widget.tags ?? [];
|
||||||
|
subspaces = widget.subspaces ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -237,7 +239,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
width: screenWidth * 0.35,
|
width: screenWidth * 0.25,
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 10.0, horizontal: 16.0),
|
vertical: 10.0, horizontal: 16.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -312,7 +314,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 25),
|
const SizedBox(height: 25),
|
||||||
subspaces == null
|
subspaces == null || subspaces!.isEmpty
|
||||||
? TextButton(
|
? TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
@ -344,21 +346,29 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
runSpacing: 8.0,
|
runSpacing: 8.0,
|
||||||
children: [
|
children: [
|
||||||
if (subspaces != null)
|
if (subspaces != null)
|
||||||
...subspaces!.map((subspace) =>
|
...subspaces!.map((subspace) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
SubspaceNameDisplayWidget(
|
SubspaceNameDisplayWidget(
|
||||||
validateName: (updatedName) {
|
|
||||||
return !subspaces!.any((s) =>
|
|
||||||
s != subspace &&
|
|
||||||
s.subspaceName == updatedName);
|
|
||||||
},
|
|
||||||
text: subspace.subspaceName,
|
text: subspace.subspaceName,
|
||||||
|
validateName: (updatedName) {
|
||||||
|
return subspaces!.any((s) =>
|
||||||
|
s != subspace &&
|
||||||
|
s.subspaceName ==
|
||||||
|
updatedName);
|
||||||
|
},
|
||||||
onNameChanged: (updatedName) {
|
onNameChanged: (updatedName) {
|
||||||
setState(() {
|
setState(() {
|
||||||
subspace.subspaceName =
|
subspace.subspaceName =
|
||||||
updatedName;
|
updatedName;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
)),
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
EditChip(
|
EditChip(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_showSubSpaceDialog(context, enteredName,
|
_showSubSpaceDialog(context, enteredName,
|
||||||
@ -425,14 +435,29 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
),
|
),
|
||||||
|
|
||||||
EditChip(onTap: () async {
|
EditChip(onTap: () async {
|
||||||
_showTagCreateDialog(
|
final result = await showDialog(
|
||||||
context,
|
context: context,
|
||||||
enteredName,
|
builder: (context) => AssignTagDialog(
|
||||||
widget.isEdit,
|
products: widget.products,
|
||||||
widget.products,
|
subspaces: widget.subspaces,
|
||||||
subspaces,
|
addedProducts: TagHelper
|
||||||
|
.createInitialSelectedProductsForTags(
|
||||||
|
tags ?? [], subspaces),
|
||||||
|
title: 'Edit Device',
|
||||||
|
initialTags:
|
||||||
|
TagHelper.generateInitialForTags(
|
||||||
|
spaceTags: tags,
|
||||||
|
subspaces: subspaces),
|
||||||
|
spaceName: widget.name ?? '',
|
||||||
|
onSave:
|
||||||
|
(updatedTags, updatedSubspaces) {
|
||||||
|
setState(() {
|
||||||
|
tags = updatedTags;
|
||||||
|
subspaces = updatedSubspaces;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
// Edit action
|
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -547,6 +572,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
selectedSpaceModel = selectedModel;
|
selectedSpaceModel = selectedModel;
|
||||||
subspaces = null;
|
subspaces = null;
|
||||||
|
tags = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -610,6 +636,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
products: products,
|
products: products,
|
||||||
subspaces: subspaces,
|
subspaces: subspaces,
|
||||||
spaceTags: tags,
|
spaceTags: tags,
|
||||||
|
isCreate: true,
|
||||||
allTags: [],
|
allTags: [],
|
||||||
initialSelectedProducts:
|
initialSelectedProducts:
|
||||||
TagHelper.createInitialSelectedProductsForTags(
|
TagHelper.createInitialSelectedProductsForTags(
|
||||||
|
@ -82,7 +82,6 @@ class SubSpaceBloc extends Bloc<SubSpaceEvent, SubSpaceState> {
|
|||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
on<UpdateSubSpace>((event, emit) {
|
on<UpdateSubSpace>((event, emit) {
|
||||||
final updatedSubSpaces = state.subSpaces.map((subSpace) {
|
final updatedSubSpaces = state.subSpaces.map((subSpace) {
|
||||||
if (subSpace.uuid == event.updatedSubSpace.uuid) {
|
if (subSpace.uuid == event.updatedSubSpace.uuid) {
|
||||||
|
@ -4,7 +4,9 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subs
|
|||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_response_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_response_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/create_space_template_body_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/create_space_template_body_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_body_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_body_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||||
import 'package:syncrow_web/utils/constants/temp_const.dart';
|
import 'package:syncrow_web/utils/constants/temp_const.dart';
|
||||||
@ -219,6 +221,8 @@ class CommunitySpaceManagementApi {
|
|||||||
String? direction,
|
String? direction,
|
||||||
bool isPrivate = false,
|
bool isPrivate = false,
|
||||||
required Offset position,
|
required Offset position,
|
||||||
|
List<TagModelUpdate>? tags,
|
||||||
|
List<UpdateSubspaceTemplateModel>? subspaces,
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
final body = {
|
final body = {
|
||||||
@ -228,6 +232,8 @@ class CommunitySpaceManagementApi {
|
|||||||
'y': position.dy,
|
'y': position.dy,
|
||||||
'direction': direction,
|
'direction': direction,
|
||||||
'icon': icon,
|
'icon': icon,
|
||||||
|
'subspace':subspaces,
|
||||||
|
'tags':tags,
|
||||||
};
|
};
|
||||||
if (parentId != null) {
|
if (parentId != null) {
|
||||||
body['parentUuid'] = parentId;
|
body['parentUuid'] = parentId;
|
||||||
|
Reference in New Issue
Block a user