mirror of
https://github.com/SyncrowIOT/web.git
synced 2026-10-23 10:37:57 +00:00
updated tag dialogue selection
This commit is contained in:
@@ -60,7 +60,7 @@ class SpaceManagementBloc extends Bloc<SpaceManagementEvent, SpaceManagementStat
|
||||
_cachedSpaceModels = await fetchSpaceModels();
|
||||
}
|
||||
|
||||
await fetchSpaceModels();
|
||||
await fetchTags();
|
||||
|
||||
emit(SpaceModelLoaded(
|
||||
communities:
|
||||
@@ -78,7 +78,7 @@ class SpaceManagementBloc extends Bloc<SpaceManagementEvent, SpaceManagementStat
|
||||
} else {
|
||||
_cachedSpaceModels = await fetchSpaceModels();
|
||||
}
|
||||
await fetchSpaceModels();
|
||||
await fetchTags();
|
||||
|
||||
emit(SpaceModelLoaded(
|
||||
communities:
|
||||
|
||||
@@ -25,7 +25,7 @@ class Tag extends BaseTag {
|
||||
return Tag(
|
||||
uuid: json['uuid'] ?? '',
|
||||
internalId: internalId,
|
||||
tag: json['tag'] ?? '',
|
||||
tag: json['name'] ?? '',
|
||||
product: json['product'] != null
|
||||
? ProductModel.fromMap(json['product'])
|
||||
: null,
|
||||
@@ -34,6 +34,7 @@ class Tag extends BaseTag {
|
||||
|
||||
@override
|
||||
Tag copyWith({
|
||||
String? uuid,
|
||||
String? tag,
|
||||
ProductModel? product,
|
||||
String? location,
|
||||
@@ -60,7 +61,7 @@ class Tag extends BaseTag {
|
||||
extension TagModelExtensions on Tag {
|
||||
TagBodyModel toTagBodyModel() {
|
||||
return TagBodyModel()
|
||||
..uuid = uuid ?? ''
|
||||
..uuid = uuid
|
||||
..tag = tag ?? ''
|
||||
..productUuid = product?.uuid;
|
||||
}
|
||||
|
||||
@@ -3,20 +3,17 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart';
|
||||
|
||||
class AssignTagModelBloc
|
||||
extends Bloc<AssignTagModelEvent, AssignTagModelState> {
|
||||
final List<String> allTags;
|
||||
class AssignTagModelBloc extends Bloc<AssignTagModelEvent, AssignTagModelState> {
|
||||
final List<Tag> projectTags;
|
||||
|
||||
AssignTagModelBloc(this.allTags, this.projectTags) : super(AssignTagModelInitial()) {
|
||||
AssignTagModelBloc(this.projectTags) : super(AssignTagModelInitial()) {
|
||||
on<InitializeTagModels>((event, emit) {
|
||||
final initialTags = event.initialTags ?? [];
|
||||
|
||||
final existingTagCounts = <String, int>{};
|
||||
for (var tag in initialTags) {
|
||||
if (tag.product != null) {
|
||||
existingTagCounts[tag.product!.uuid] =
|
||||
(existingTagCounts[tag.product!.uuid] ?? 0) + 1;
|
||||
existingTagCounts[tag.product!.uuid] = (existingTagCounts[tag.product!.uuid] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,17 +22,14 @@ class AssignTagModelBloc
|
||||
for (var selectedProduct in event.addedProducts) {
|
||||
final existingCount = existingTagCounts[selectedProduct.productId] ?? 0;
|
||||
|
||||
if (selectedProduct.count == 0 ||
|
||||
selectedProduct.count <= existingCount) {
|
||||
tags.addAll(initialTags
|
||||
.where((tag) => tag.product?.uuid == selectedProduct.productId));
|
||||
if (selectedProduct.count == 0 || selectedProduct.count <= existingCount) {
|
||||
tags.addAll(initialTags.where((tag) => tag.product?.uuid == selectedProduct.productId));
|
||||
continue;
|
||||
}
|
||||
|
||||
final missingCount = selectedProduct.count - existingCount;
|
||||
|
||||
tags.addAll(initialTags
|
||||
.where((tag) => tag.product?.uuid == selectedProduct.productId));
|
||||
tags.addAll(initialTags.where((tag) => tag.product?.uuid == selectedProduct.productId));
|
||||
|
||||
if (missingCount > 0) {
|
||||
tags.addAll(List.generate(
|
||||
@@ -49,7 +43,7 @@ class AssignTagModelBloc
|
||||
}
|
||||
}
|
||||
|
||||
final updatedTags = _calculateAvailableTags(allTags, tags);
|
||||
final updatedTags = _calculateAvailableTags(projectTags, tags);
|
||||
|
||||
emit(AssignTagModelLoaded(
|
||||
tags: tags,
|
||||
@@ -60,11 +54,20 @@ class AssignTagModelBloc
|
||||
|
||||
on<UpdateTag>((event, emit) {
|
||||
final currentState = state;
|
||||
if (currentState is AssignTagModelLoaded &&
|
||||
currentState.tags.isNotEmpty) {
|
||||
if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) {
|
||||
final tags = List<Tag>.from(currentState.tags);
|
||||
tags[event.index] = tags[event.index].copyWith(tag: event.tag);
|
||||
final updatedTags = _calculateAvailableTags(allTags, tags);
|
||||
|
||||
if (event.index < 0 || event.index >= tags.length) return;
|
||||
|
||||
tags[event.index] = tags[event.index].copyWith(
|
||||
tag: event.tag.tag,
|
||||
uuid: event.tag.uuid,
|
||||
product: event.tag.product,
|
||||
internalId: event.tag.internalId,
|
||||
location: event.tag.location,
|
||||
);
|
||||
|
||||
final updatedTags = _calculateAvailableTags(projectTags ?? [], tags);
|
||||
|
||||
emit(AssignTagModelLoaded(
|
||||
tags: tags,
|
||||
@@ -78,15 +81,13 @@ class AssignTagModelBloc
|
||||
on<UpdateLocation>((event, emit) {
|
||||
final currentState = state;
|
||||
|
||||
if (currentState is AssignTagModelLoaded &&
|
||||
currentState.tags.isNotEmpty) {
|
||||
if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) {
|
||||
final tags = List<Tag>.from(currentState.tags);
|
||||
|
||||
// Use copyWith for immutability
|
||||
tags[event.index] =
|
||||
tags[event.index].copyWith(location: event.location);
|
||||
tags[event.index] = tags[event.index].copyWith(location: event.location);
|
||||
|
||||
final updatedTags = _calculateAvailableTags(allTags, tags);
|
||||
final updatedTags = _calculateAvailableTags(projectTags, tags);
|
||||
|
||||
emit(AssignTagModelLoaded(
|
||||
tags: tags,
|
||||
@@ -100,13 +101,12 @@ class AssignTagModelBloc
|
||||
on<ValidateTagModels>((event, emit) {
|
||||
final currentState = state;
|
||||
|
||||
if (currentState is AssignTagModelLoaded &&
|
||||
currentState.tags.isNotEmpty) {
|
||||
if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) {
|
||||
final tags = List<Tag>.from(currentState.tags);
|
||||
|
||||
emit(AssignTagModelLoaded(
|
||||
tags: tags,
|
||||
updatedTags: _calculateAvailableTags(allTags, tags),
|
||||
updatedTags: _calculateAvailableTags(projectTags, tags),
|
||||
isSaveEnabled: _validateTags(tags),
|
||||
errorMessage: _getValidationError(tags),
|
||||
));
|
||||
@@ -116,12 +116,10 @@ class AssignTagModelBloc
|
||||
on<DeleteTagModel>((event, emit) {
|
||||
final currentState = state;
|
||||
|
||||
if (currentState is AssignTagModelLoaded &&
|
||||
currentState.tags.isNotEmpty) {
|
||||
final tags = List<Tag>.from(currentState.tags)
|
||||
..remove(event.tagToDelete);
|
||||
if (currentState is AssignTagModelLoaded && currentState.tags.isNotEmpty) {
|
||||
final tags = List<Tag>.from(currentState.tags)..remove(event.tagToDelete);
|
||||
|
||||
final updatedTags = _calculateAvailableTags(allTags, tags);
|
||||
final updatedTags = _calculateAvailableTags(projectTags, tags);
|
||||
|
||||
emit(AssignTagModelLoaded(
|
||||
tags: tags,
|
||||
@@ -143,10 +141,8 @@ class AssignTagModelBloc
|
||||
String? _getValidationError(List<Tag> tags) {
|
||||
// Check for duplicate tags
|
||||
|
||||
final nonEmptyTags = tags
|
||||
.map((tag) => tag.tag?.trim() ?? '')
|
||||
.where((tag) => tag.isNotEmpty)
|
||||
.toList();
|
||||
final nonEmptyTags =
|
||||
tags.map((tag) => tag.tag?.trim() ?? '').where((tag) => tag.isNotEmpty).toList();
|
||||
|
||||
final duplicateTags = nonEmptyTags
|
||||
.fold<Map<String, int>>({}, (map, tag) {
|
||||
@@ -165,15 +161,16 @@ class AssignTagModelBloc
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> _calculateAvailableTags(
|
||||
List<String> allTags, List<Tag> tags) {
|
||||
final selectedTags = tags
|
||||
List<Tag> _calculateAvailableTags(List<Tag> allTags, List<Tag> selectedTags) {
|
||||
final selectedTagSet = selectedTags
|
||||
.where((tag) => (tag.tag?.trim().isNotEmpty ?? false))
|
||||
.map((tag) => tag.tag!.trim())
|
||||
.toSet();
|
||||
|
||||
final availableTags =
|
||||
allTags.where((tag) => !selectedTags.contains(tag.trim())).toList();
|
||||
final availableTags = allTags
|
||||
.where((tag) => tag.tag != null && !selectedTagSet.contains(tag.tag!.trim()))
|
||||
.toList();
|
||||
|
||||
return availableTags;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class InitializeTagModels extends AssignTagModelEvent {
|
||||
|
||||
class UpdateTag extends AssignTagModelEvent {
|
||||
final int index;
|
||||
final String tag;
|
||||
final Tag tag;
|
||||
|
||||
const UpdateTag({required this.index, required this.tag});
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class AssignTagModelLoaded extends AssignTagModelState {
|
||||
final bool isSaveEnabled;
|
||||
final String? errorMessage;
|
||||
|
||||
final List<String> updatedTags;
|
||||
final List<Tag> updatedTags;
|
||||
|
||||
const AssignTagModelLoaded({
|
||||
required this.tags,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/common/dialog_dropdown.dart';
|
||||
import 'package:syncrow_web/common/dialog_textfield_dropdown.dart';
|
||||
import 'package:syncrow_web/common/tag_dialog_textfield_dropdown.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
||||
@@ -53,12 +53,11 @@ class AssignTagModelsDialog extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print(projectTags);
|
||||
final List<String> locations =
|
||||
(subspaces ?? []).map((subspace) => subspace.subspaceName).toList()..add('Main Space');
|
||||
|
||||
return BlocProvider(
|
||||
create: (_) => AssignTagModelBloc(allTags ?? [], projectTags)
|
||||
create: (_) => AssignTagModelBloc( projectTags)
|
||||
..add(InitializeTagModels(
|
||||
initialTags: initialTags,
|
||||
addedProducts: addedProducts,
|
||||
@@ -174,12 +173,14 @@ class AssignTagModelsDialog extends StatelessWidget {
|
||||
child: SizedBox(
|
||||
width:
|
||||
double.infinity, // Ensure full width for dropdown
|
||||
child: DialogTextfieldDropdown(
|
||||
key: ValueKey('dropdown_${Uuid().v4()}_$index'),
|
||||
child: TagDialogTextfieldDropdown(
|
||||
key: ValueKey(
|
||||
'dropdown_${const Uuid().v4()}_$index'),
|
||||
product: tag.product?.uuid ?? 'Unknown',
|
||||
items: state.updatedTags,
|
||||
initialValue: tag.tag,
|
||||
initialValue: tag,
|
||||
onSelected: (value) {
|
||||
controller.text = value;
|
||||
controller.text = value.tag ?? '';
|
||||
context.read<AssignTagModelBloc>().add(UpdateTag(
|
||||
index: index,
|
||||
tag: value,
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ class TagBodyModel {
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'uuid': uuid,
|
||||
'tag': tag,
|
||||
'name': tag,
|
||||
'productUuid': productUuid,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user