mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
subspace model
This commit is contained in:
@ -1,2 +1,2 @@
|
|||||||
ENV_NAME=development
|
ENV_NAME=development
|
||||||
BASE_URL=https://syncrow-dev.azurewebsites.net
|
BASE_URL=http://localhost:4001
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -41,3 +41,6 @@ app.*.map.json
|
|||||||
/android/app/debug
|
/android/app/debug
|
||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
lib/utils/constants/temp_const.dart
|
||||||
|
.env.development
|
||||||
|
lib/utils/constants/temp_const.dart
|
||||||
|
@ -329,6 +329,7 @@ class SpaceManagementBloc
|
|||||||
Emitter<SpaceManagementState> emit,
|
Emitter<SpaceManagementState> emit,
|
||||||
) {
|
) {
|
||||||
final communities = List<CommunityModel>.from(previousState.communities);
|
final communities = List<CommunityModel>.from(previousState.communities);
|
||||||
|
|
||||||
|
|
||||||
for (var community in communities) {
|
for (var community in communities) {
|
||||||
if (community.uuid == communityUuid) {
|
if (community.uuid == communityUuid) {
|
||||||
@ -425,7 +426,7 @@ class SpaceManagementBloc
|
|||||||
emit(SpaceManagementLoading());
|
emit(SpaceManagementLoading());
|
||||||
try {
|
try {
|
||||||
List<CommunityModel> communities = await _api.fetchCommunities();
|
List<CommunityModel> communities = await _api.fetchCommunities();
|
||||||
|
|
||||||
List<CommunityModel> updatedCommunities = await Future.wait(
|
List<CommunityModel> updatedCommunities = await Future.wait(
|
||||||
communities.map((community) async {
|
communities.map((community) async {
|
||||||
List<SpaceModel> spaces =
|
List<SpaceModel> spaces =
|
||||||
|
@ -48,7 +48,8 @@ class _LoadedStateViewState extends State<LoadedSpaceView> {
|
|||||||
hasSpaceModels
|
hasSpaceModels
|
||||||
? Expanded(
|
? Expanded(
|
||||||
child: SpaceModelPage(
|
child: SpaceModelPage(
|
||||||
spaceModels: widget.spaceModels ??[],
|
spaceModels: widget.spaceModels ?? [],
|
||||||
|
products: widget.products,
|
||||||
))
|
))
|
||||||
: CommunityStructureArea(
|
: CommunityStructureArea(
|
||||||
selectedCommunity: widget.selectedCommunity,
|
selectedCommunity: widget.selectedCommunity,
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_event.dart';
|
||||||
|
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/space_template_model.dart';
|
||||||
|
|
||||||
|
class CreateSpaceModelBloc extends Bloc<CreateSpaceModelEvent, CreateSpaceModelState> {
|
||||||
|
SpaceTemplateModel? _space;
|
||||||
|
|
||||||
|
CreateSpaceModelBloc() : super(CreateSpaceModelInitial()) {
|
||||||
|
on<LoadSpaceTemplate>((event, emit) {
|
||||||
|
emit(CreateSpaceModelLoading());
|
||||||
|
Future.delayed(const Duration(seconds: 1), () {
|
||||||
|
if (_space != null) {
|
||||||
|
emit(CreateSpaceModelLoaded(_space!));
|
||||||
|
} else {
|
||||||
|
emit(CreateSpaceModelError("No space template found"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
on<UpdateSpaceTemplate>((event, emit) {
|
||||||
|
_space = event.spaceTemplate;
|
||||||
|
emit(CreateSpaceModelLoaded(_space!));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
|
|
||||||
|
abstract class CreateSpaceModelEvent {}
|
||||||
|
|
||||||
|
class LoadSpaceTemplate extends CreateSpaceModelEvent {}
|
||||||
|
|
||||||
|
class UpdateSpaceTemplate extends CreateSpaceModelEvent {
|
||||||
|
final SpaceTemplateModel spaceTemplate;
|
||||||
|
|
||||||
|
UpdateSpaceTemplate(this.spaceTemplate);
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
|
|
||||||
|
abstract class CreateSpaceModelState {}
|
||||||
|
|
||||||
|
class CreateSpaceModelInitial extends CreateSpaceModelState {}
|
||||||
|
|
||||||
|
class CreateSpaceModelLoading extends CreateSpaceModelState {}
|
||||||
|
|
||||||
|
class CreateSpaceModelLoaded extends CreateSpaceModelState {
|
||||||
|
final SpaceTemplateModel space;
|
||||||
|
|
||||||
|
CreateSpaceModelLoaded(this.space);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreateSpaceModelError extends CreateSpaceModelState {
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
CreateSpaceModelError(this.message);
|
||||||
|
}
|
@ -1,38 +1,34 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/subspace_model_event.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/subspace_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/space_template_model.dart';
|
||||||
|
import 'package:syncrow_web/utils/constants/action_enum.dart';
|
||||||
// Events
|
|
||||||
abstract class SubSpaceModelEvent {}
|
|
||||||
|
|
||||||
class AddSubSpaceModel extends SubSpaceModelEvent {
|
|
||||||
final SubspaceTemplateModel subSpace;
|
|
||||||
AddSubSpaceModel(this.subSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
class RemoveSubSpaceModel extends SubSpaceModelEvent {
|
|
||||||
final SubspaceTemplateModel subSpace;
|
|
||||||
RemoveSubSpaceModel(this.subSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
// State
|
|
||||||
class SubSpaceModelState {
|
|
||||||
final List<SubspaceTemplateModel> subSpaces;
|
|
||||||
SubSpaceModelState(this.subSpaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
// BLoC
|
// BLoC
|
||||||
class SubSpaceModelBloc extends Bloc<SubSpaceModelEvent, SubSpaceModelState> {
|
class SubSpaceModelBloc extends Bloc<SubSpaceModelEvent, SubSpaceModelState> {
|
||||||
SubSpaceModelBloc() : super(SubSpaceModelState([])) {
|
SubSpaceModelBloc() : super(SubSpaceModelState([], [])) {
|
||||||
on<AddSubSpaceModel>((event, emit) {
|
on<AddSubSpaceModel>((event, emit) {
|
||||||
final updatedSubSpaces = List<SubspaceTemplateModel>.from(state.subSpaces)
|
final updatedSubSpaces = List<SubspaceTemplateModel>.from(state.subSpaces)
|
||||||
..add(event.subSpace);
|
..add(event.subSpace);
|
||||||
emit(SubSpaceModelState(updatedSubSpaces));
|
emit(SubSpaceModelState(updatedSubSpaces, []));
|
||||||
});
|
});
|
||||||
|
|
||||||
on<RemoveSubSpaceModel>((event, emit) {
|
on<RemoveSubSpaceModel>((event, emit) {
|
||||||
final updatedSubSpaces = List<SubspaceTemplateModel>.from(state.subSpaces)
|
final updatedSubSpaces = List<SubspaceTemplateModel>.from(state.subSpaces)
|
||||||
..remove(event.subSpace);
|
..remove(event.subSpace);
|
||||||
emit(SubSpaceModelState(updatedSubSpaces));
|
|
||||||
|
final updatedSubspaceModels = List<UpdateSubspaceTemplateModel>.from(
|
||||||
|
state.updatedSubSpaceModels,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event.subSpace.uuid?.isNotEmpty ?? false) {
|
||||||
|
updatedSubspaceModels.add(UpdateSubspaceTemplateModel(
|
||||||
|
action: Action.delete,
|
||||||
|
uuid: event.subSpace.uuid!,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(SubSpaceModelState(updatedSubSpaces, updatedSubspaceModels));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
// Events
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
|
|
||||||
|
abstract class SubSpaceModelEvent {}
|
||||||
|
|
||||||
|
class AddSubSpaceModel extends SubSpaceModelEvent {
|
||||||
|
final SubspaceTemplateModel subSpace;
|
||||||
|
AddSubSpaceModel(this.subSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RemoveSubSpaceModel extends SubSpaceModelEvent {
|
||||||
|
final SubspaceTemplateModel subSpace;
|
||||||
|
RemoveSubSpaceModel(this.subSpace);
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
|
|
||||||
|
class SubSpaceModelState {
|
||||||
|
final List<SubspaceTemplateModel> subSpaces;
|
||||||
|
final List<UpdateSubspaceTemplateModel> updatedSubSpaceModels;
|
||||||
|
|
||||||
|
SubSpaceModelState(
|
||||||
|
this.subSpaces,
|
||||||
|
this.updatedSubSpaceModels,
|
||||||
|
);
|
||||||
|
}
|
@ -1,25 +1,20 @@
|
|||||||
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/utils/constants/action_enum.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class SpaceTemplateModel {
|
class SpaceTemplateModel {
|
||||||
final String uuid;
|
final String? uuid;
|
||||||
final DateTime createdAt;
|
|
||||||
final DateTime updatedAt;
|
|
||||||
final String modelName;
|
final String modelName;
|
||||||
final bool disabled;
|
final List<SubspaceTemplateModel>? subspaceModels;
|
||||||
final List<SubspaceTemplateModel> subspaceModels;
|
final List<TagModel>? tags;
|
||||||
final List<TagModel> tags;
|
|
||||||
String internalId;
|
String internalId;
|
||||||
|
|
||||||
SpaceTemplateModel({
|
SpaceTemplateModel({
|
||||||
required this.uuid,
|
this.uuid,
|
||||||
String? internalId,
|
String? internalId,
|
||||||
required this.createdAt,
|
|
||||||
required this.updatedAt,
|
|
||||||
required this.modelName,
|
required this.modelName,
|
||||||
required this.disabled,
|
this.subspaceModels,
|
||||||
required this.subspaceModels,
|
this.tags,
|
||||||
required this.tags,
|
|
||||||
}) : internalId = internalId ?? const Uuid().v4();
|
}) : internalId = internalId ?? const Uuid().v4();
|
||||||
|
|
||||||
factory SpaceTemplateModel.fromJson(Map<String, dynamic> json) {
|
factory SpaceTemplateModel.fromJson(Map<String, dynamic> json) {
|
||||||
@ -28,28 +23,22 @@ class SpaceTemplateModel {
|
|||||||
return SpaceTemplateModel(
|
return SpaceTemplateModel(
|
||||||
uuid: json['uuid'] ?? '',
|
uuid: json['uuid'] ?? '',
|
||||||
internalId: internalId,
|
internalId: internalId,
|
||||||
createdAt: DateTime.parse(json['createdAt']),
|
|
||||||
updatedAt: DateTime.parse(json['updatedAt']),
|
|
||||||
modelName: json['modelName'] ?? '',
|
modelName: json['modelName'] ?? '',
|
||||||
disabled: json['disabled'] ?? false,
|
|
||||||
subspaceModels: (json['subspaceModels'] as List)
|
subspaceModels: (json['subspaceModels'] as List)
|
||||||
.map((item) => SubspaceTemplateModel.fromJson(item))
|
.map((item) => SubspaceTemplateModel.fromJson(item))
|
||||||
.toList(),
|
.toList(),
|
||||||
tags: (json['tags'] as List)
|
tags: (json['tags'] as List)
|
||||||
.map((item) => TagModel.fromJson(item))
|
.map((item) => TagModel.fromJson(item))
|
||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'uuid': uuid,
|
'uuid': uuid,
|
||||||
'createdAt': createdAt.toIso8601String(),
|
|
||||||
'updatedAt': updatedAt.toIso8601String(),
|
|
||||||
'modelName': modelName,
|
'modelName': modelName,
|
||||||
'disabled': disabled,
|
'subspaceModels': subspaceModels?.map((e) => e.toJson()).toList(),
|
||||||
'subspaceModels': subspaceModels.map((e) => e.toJson()).toList(),
|
'tags': tags?.map((e) => e.toJson()).toList(),
|
||||||
'tags': tags.map((e) => e.toJson()).toList(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,3 +118,75 @@ class TagModel {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class UpdateSubspaceTemplateModel {
|
||||||
|
final String uuid;
|
||||||
|
final Action action;
|
||||||
|
final String? subspaceName;
|
||||||
|
final List<UpdateTagModel>? tags;
|
||||||
|
|
||||||
|
UpdateSubspaceTemplateModel({
|
||||||
|
required this.action,
|
||||||
|
required this.uuid,
|
||||||
|
this.subspaceName,
|
||||||
|
this.tags,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory UpdateSubspaceTemplateModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return UpdateSubspaceTemplateModel(
|
||||||
|
action: ActionExtension.fromValue(json['action']),
|
||||||
|
uuid: json['uuid'] ?? '',
|
||||||
|
subspaceName: json['subspaceName'] ?? '',
|
||||||
|
tags: (json['tags'] as List)
|
||||||
|
.map((item) => UpdateTagModel.fromJson(item))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'action': action.value,
|
||||||
|
'uuid': uuid,
|
||||||
|
'subspaceName': subspaceName,
|
||||||
|
'tags': tags?.map((e) => e.toJson()).toList() ?? [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpdateTagModel {
|
||||||
|
final Action action;
|
||||||
|
final String? uuid;
|
||||||
|
final String tag;
|
||||||
|
final bool disabled;
|
||||||
|
final ProductModel? product;
|
||||||
|
|
||||||
|
UpdateTagModel({
|
||||||
|
required this.action,
|
||||||
|
this.uuid,
|
||||||
|
required this.tag,
|
||||||
|
required this.disabled,
|
||||||
|
this.product,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory UpdateTagModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return UpdateTagModel(
|
||||||
|
action: ActionExtension.fromValue(json['action']),
|
||||||
|
uuid: json['uuid'] ?? '',
|
||||||
|
tag: json['tag'] ?? '',
|
||||||
|
disabled: json['disabled'] ?? false,
|
||||||
|
product: json['product'] != null
|
||||||
|
? ProductModel.fromMap(json['product'])
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'action': action.value,
|
||||||
|
'uuid': uuid,
|
||||||
|
'tag': tag,
|
||||||
|
'disabled': disabled,
|
||||||
|
'product': product?.toMap(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/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/space_template_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/space_model/widgets/dialog/create_space_model_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/space_model_card_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/space_model_card_widget.dart';
|
||||||
@ -6,8 +7,10 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
|
|
||||||
class SpaceModelPage extends StatelessWidget {
|
class SpaceModelPage extends StatelessWidget {
|
||||||
final List<SpaceTemplateModel> spaceModels;
|
final List<SpaceTemplateModel> spaceModels;
|
||||||
|
final List<ProductModel>? products;
|
||||||
|
|
||||||
const SpaceModelPage({Key? key, required this.spaceModels}) : super(key: key);
|
const SpaceModelPage({Key? key, required this.spaceModels, this.products})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -33,7 +36,7 @@ class SpaceModelPage extends StatelessWidget {
|
|||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return const CreateSpaceModelDialog();
|
return CreateSpaceModelDialog(products: products);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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/common/buttons/default_button.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/add_device_type_widget.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_subspace_model_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_subspace_model_dialog.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class CreateSpaceModelDialog extends StatelessWidget {
|
class CreateSpaceModelDialog extends StatelessWidget {
|
||||||
const CreateSpaceModelDialog({Key? key}) : super(key: key);
|
final List<ProductModel>? products;
|
||||||
|
|
||||||
|
const CreateSpaceModelDialog({Key? key, this.products}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -50,94 +53,54 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
GestureDetector(
|
TextButton(
|
||||||
onTap: () async {
|
onPressed: () async {
|
||||||
final result = await showDialog(
|
final result = await showDialog<String>(
|
||||||
|
barrierDismissible: false,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return CreateSubSpaceModelDialog(
|
return const CreateSubSpaceModelDialog(
|
||||||
isEdit: true,
|
isEdit: true,
|
||||||
dialogTitle: 'Create Sub-space',
|
dialogTitle: 'Create Sub-space',
|
||||||
existingSubSpaces: [
|
|
||||||
SubspaceTemplateModel(
|
|
||||||
subspaceName: "Living Room",
|
|
||||||
disabled: false,
|
|
||||||
uuid: "mkmkl,",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (result == true) {}
|
if (result != null && result.isNotEmpty) {
|
||||||
|
// Handle the result if necessary
|
||||||
|
print('Subspace created: $result');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
style: TextButton.styleFrom(
|
||||||
width: screenWidth * 0.25,
|
padding: EdgeInsets.zero,
|
||||||
child: Container(
|
),
|
||||||
decoration: BoxDecoration(
|
child: _buildButtonContent(
|
||||||
color: ColorsManager.textFieldGreyColor,
|
context,
|
||||||
border: Border.all(
|
icon: Icons.add,
|
||||||
color: ColorsManager.neutralGray,
|
label: 'Create Sub Space',
|
||||||
width: 3.0,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
child: const Padding(
|
|
||||||
padding:
|
|
||||||
EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.add,
|
|
||||||
color: ColorsManager.spaceColor,
|
|
||||||
),
|
|
||||||
SizedBox(width: 10),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
'Create sub space',
|
|
||||||
style: TextStyle(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
SizedBox(
|
TextButton(
|
||||||
width: screenWidth * 0.25,
|
onPressed: () async {
|
||||||
child: Container(
|
final result = await showDialog<bool>(
|
||||||
decoration: BoxDecoration(
|
barrierDismissible: false,
|
||||||
color: ColorsManager.textFieldGreyColor,
|
context: context,
|
||||||
border:
|
builder: (context) => AddDeviceWidget(
|
||||||
Border.all(color: ColorsManager.neutralGray, width: 3.0),
|
products: products,
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
child: const Padding(
|
|
||||||
padding:
|
|
||||||
EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.add,
|
|
||||||
color: ColorsManager.spaceColor,
|
|
||||||
),
|
|
||||||
SizedBox(width: 10),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
'Add devices',
|
|
||||||
style: TextStyle(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
|
if (result == true) {
|
||||||
|
// Handle the result if necessary
|
||||||
|
print('Devices added successfully');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
),
|
||||||
|
child: _buildButtonContent(
|
||||||
|
context,
|
||||||
|
icon: Icons.add,
|
||||||
|
label: 'Add Devices',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
@ -146,14 +109,17 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: CancelButton(
|
child: CancelButton(
|
||||||
label: 'Cancel',
|
label: 'Cancel',
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
backgroundColor: ColorsManager.secondaryColor,
|
backgroundColor: ColorsManager.secondaryColor,
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
foregroundColor: ColorsManager.whiteColors,
|
foregroundColor: ColorsManager.whiteColors,
|
||||||
@ -162,10 +128,50 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildButtonContent(BuildContext context,
|
||||||
|
{required IconData icon, required String label}) {
|
||||||
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
width: screenWidth * 0.25,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.textFieldGreyColor,
|
||||||
|
border: Border.all(
|
||||||
|
color: ColorsManager.neutralGray,
|
||||||
|
width: 3.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
color: ColorsManager.spaceColor,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,15 @@ 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/common/buttons/default_button.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/subspace_model_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/subspace_model_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/subspace_model_event.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/subspace_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/space_template_model.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class CreateSubSpaceModelDialog extends StatefulWidget {
|
class CreateSubSpaceModelDialog extends StatefulWidget {
|
||||||
final bool isEdit; // Flag to determine if it's edit or create
|
final bool isEdit;
|
||||||
final String dialogTitle; // Title for the dialog
|
final String dialogTitle;
|
||||||
final List<SubspaceTemplateModel>? existingSubSpaces; // For edit mode
|
final List<SubspaceTemplateModel>? existingSubSpaces;
|
||||||
|
|
||||||
const CreateSubSpaceModelDialog({
|
const CreateSubSpaceModelDialog({
|
||||||
super.key,
|
super.key,
|
||||||
@ -52,8 +54,17 @@ class _CreateSubSpaceModelDialogState extends State<CreateSubSpaceModelDialog> {
|
|||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
|
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (_) => SubSpaceModelBloc(),
|
create: (_) {
|
||||||
|
final bloc = SubSpaceModelBloc();
|
||||||
|
if (widget.existingSubSpaces != null) {
|
||||||
|
for (var subSpace in widget.existingSubSpaces!) {
|
||||||
|
bloc.add(AddSubSpaceModel(subSpace));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bloc;
|
||||||
|
},
|
||||||
child: BlocBuilder<SubSpaceModelBloc, SubSpaceModelState>(
|
child: BlocBuilder<SubSpaceModelBloc, SubSpaceModelState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
|
@ -13,16 +13,20 @@ class SpaceModelCardWidget extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final Map<String, int> productTagCount = {};
|
final Map<String, int> productTagCount = {};
|
||||||
|
|
||||||
for (var tag in model.tags) {
|
if (model.tags != null) {
|
||||||
final prodIcon = tag.product?.icon ?? 'Unknown';
|
for (var tag in model.tags!) {
|
||||||
productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1;
|
final prodIcon = tag.product?.icon ?? 'Unknown';
|
||||||
|
productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var subspace in model.subspaceModels) {
|
if (model.subspaceModels != null) {
|
||||||
if (subspace.tags != null) {
|
for (var subspace in model.subspaceModels!) {
|
||||||
for (var tag in subspace.tags!) {
|
if (subspace.tags != null) {
|
||||||
final prodIcon = tag.product?.icon ?? 'Unknown';
|
for (var tag in subspace.tags!) {
|
||||||
productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1;
|
final prodIcon = tag.product?.icon ?? 'Unknown';
|
||||||
|
productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +69,7 @@ class SpaceModelCardWidget extends StatelessWidget {
|
|||||||
spacing: 3.0,
|
spacing: 3.0,
|
||||||
runSpacing: 3.0,
|
runSpacing: 3.0,
|
||||||
children: [
|
children: [
|
||||||
for (var subspace in model.subspaceModels.take(3))
|
for (var subspace in model.subspaceModels!.take(3))
|
||||||
SubspaceChipWidget(subspace: subspace.subspaceName),
|
SubspaceChipWidget(subspace: subspace.subspaceName),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
31
lib/utils/constants/action_enum.dart
Normal file
31
lib/utils/constants/action_enum.dart
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
enum Action {
|
||||||
|
update,
|
||||||
|
add,
|
||||||
|
delete,
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ActionExtension on Action {
|
||||||
|
String get value {
|
||||||
|
switch (this) {
|
||||||
|
case Action.update:
|
||||||
|
return 'update';
|
||||||
|
case Action.add:
|
||||||
|
return 'add';
|
||||||
|
case Action.delete:
|
||||||
|
return 'delete';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Action fromValue(String value) {
|
||||||
|
switch (value) {
|
||||||
|
case 'update':
|
||||||
|
return Action.update;
|
||||||
|
case 'add':
|
||||||
|
return Action.add;
|
||||||
|
case 'delete':
|
||||||
|
return Action.delete;
|
||||||
|
default:
|
||||||
|
throw ArgumentError('Invalid action: $value');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user