mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-14 09:17:37 +00:00
edit flow
This commit is contained in:
@ -3,6 +3,7 @@ import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_spac
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_state.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/subspace_template_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
||||
import 'package:syncrow_web/services/space_model_mang_api.dart';
|
||||
|
||||
@ -67,36 +68,102 @@ class CreateSpaceModelBloc
|
||||
_space = event.spaceTemplate;
|
||||
emit(CreateSpaceModelLoaded(_space!));
|
||||
});
|
||||
|
||||
on<AddSubspacesToSpaceTemplate>((event, emit) {
|
||||
final currentState = state;
|
||||
|
||||
if (currentState is CreateSpaceModelLoaded) {
|
||||
final updatedSpace = currentState.space.copyWith(
|
||||
subspaceModels: [
|
||||
...(_space!.subspaceModels ?? []),
|
||||
...event.subspaces,
|
||||
],
|
||||
);
|
||||
final eventSubspaceIds =
|
||||
event.subspaces.map((e) => e.internalId).toSet();
|
||||
|
||||
// Update or retain subspaces
|
||||
final updatedSubspaces = currentState.space.subspaceModels
|
||||
?.where((subspace) =>
|
||||
eventSubspaceIds.contains(subspace.internalId))
|
||||
.map((subspace) {
|
||||
final matchingEventSubspace = event.subspaces.firstWhere(
|
||||
(e) => e.internalId == subspace.internalId,
|
||||
orElse: () => subspace,
|
||||
);
|
||||
|
||||
// Update the subspace's tags
|
||||
final eventTagIds = matchingEventSubspace.tags
|
||||
?.map((e) => e.internalId)
|
||||
.toSet() ??
|
||||
{};
|
||||
|
||||
final updatedTags = [
|
||||
...?subspace.tags?.map<TagModel>((tag) {
|
||||
final matchingTag =
|
||||
matchingEventSubspace.tags?.firstWhere(
|
||||
(e) => e.internalId == tag.internalId,
|
||||
orElse: () => tag,
|
||||
);
|
||||
final isUpdated = matchingTag != tag;
|
||||
return isUpdated
|
||||
? tag.copyWith(tag: matchingTag?.tag)
|
||||
: tag;
|
||||
}) ??
|
||||
<TagModel>[],
|
||||
...?matchingEventSubspace.tags?.where(
|
||||
(e) =>
|
||||
subspace.tags
|
||||
?.every((t) => t.internalId != e.internalId) ??
|
||||
true,
|
||||
) ??
|
||||
<TagModel>[],
|
||||
];
|
||||
return subspace.copyWith(
|
||||
subspaceName: matchingEventSubspace.subspaceName,
|
||||
tags: updatedTags,
|
||||
);
|
||||
}).toList() ??
|
||||
[];
|
||||
|
||||
// Add new subspaces
|
||||
event.subspaces
|
||||
.where((e) =>
|
||||
updatedSubspaces.every((s) => s.internalId != e.internalId))
|
||||
.forEach((newSubspace) {
|
||||
updatedSubspaces.add(newSubspace);
|
||||
});
|
||||
|
||||
final updatedSpace =
|
||||
currentState.space.copyWith(subspaceModels: updatedSubspaces);
|
||||
|
||||
emit(CreateSpaceModelLoaded(updatedSpace));
|
||||
} else {
|
||||
emit(CreateSpaceModelError("Space template not initialized"));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
on<AddTagsToSpaceTemplate>((event, emit) {
|
||||
final currentState = state;
|
||||
|
||||
if (currentState is CreateSpaceModelLoaded) {
|
||||
final updatedTags = currentState.space.copyWith(
|
||||
tags: [
|
||||
...(_space!.tags ?? []),
|
||||
...event.tags,
|
||||
],
|
||||
);
|
||||
emit(CreateSpaceModelLoaded(updatedTags));
|
||||
final eventTagIds = event.tags.map((e) => e.internalId).toSet();
|
||||
|
||||
final updatedTags = currentState.space.tags
|
||||
?.where((tag) => eventTagIds.contains(tag.internalId))
|
||||
.map((tag) {
|
||||
final matchingEventTag = event.tags.firstWhere(
|
||||
(e) => e.internalId == tag.internalId,
|
||||
orElse: () => tag,
|
||||
);
|
||||
return matchingEventTag != tag
|
||||
? tag.copyWith(tag: matchingEventTag.tag)
|
||||
: tag;
|
||||
}).toList() ??
|
||||
[];
|
||||
|
||||
event.tags
|
||||
.where(
|
||||
(e) => updatedTags.every((t) => t.internalId != e.internalId))
|
||||
.forEach((e) {
|
||||
updatedTags.add(e);
|
||||
});
|
||||
|
||||
emit(CreateSpaceModelLoaded(
|
||||
currentState.space.copyWith(tags: updatedTags)));
|
||||
} else {
|
||||
emit(CreateSpaceModelError("Space template not initialized"));
|
||||
}
|
||||
@ -106,7 +173,6 @@ class CreateSpaceModelBloc
|
||||
final currentState = state;
|
||||
if (currentState is CreateSpaceModelLoaded) {
|
||||
if (event.name.trim().isEmpty) {
|
||||
|
||||
emit(CreateSpaceModelLoaded(
|
||||
currentState.space,
|
||||
errorMessage: "Model name cannot be empty",
|
||||
@ -114,7 +180,7 @@ class CreateSpaceModelBloc
|
||||
} else {
|
||||
final updatedSpaceModel =
|
||||
currentState.space.copyWith(modelName: event.name);
|
||||
|
||||
|
||||
emit(CreateSpaceModelLoaded(updatedSpaceModel));
|
||||
}
|
||||
} else {
|
||||
|
@ -1,22 +1,28 @@
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class SubspaceTemplateModel {
|
||||
final String? uuid;
|
||||
String subspaceName;
|
||||
final bool disabled;
|
||||
List<TagModel>? tags;
|
||||
String internalId;
|
||||
|
||||
SubspaceTemplateModel({
|
||||
this.uuid,
|
||||
required this.subspaceName,
|
||||
required this.disabled,
|
||||
this.tags,
|
||||
});
|
||||
String? internalId,
|
||||
}) : internalId = internalId ?? const Uuid().v4();
|
||||
|
||||
factory SubspaceTemplateModel.fromJson(Map<String, dynamic> json) {
|
||||
final String internalId = json['internalId'] ?? const Uuid().v4();
|
||||
|
||||
return SubspaceTemplateModel(
|
||||
uuid: json['uuid'] ?? '',
|
||||
subspaceName: json['subspaceName'] ?? '',
|
||||
internalId: internalId,
|
||||
disabled: json['disabled'] ?? false,
|
||||
tags: (json['tags'] as List<dynamic>?)
|
||||
?.map((item) => TagModel.fromJson(item))
|
||||
@ -33,4 +39,20 @@ class SubspaceTemplateModel {
|
||||
'tags': tags?.map((e) => e.toJson()).toList() ?? [],
|
||||
};
|
||||
}
|
||||
|
||||
SubspaceTemplateModel copyWith({
|
||||
String? uuid,
|
||||
String? subspaceName,
|
||||
bool? disabled,
|
||||
List<TagModel>? tags,
|
||||
String? internalId,
|
||||
}) {
|
||||
return SubspaceTemplateModel(
|
||||
uuid: uuid ?? this.uuid,
|
||||
subspaceName: subspaceName ?? this.subspaceName,
|
||||
disabled: disabled ?? this.disabled,
|
||||
tags: tags ?? this.tags,
|
||||
internalId: internalId ?? this.internalId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -30,15 +30,16 @@ class TagModel {
|
||||
);
|
||||
}
|
||||
|
||||
TagModel copyWith({
|
||||
String? tag,
|
||||
ProductModel? product,
|
||||
String? location,
|
||||
}) {
|
||||
TagModel copyWith(
|
||||
{String? tag,
|
||||
ProductModel? product,
|
||||
String? location,
|
||||
String? internalId}) {
|
||||
return TagModel(
|
||||
tag: tag ?? this.tag,
|
||||
product: product ?? this.product,
|
||||
location: location ?? this.location,
|
||||
internalId: internalId ?? this.internalId,
|
||||
);
|
||||
}
|
||||
|
||||
@ -58,4 +59,4 @@ extension TagModelExtensions on TagModel {
|
||||
..tag = tag ?? ''
|
||||
..productUuid = product?.uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,15 +44,15 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
||||
child: BlocProvider(
|
||||
create: (_) {
|
||||
final bloc = CreateSpaceModelBloc(_spaceModelApi);
|
||||
if (spaceModel != null) {
|
||||
bloc.add(UpdateSpaceTemplate(spaceModel!));
|
||||
} else {
|
||||
bloc.add(UpdateSpaceTemplate(SpaceTemplateModel(
|
||||
modelName: '',
|
||||
subspaceModels: const [],
|
||||
)));
|
||||
}
|
||||
|
||||
if (spaceModel != null) {
|
||||
bloc.add(UpdateSpaceTemplate(spaceModel!));
|
||||
} else {
|
||||
bloc.add(UpdateSpaceTemplate(SpaceTemplateModel(
|
||||
modelName: '',
|
||||
subspaceModels: const [],
|
||||
)));
|
||||
}
|
||||
|
||||
spaceNameController.addListener(() {
|
||||
bloc.add(UpdateSpaceTemplateName(name: spaceNameController.text));
|
||||
});
|
||||
@ -72,7 +72,9 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
spaceModel?.uuid == null ? 'Create New Space Model': 'Edit Space Model',
|
||||
spaceModel?.uuid == null
|
||||
? 'Create New Space Model'
|
||||
: 'Edit Space Model',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineLarge
|
||||
@ -127,16 +129,18 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
||||
allTags: allTags,
|
||||
spaceNameController: spaceNameController,
|
||||
onLoad: (tags, subspaces) {
|
||||
if(subspaces!=null){
|
||||
context
|
||||
.read<CreateSpaceModelBloc>()
|
||||
.add(AddSubspacesToSpaceTemplate(subspaces));
|
||||
}
|
||||
if(tags!=null){
|
||||
if (context.read<CreateSpaceModelBloc>().state
|
||||
is CreateSpaceModelLoaded) {
|
||||
if (subspaces != null) {
|
||||
context
|
||||
.read<CreateSpaceModelBloc>()
|
||||
.add(AddTagsToSpaceTemplate(tags));
|
||||
|
||||
.read<CreateSpaceModelBloc>()
|
||||
.add(AddSubspacesToSpaceTemplate(subspaces));
|
||||
}
|
||||
if (tags != null) {
|
||||
context
|
||||
.read<CreateSpaceModelBloc>()
|
||||
.add(AddTagsToSpaceTemplate(tags));
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.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/subspace_template_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
||||
@ -53,7 +54,7 @@ class TagChipDisplay extends StatelessWidget {
|
||||
runSpacing: 8.0,
|
||||
children: [
|
||||
// Combine tags from spaceModel and subspaces
|
||||
..._groupTags([
|
||||
...TagHelper.groupTags([
|
||||
...?spaceModel?.tags,
|
||||
...?spaceModel?.subspaceModels
|
||||
?.expand((subspace) => subspace.tags ?? [])
|
||||
@ -84,24 +85,32 @@ class TagChipDisplay extends StatelessWidget {
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
Navigator.of(context).pop();
|
||||
// Use the Navigator's context for showDialog
|
||||
final navigatorContext =
|
||||
Navigator.of(context).overlay?.context;
|
||||
|
||||
await showDialog<bool>(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (context) => AddDeviceTypeModelWidget(
|
||||
isCreate: false,
|
||||
products: products,
|
||||
subspaces: subspaces,
|
||||
allTags: allTags,
|
||||
spaceName: spaceNameController.text,
|
||||
spaceTagModels: spaceModel?.tags,
|
||||
initialSelectedProducts:
|
||||
_createInitialSelectedProducts(
|
||||
spaceModel?.tags, spaceModel?.subspaceModels),
|
||||
),
|
||||
);
|
||||
// Edit action
|
||||
if (navigatorContext != null) {
|
||||
await showDialog<bool>(
|
||||
barrierDismissible: false,
|
||||
context: navigatorContext,
|
||||
builder: (context) => AssignTagModelsDialog(
|
||||
products: products,
|
||||
subspaces: subspaces,
|
||||
allTags: allTags,
|
||||
initialTags: TagHelper.generateInitialTags(
|
||||
subspaces: subspaces,
|
||||
spaceTagModels: spaceModel?.tags ?? []),
|
||||
title: 'Edit Device',
|
||||
addedProducts:
|
||||
TagHelper.createInitialSelectedProducts(
|
||||
spaceModel?.tags ?? [], subspaces),
|
||||
spaceName: spaceModel?.modelName ?? '',
|
||||
onUpdate: (tags, subspaces){
|
||||
print("here");
|
||||
onLoad?.call(tags, subspaces);}
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Chip(
|
||||
label: const Text(
|
||||
@ -130,11 +139,7 @@ class TagChipDisplay extends StatelessWidget {
|
||||
allTags: allTags,
|
||||
spaceName: spaceNameController.text,
|
||||
isCreate: true,
|
||||
onLoad: (tags, subspaces) {
|
||||
if (onLoad != null) {
|
||||
onLoad!(tags, subspaces);
|
||||
}
|
||||
},
|
||||
onLoad: (tags, subspaces) => onLoad?.call(tags, subspaces),
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -147,49 +152,4 @@ class TagChipDisplay extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Map<ProductModel, int> _groupTags(List<TagModel> tags) {
|
||||
final Map<ProductModel, int> groupedTags = {};
|
||||
for (var tag in tags) {
|
||||
if (tag.product != null) {
|
||||
groupedTags[tag.product!] = (groupedTags[tag.product!] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
return groupedTags;
|
||||
}
|
||||
|
||||
List<SelectedProduct> _createInitialSelectedProducts(
|
||||
List<TagModel>? tags, List<SubspaceTemplateModel>? subspaces) {
|
||||
final Map<ProductModel, int> productCounts = {};
|
||||
|
||||
if (tags != null) {
|
||||
for (var tag in tags) {
|
||||
if (tag.product != null) {
|
||||
productCounts[tag.product!] = (productCounts[tag.product!] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (subspaces != null) {
|
||||
for (var subspace in subspaces) {
|
||||
if (subspace.tags != null) {
|
||||
for (var tag in subspace.tags!) {
|
||||
if (tag.product != null) {
|
||||
productCounts[tag.product!] =
|
||||
(productCounts[tag.product!] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return productCounts.entries
|
||||
.map((entry) => SelectedProduct(
|
||||
productId: entry.key.uuid,
|
||||
count: entry.value,
|
||||
productName: entry.key.name ?? 'Unnamed',
|
||||
product: entry.key,
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user