added load new space models

This commit is contained in:
hannathkadher
2025-01-09 00:07:51 +04:00
parent 48c064c711
commit 339a242e74
12 changed files with 249 additions and 74 deletions

View File

@ -1,12 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_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/product_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_model.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_structure_widget.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/gradient_canvas_border_widget.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/sidebar_widget.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_bloc.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/view/space_model_page.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/view/space_model_page.dart';
import 'package:syncrow_web/services/space_model_mang_api.dart';
class LoadedSpaceView extends StatefulWidget { class LoadedSpaceView extends StatefulWidget {
final List<CommunityModel> communities; final List<CommunityModel> communities;
@ -47,10 +50,16 @@ class _LoadedStateViewState extends State<LoadedSpaceView> {
), ),
hasSpaceModels hasSpaceModels
? Expanded( ? Expanded(
child: SpaceModelPage( child: BlocProvider(
spaceModels: widget.spaceModels ?? [], create: (context) => SpaceModelBloc(
products: widget.products, api: SpaceModelManagementApi(),
)) initialSpaceModels: widget.spaceModels ?? [],
),
child: SpaceModelPage(
products: widget.products,
),
),
)
: CommunityStructureArea( : CommunityStructureArea(
selectedCommunity: widget.selectedCommunity, selectedCommunity: widget.selectedCommunity,
selectedSpace: widget.selectedSpace, selectedSpace: widget.selectedSpace,

View File

@ -15,7 +15,7 @@ class CreateSpaceModelBloc
CreateSpaceModelBloc(this._api) : super(CreateSpaceModelInitial()) { CreateSpaceModelBloc(this._api) : super(CreateSpaceModelInitial()) {
on<CreateSpaceTemplate>((event, emit) async { on<CreateSpaceTemplate>((event, emit) async {
try { try {
final spaceTemplate = event.spaceTemplate; late SpaceTemplateModel spaceTemplate = event.spaceTemplate;
final tagBodyModels = final tagBodyModels =
spaceTemplate.tags?.map((tag) => tag.toTagBodyModel()).toList() ?? spaceTemplate.tags?.map((tag) => tag.toTagBodyModel()).toList() ??
@ -37,7 +37,16 @@ class CreateSpaceModelBloc
tags: tagBodyModels, tags: tagBodyModels,
subspaceModels: subspaceTemplateBodyModels); subspaceModels: subspaceTemplateBodyModels);
await _api.createSpaceModel(spaceModelBody); final newSpaceTemplate = await _api.createSpaceModel(spaceModelBody);
spaceTemplate.uuid = newSpaceTemplate?.uuid ?? '';
if (newSpaceTemplate != null) {
emit(CreateSpaceModelLoaded(spaceTemplate));
if (event.onCreate != null) {
event.onCreate!(spaceTemplate);
}
}
} catch (e) { } catch (e) {
emit(CreateSpaceModelError('Error creating space model')); emit(CreateSpaceModelError('Error creating space model'));
} }
@ -77,22 +86,17 @@ class CreateSpaceModelBloc
on<UpdateSpaceTemplateName>((event, emit) { on<UpdateSpaceTemplateName>((event, emit) {
final currentState = state; final currentState = state;
print('Current State: $currentState');
if (currentState is CreateSpaceModelLoaded) { if (currentState is CreateSpaceModelLoaded) {
if (event.name.trim().isEmpty) { if (event.name.trim().isEmpty) {
print("set error message");
emit(CreateSpaceModelLoaded( emit(CreateSpaceModelLoaded(
currentState.space, currentState.space,
errorMessage: "Model name cannot be empty", errorMessage: "Model name cannot be empty",
)); ));
print('State emitted: CreateSpaceModelLoaded with updated model:');
} else { } else {
final updatedSpaceModel = final updatedSpaceModel =
currentState.space.copyWith(modelName: event.name); currentState.space.copyWith(modelName: event.name);
print(
'State emitted: CreateSpaceModelLoaded with updated model: $updatedSpaceModel');
emit(CreateSpaceModelLoaded(updatedSpaceModel)); emit(CreateSpaceModelLoaded(updatedSpaceModel));
} }
} else { } else {

View File

@ -19,9 +19,11 @@ class UpdateSpaceTemplate extends CreateSpaceModelEvent {
class CreateSpaceTemplate extends CreateSpaceModelEvent { class CreateSpaceTemplate extends CreateSpaceModelEvent {
final SpaceTemplateModel spaceTemplate; final SpaceTemplateModel spaceTemplate;
final Function(SpaceTemplateModel)? onCreate;
const CreateSpaceTemplate({ const CreateSpaceTemplate({
required this.spaceTemplate, required this.spaceTemplate,
this.onCreate,
}); });
@override @override
@ -47,4 +49,4 @@ class ValidateSpaceTemplateName extends CreateSpaceModelEvent {
final String name; final String name;
ValidateSpaceTemplateName({required this.name}); ValidateSpaceTemplateName({required this.name});
} }

View File

@ -0,0 +1,36 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_state.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
import 'package:syncrow_web/services/space_model_mang_api.dart';
class SpaceModelBloc extends Bloc<SpaceModelEvent, SpaceModelState> {
final SpaceModelManagementApi api;
SpaceModelBloc({
required this.api,
required List<SpaceTemplateModel> initialSpaceModels,
}) : super(SpaceModelLoaded(spaceModels: initialSpaceModels)) {
on<CreateSpaceModel>(_onCreateSpaceModel);
}
Future<void> _onCreateSpaceModel(
CreateSpaceModel event, Emitter<SpaceModelState> emit) async {
final currentState = state;
if (currentState is SpaceModelLoaded) {
try {
final newSpaceModel =
await api.getSpaceModel(event.newSpaceModel.uuid ?? '');
if (newSpaceModel != null) {
final updatedSpaceModels =
List<SpaceTemplateModel>.from(currentState.spaceModels)
..add(newSpaceModel);
emit(SpaceModelLoaded(spaceModels: updatedSpaceModels));
}
} catch (e) {
emit(SpaceModelError(message: e.toString()));
}
}
}
}

View File

@ -0,0 +1,18 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
abstract class SpaceModelEvent extends Equatable {
@override
List<Object?> get props => [];
}
class LoadSpaceModels extends SpaceModelEvent {}
class CreateSpaceModel extends SpaceModelEvent {
final SpaceTemplateModel newSpaceModel;
CreateSpaceModel({required this.newSpaceModel});
@override
List<Object?> get props => [newSpaceModel];
}

View File

@ -0,0 +1,29 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
abstract class SpaceModelState extends Equatable {
@override
List<Object?> get props => [];
}
class SpaceModelInitial extends SpaceModelState {}
class SpaceModelLoading extends SpaceModelState {}
class SpaceModelLoaded extends SpaceModelState {
final List<SpaceTemplateModel> spaceModels;
SpaceModelLoaded({required this.spaceModels});
@override
List<Object?> get props => [spaceModels];
}
class SpaceModelError extends SpaceModelState {
final String message;
SpaceModelError({required this.message});
@override
List<Object?> get props => [message];
}

View File

@ -6,7 +6,7 @@ import 'package:syncrow_web/utils/constants/action_enum.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
class SpaceTemplateModel extends Equatable { class SpaceTemplateModel extends Equatable {
final String? uuid; String? uuid;
String modelName; String modelName;
List<SubspaceTemplateModel>? subspaceModels; List<SubspaceTemplateModel>? subspaceModels;
final List<TagModel>? tags; final List<TagModel>? tags;
@ -31,16 +31,18 @@ class SpaceTemplateModel extends Equatable {
internalId: internalId, internalId: internalId,
modelName: json['modelName'] ?? '', modelName: json['modelName'] ?? '',
subspaceModels: (json['subspaceModels'] as List<dynamic>?) subspaceModels: (json['subspaceModels'] as List<dynamic>?)
?.map((e) => SubspaceTemplateModel.fromJson(e)) ?.where((e) => e is Map<String, dynamic>) // Validate type
.map((e) =>
SubspaceTemplateModel.fromJson(e as Map<String, dynamic>))
.toList() ?? .toList() ??
[], [],
tags: (json['tags'] as List<dynamic>?) tags: (json['tags'] as List<dynamic>?)
?.map((item) => TagModel.fromJson(item)) ?.where((item) => item is Map<String, dynamic>) // Validate type
.map((item) => TagModel.fromJson(item as Map<String, dynamic>))
.toList() ?? .toList() ??
[], [],
); );
} }
SpaceTemplateModel copyWith({ SpaceTemplateModel copyWith({
String? uuid, String? uuid,
String? modelName, String? modelName,

View File

@ -1,61 +1,90 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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/space_model/bloc/space_model_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_model_event.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/space_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/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';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
class SpaceModelPage extends StatelessWidget { class SpaceModelPage extends StatelessWidget {
final List<SpaceTemplateModel> spaceModels;
final List<ProductModel>? products; final List<ProductModel>? products;
const SpaceModelPage({Key? key, required this.spaceModels, this.products}) const SpaceModelPage({Key? key, this.products}) : super(key: key);
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final allTagValues = getAllTagValues(); return BlocBuilder<SpaceModelBloc, SpaceModelState>(
return Scaffold( builder: (context, state) {
backgroundColor: ColorsManager.whiteColors, if (state is SpaceModelLoading) {
body: Padding( return const Center(child: CircularProgressIndicator());
padding: const EdgeInsets.fromLTRB(20.0, 16.0, 16.0, 16.0), } else if (state is SpaceModelLoaded) {
child: Column( final spaceModels = state.spaceModels;
crossAxisAlignment: CrossAxisAlignment.stretch, final allTagValues = _getAllTagValues(spaceModels);
children: [
Expanded( return Scaffold(
child: GridView.builder( backgroundColor: ColorsManager.whiteColors,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( body: Padding(
crossAxisCount: 3, padding: const EdgeInsets.fromLTRB(20.0, 16.0, 16.0, 16.0),
crossAxisSpacing: 10.0, child: Column(
mainAxisSpacing: 10.0, crossAxisAlignment: CrossAxisAlignment.stretch,
childAspectRatio: calculateChildAspectRatio(context), children: [
), Expanded(
itemCount: spaceModels.length + 1, child: GridView.builder(
itemBuilder: (context, index) { gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
if (index == spaceModels.length) { crossAxisCount: 3,
return GestureDetector( crossAxisSpacing: 10.0,
onTap: () { mainAxisSpacing: 10.0,
showDialog( childAspectRatio: _calculateChildAspectRatio(context),
context: context, ),
builder: (BuildContext context) { itemCount: spaceModels.length + 1,
return CreateSpaceModelDialog( itemBuilder: (context, index) {
products: products, if (index == spaceModels.length) {
allTags: allTagValues, // Add Button
); return GestureDetector(
}, onTap: () {
); showDialog(
context: context,
builder: (BuildContext dialogContext) {
return CreateSpaceModelDialog(
products: products,
allTags: allTagValues,
onLoad: (newModel) {
context.read<SpaceModelBloc>().add(
CreateSpaceModel(
newSpaceModel: newModel),
);
},
);
},
);
},
child: _buildAddContainer(),
);
}
// Render existing space model
final model = spaceModels[index];
return SpaceModelCardWidget(model: model);
}, },
child: _buildAddContainer(), ),
); ),
} ],
final model = spaceModels[index];
return SpaceModelCardWidget(model: model);
},
), ),
), ),
], );
), } else if (state is SpaceModelError) {
), return Center(
child: Text(
'Error: ${state.message}',
style: const TextStyle(color: Colors.red),
),
);
}
return const Center(child: Text('Initializing...'));
},
); );
} }
@ -101,23 +130,22 @@ class SpaceModelPage extends StatelessWidget {
); );
} }
double calculateChildAspectRatio(BuildContext context) { double _calculateChildAspectRatio(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width; double screenWidth = MediaQuery.of(context).size.width;
if (screenWidth > 1600) { if (screenWidth > 1600) {
return 3; return 3;
} }
if (screenWidth > 1200) { if (screenWidth > 1200) {
return 5; return 5;
} else if (screenWidth > 800) { } else if (screenWidth > 800) {
return 5; return 5;
} else { } else {
return 6.0; return 6.0;
} }
} }
List<String> getAllTagValues() { List<String> _getAllTagValues(List<SpaceTemplateModel> spaceModels) {
final List<String> allTags = []; final List<String> allTags = [];
for (final spaceModel in spaceModels) { for (final spaceModel in spaceModels) {
if (spaceModel.tags != null) { if (spaceModel.tags != null) {
allTags.addAll(spaceModel.listAllTagValues()); allTags.addAll(spaceModel.listAllTagValues());

View File

@ -17,10 +17,15 @@ class CreateSpaceModelDialog extends StatelessWidget {
final List<ProductModel>? products; final List<ProductModel>? products;
final List<String>? allTags; final List<String>? allTags;
final SpaceTemplateModel? spaceModel; final SpaceTemplateModel? spaceModel;
final void Function(SpaceTemplateModel newModel)? onLoad;
const CreateSpaceModelDialog( const CreateSpaceModelDialog({
{Key? key, this.products, this.allTags, this.spaceModel}) Key? key,
: super(key: key); this.products,
this.allTags,
this.spaceModel,
this.onLoad,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -142,11 +147,15 @@ class CreateSpaceModelDialog extends StatelessWidget {
); );
context.read<CreateSpaceModelBloc>().add( context.read<CreateSpaceModelBloc>().add(
CreateSpaceTemplate( CreateSpaceTemplate(
spaceTemplate: spaceTemplate:
updatedSpaceTemplate), updatedSpaceTemplate,
onCreate: (newModel) {
onLoad!(newModel);
Navigator.of(context)
.pop(); // Close the dialog
},
),
); );
Navigator.of(context).pop();
} }
: null, : null,
backgroundColor: ColorsManager.secondaryColor, backgroundColor: ColorsManager.secondaryColor,

View File

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/services/api/http_interceptor.dart'; import 'package:syncrow_web/services/api/http_interceptor.dart';
import 'package:syncrow_web/services/locator.dart'; import 'package:syncrow_web/services/locator.dart';
import 'package:syncrow_web/utils/constants/api_const.dart'; import 'package:syncrow_web/utils/constants/api_const.dart';
@ -34,13 +35,29 @@ class HTTPService {
bool showServerMessage = true, bool showServerMessage = true,
}) async { }) async {
try { try {
// Log the request path and query parameters
debugPrint('GET Request: $path');
if (queryParameters != null) {
debugPrint('Query Parameters: $queryParameters');
}
// Perform the HTTP GET request
final response = await client.get( final response = await client.get(
path, path,
queryParameters: queryParameters, queryParameters: queryParameters,
); );
return expectedResponseModel(response.data);
// Log the raw response data
debugPrint('Response Data: ${response.data}');
// Process the response using the expected model function
final result = expectedResponseModel(response.data);
return result;
} catch (error) { } catch (error) {
rethrow; // Log the error details
debugPrint('Error in GET Request: $error');
rethrow; // Re-throw the error to propagate it further
} }
} }

View File

@ -50,7 +50,27 @@ class SpaceModelManagementApi {
); );
return response; return response;
} catch (e) { } catch (e) {
debugPrint('Error creating community: $e'); debugPrint('Error creating space model: $e');
return null;
}
}
Future<SpaceTemplateModel?> getSpaceModel(String spaceModelUuid) async {
try {
final response = await HTTPService().get(
path: ApiEndpoints.getSpaceModel
.replaceAll('{projectId}', TempConst.projectId)
.replaceAll('{spaceModelUuid}', spaceModelUuid),
showServerMessage: true,
expectedResponseModel: (json) {
debugPrint('Response JSON: $json');
return SpaceTemplateModel.fromJson(json['data']);
},
);
return response;
} catch (e) {
debugPrint('Error getting space model: $e');
return null; return null;
} }
} }

View File

@ -100,4 +100,5 @@ abstract class ApiEndpoints {
//space model //space model
static const String listSpaceModels = '/projects/{projectId}/space-models'; static const String listSpaceModels = '/projects/{projectId}/space-models';
static const String createSpaceModel = '/projects/{projectId}/space-models'; static const String createSpaceModel = '/projects/{projectId}/space-models';
static const String getSpaceModel = '/projects/{projectId}/space-models/{spaceModelUuid}';
} }