mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
added initial flow
This commit is contained in:
@ -9,10 +9,8 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_pr
|
|||||||
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.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_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.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/subspace_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class AssignTagModelsDialog extends StatelessWidget {
|
class AssignTagModelsDialog extends StatelessWidget {
|
||||||
@ -24,6 +22,8 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
final List<String>? allTags;
|
final List<String>? allTags;
|
||||||
final String spaceName;
|
final String spaceName;
|
||||||
final String title;
|
final String title;
|
||||||
|
final void Function(
|
||||||
|
List<TagModel>? tags, List<SubspaceTemplateModel>? subspaces)? onUpdate;
|
||||||
|
|
||||||
const AssignTagModelsDialog(
|
const AssignTagModelsDialog(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
@ -34,7 +34,8 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
this.onTagsAssigned,
|
this.onTagsAssigned,
|
||||||
this.allTags,
|
this.allTags,
|
||||||
required this.spaceName,
|
required this.spaceName,
|
||||||
required this.title})
|
required this.title,
|
||||||
|
this.onUpdate})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -226,6 +227,21 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
label: 'Add New Device',
|
label: 'Add New Device',
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
final assignedTags = <TagModel>{};
|
||||||
|
for (var tag in state.tags) {
|
||||||
|
if (tag.location == null || subspaces == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (var subspace in subspaces!) {
|
||||||
|
if (tag.location == subspace.subspaceName) {
|
||||||
|
subspace.tags ??= [];
|
||||||
|
subspace.tags!.add(tag);
|
||||||
|
assignedTags.add(tag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.tags.removeWhere(assignedTags.contains);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -256,18 +272,7 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.tags.removeWhere(assignedTags.contains);
|
state.tags.removeWhere(assignedTags.contains);
|
||||||
await showDialog(
|
onUpdate!(state.tags,subspaces);
|
||||||
barrierDismissible: false,
|
|
||||||
context: context,
|
|
||||||
builder: (context) => CreateSpaceModelDialog(
|
|
||||||
products: products,
|
|
||||||
allTags: allTags,
|
|
||||||
spaceModel: SpaceTemplateModel(
|
|
||||||
modelName: spaceName,
|
|
||||||
subspaceModels: subspaces,
|
|
||||||
tags: state.tags),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: const Text('Save'),
|
child: const Text('Save'),
|
||||||
|
@ -84,6 +84,24 @@ class CreateSpaceModelBloc
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on<AddTagsToSpaceTemplate>((event, emit) {
|
||||||
|
final currentState = state;
|
||||||
|
|
||||||
|
if (currentState is CreateSpaceModelLoaded) {
|
||||||
|
final updatedTags = currentState.space.copyWith(
|
||||||
|
tags: [
|
||||||
|
...(_space!.tags ?? []),
|
||||||
|
...event.tags,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
emit(CreateSpaceModelLoaded(updatedTags));
|
||||||
|
} else {
|
||||||
|
emit(CreateSpaceModelError("Space template not initialized"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
on<UpdateSpaceTemplateName>((event, emit) {
|
on<UpdateSpaceTemplateName>((event, emit) {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
if (currentState is CreateSpaceModelLoaded) {
|
if (currentState is CreateSpaceModelLoaded) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.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/subspace_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';
|
||||||
|
|
||||||
abstract class CreateSpaceModelEvent extends Equatable {
|
abstract class CreateSpaceModelEvent extends Equatable {
|
||||||
const CreateSpaceModelEvent();
|
const CreateSpaceModelEvent();
|
||||||
@ -46,6 +47,13 @@ class AddSubspacesToSpaceTemplate extends CreateSpaceModelEvent {
|
|||||||
AddSubspacesToSpaceTemplate(this.subspaces);
|
AddSubspacesToSpaceTemplate(this.subspaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AddTagsToSpaceTemplate extends CreateSpaceModelEvent {
|
||||||
|
final List<TagModel> tags;
|
||||||
|
|
||||||
|
AddTagsToSpaceTemplate(this.tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ValidateSpaceTemplateName extends CreateSpaceModelEvent {
|
class ValidateSpaceTemplateName extends CreateSpaceModelEvent {
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ class SpaceTemplateModel extends Equatable {
|
|||||||
String internalId;
|
String internalId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [modelName, subspaceModels];
|
List<Object?> get props => [modelName, subspaceModels, tags];
|
||||||
|
|
||||||
SpaceTemplateModel({
|
SpaceTemplateModel({
|
||||||
this.uuid,
|
this.uuid,
|
||||||
|
@ -118,13 +118,28 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
TagChipDisplay(context,
|
TagChipDisplay(
|
||||||
screenWidth: screenWidth,
|
context,
|
||||||
spaceModel: updatedSpaceModel,
|
screenWidth: screenWidth,
|
||||||
products: products,
|
spaceModel: updatedSpaceModel,
|
||||||
subspaces: subspaces,
|
products: products,
|
||||||
allTags: allTags,
|
subspaces: subspaces,
|
||||||
spaceNameController: spaceNameController),
|
allTags: allTags,
|
||||||
|
spaceNameController: spaceNameController,
|
||||||
|
onLoad: (tags, subspaces) {
|
||||||
|
if(subspaces!=null){
|
||||||
|
context
|
||||||
|
.read<CreateSpaceModelBloc>()
|
||||||
|
.add(AddSubspacesToSpaceTemplate(subspaces));
|
||||||
|
}
|
||||||
|
if(tags!=null){
|
||||||
|
context
|
||||||
|
.read<CreateSpaceModelBloc>()
|
||||||
|
.add(AddTagsToSpaceTemplate(tags));
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: screenWidth * 0.25,
|
width: screenWidth * 0.25,
|
||||||
|
@ -16,17 +16,19 @@ class TagChipDisplay extends StatelessWidget {
|
|||||||
final List<SubspaceTemplateModel>? subspaces;
|
final List<SubspaceTemplateModel>? subspaces;
|
||||||
final List<String>? allTags;
|
final List<String>? allTags;
|
||||||
final TextEditingController spaceNameController;
|
final TextEditingController spaceNameController;
|
||||||
|
final void Function(
|
||||||
|
List<TagModel>? tags, List<SubspaceTemplateModel>? subspaces)? onLoad;
|
||||||
|
|
||||||
const TagChipDisplay(
|
const TagChipDisplay(BuildContext context,
|
||||||
BuildContext context, {
|
{Key? key,
|
||||||
Key? key,
|
required this.screenWidth,
|
||||||
required this.screenWidth,
|
required this.spaceModel,
|
||||||
required this.spaceModel,
|
required this.products,
|
||||||
required this.products,
|
required this.subspaces,
|
||||||
required this.subspaces,
|
required this.allTags,
|
||||||
required this.allTags,
|
required this.spaceNameController,
|
||||||
required this.spaceNameController,
|
this.onLoad})
|
||||||
}) : super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -104,15 +106,12 @@ class TagChipDisplay extends StatelessWidget {
|
|||||||
child: Chip(
|
child: Chip(
|
||||||
label: const Text(
|
label: const Text(
|
||||||
'Edit',
|
'Edit',
|
||||||
style: TextStyle(
|
style: TextStyle(color: ColorsManager.spaceColor),
|
||||||
color: ColorsManager.spaceColor),
|
|
||||||
),
|
),
|
||||||
backgroundColor:
|
backgroundColor: ColorsManager.whiteColors,
|
||||||
ColorsManager.whiteColors,
|
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
side: const BorderSide(
|
side: const BorderSide(color: ColorsManager.spaceColor),
|
||||||
color: ColorsManager.spaceColor),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -122,7 +121,7 @@ class TagChipDisplay extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
: TextButton(
|
: TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final result = await showDialog<bool>(
|
await showDialog<bool>(
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AddDeviceTypeModelWidget(
|
builder: (context) => AddDeviceTypeModelWidget(
|
||||||
@ -131,9 +130,13 @@ class TagChipDisplay extends StatelessWidget {
|
|||||||
allTags: allTags,
|
allTags: allTags,
|
||||||
spaceName: spaceNameController.text,
|
spaceName: spaceNameController.text,
|
||||||
isCreate: true,
|
isCreate: true,
|
||||||
|
onLoad: (tags, subspaces) {
|
||||||
|
if (onLoad != null) {
|
||||||
|
onLoad!(tags, subspaces);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (result == true) {}
|
|
||||||
},
|
},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
@ -189,5 +192,4 @@ class TagChipDisplay extends StatelessWidget {
|
|||||||
))
|
))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/common/buttons/cancel_button.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/assign_tag_models/views/assign_tag_models_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.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/all_spaces/model/selected_product_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/subspace_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_model_state.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/tag_model/bloc/add_device_type_model_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/action_button_widget.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/tag_model/widgets/scrollable_grid_view_widget.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
@ -23,6 +21,8 @@ class AddDeviceTypeModelWidget extends StatelessWidget {
|
|||||||
final List<String>? allTags;
|
final List<String>? allTags;
|
||||||
final String spaceName;
|
final String spaceName;
|
||||||
final bool isCreate;
|
final bool isCreate;
|
||||||
|
final void Function(
|
||||||
|
List<TagModel>? tags, List<SubspaceTemplateModel>? subspaces)? onLoad;
|
||||||
|
|
||||||
const AddDeviceTypeModelWidget({
|
const AddDeviceTypeModelWidget({
|
||||||
super.key,
|
super.key,
|
||||||
@ -33,6 +33,7 @@ class AddDeviceTypeModelWidget extends StatelessWidget {
|
|||||||
this.spaceTagModels,
|
this.spaceTagModels,
|
||||||
required this.spaceName,
|
required this.spaceName,
|
||||||
required this.isCreate,
|
required this.isCreate,
|
||||||
|
this.onLoad,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -94,46 +95,66 @@ class AddDeviceTypeModelWidget extends StatelessWidget {
|
|||||||
CancelButton(
|
CancelButton(
|
||||||
label: 'Cancel',
|
label: 'Cancel',
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (isCreate) {
|
if (isCreate) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ActionButton(
|
|
||||||
label: 'Continue',
|
|
||||||
backgroundColor: ColorsManager.secondaryColor,
|
|
||||||
foregroundColor: ColorsManager.whiteColors,
|
|
||||||
onPressed: () async {
|
|
||||||
final state = context.read<AddDeviceTypeModelBloc>().state;
|
|
||||||
if (state is AddDeviceModelLoaded &&
|
|
||||||
state.selectedProducts.isNotEmpty) {
|
|
||||||
final initialTags = generateInitialTags(
|
|
||||||
spaceTagModels: spaceTagModels,
|
|
||||||
subspaces: subspaces,
|
|
||||||
);
|
|
||||||
if (isCreate) {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
final dialogTitle = initialTags.isNotEmpty
|
|
||||||
? 'Edit Device'
|
|
||||||
: 'Assign Tags';
|
|
||||||
await showDialog<bool>(
|
|
||||||
barrierDismissible: false,
|
|
||||||
context: context,
|
|
||||||
builder: (context) => AssignTagModelsDialog(
|
|
||||||
products: products,
|
|
||||||
subspaces: subspaces,
|
|
||||||
addedProducts: state.selectedProducts,
|
|
||||||
allTags: allTags,
|
|
||||||
spaceName: spaceName,
|
|
||||||
initialTags: state.initialTag,
|
|
||||||
title: dialogTitle,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 140,
|
||||||
|
child:
|
||||||
|
BlocBuilder<AddDeviceTypeModelBloc, AddDeviceModelState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
final isDisabled = state is AddDeviceModelLoaded &&
|
||||||
|
state.selectedProducts.isEmpty;
|
||||||
|
|
||||||
|
return DefaultButton(
|
||||||
|
backgroundColor: ColorsManager.secondaryColor,
|
||||||
|
foregroundColor: isDisabled
|
||||||
|
? ColorsManager.whiteColorsWithOpacity
|
||||||
|
: ColorsManager.whiteColors,
|
||||||
|
borderRadius: 10,
|
||||||
|
onPressed: isDisabled
|
||||||
|
? null // Disable the button
|
||||||
|
: () async {
|
||||||
|
if (state is AddDeviceModelLoaded &&
|
||||||
|
state.selectedProducts.isNotEmpty) {
|
||||||
|
final initialTags = generateInitialTags(
|
||||||
|
spaceTagModels: spaceTagModels,
|
||||||
|
subspaces: subspaces,
|
||||||
|
);
|
||||||
|
if (isCreate) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
final dialogTitle = initialTags.isNotEmpty
|
||||||
|
? 'Edit Device'
|
||||||
|
: 'Assign Tags';
|
||||||
|
await showDialog<bool>(
|
||||||
|
barrierDismissible: false,
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AssignTagModelsDialog(
|
||||||
|
products: products,
|
||||||
|
subspaces: subspaces,
|
||||||
|
addedProducts: state.selectedProducts,
|
||||||
|
allTags: allTags,
|
||||||
|
spaceName: spaceName,
|
||||||
|
initialTags: state.initialTag,
|
||||||
|
title: dialogTitle,
|
||||||
|
onUpdate: (tags, subspaces) {
|
||||||
|
if (onLoad != null) {
|
||||||
|
onLoad!(tags, subspaces);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Next'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user