mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
Implemented tags bloc, services, models, and params
This commit is contained in:
@ -0,0 +1,51 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:syncrow_web/pages/space_management_v2/shared/tags/domain/models/tag_model.dart';
|
||||
import 'package:syncrow_web/pages/space_management_v2/shared/tags/domain/params/load_tags_param.dart';
|
||||
import 'package:syncrow_web/pages/space_management_v2/shared/tags/domain/services/tags_service.dart';
|
||||
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||
import 'package:syncrow_web/services/api/http_service.dart';
|
||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||
|
||||
final class RemoteTagsService implements TagsService {
|
||||
const RemoteTagsService(this._httpService);
|
||||
|
||||
final HTTPService _httpService;
|
||||
|
||||
static const _defaultErrorMessage = 'Failed to load tags';
|
||||
|
||||
@override
|
||||
Future<List<TagModel>> loadTags(LoadTagsParam param) async {
|
||||
if (param.projectUuid == null) {
|
||||
throw Exception('Project UUID is required');
|
||||
}
|
||||
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.listTags.replaceAll(
|
||||
'{projectUuid}',
|
||||
param.projectUuid!,
|
||||
),
|
||||
expectedResponseModel: (json) {
|
||||
final result = json as Map<String, dynamic>;
|
||||
final data = result['data'] as List<dynamic>;
|
||||
return data
|
||||
.map((e) => TagModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} on DioException catch (e) {
|
||||
final message = e.response?.data as Map<String, dynamic>?;
|
||||
final error = message?['error'] as Map<String, dynamic>?;
|
||||
final errorMessage = error?['error'] as String? ?? '';
|
||||
final formattedErrorMessage = [
|
||||
_defaultErrorMessage,
|
||||
errorMessage,
|
||||
].join(': ');
|
||||
throw APIException(formattedErrorMessage);
|
||||
} catch (e) {
|
||||
final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': ');
|
||||
throw APIException(formattedErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class TagModel extends Equatable {
|
||||
const TagModel({
|
||||
required this.uuid,
|
||||
required this.tag,
|
||||
required this.internalId,
|
||||
required this.location,
|
||||
});
|
||||
|
||||
final String? uuid;
|
||||
final String? tag;
|
||||
final String? internalId;
|
||||
final String? location;
|
||||
|
||||
factory TagModel.fromJson(Map<String, dynamic> json) {
|
||||
final internalId = json['internalId'] as String? ?? const Uuid().v4();
|
||||
final tag = json['tag'] as Map<String, dynamic>?;
|
||||
final name = json['name'] as String?;
|
||||
|
||||
return TagModel(
|
||||
uuid: name != null ? json['uuid'] as String? : tag?['uuid'] as String?,
|
||||
internalId: internalId,
|
||||
tag: name ?? tag?['name'] as String?,
|
||||
location: json['location'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
TagModel copyWith({
|
||||
String? uuid,
|
||||
String? tag,
|
||||
String? location,
|
||||
String? internalId,
|
||||
}) {
|
||||
return TagModel(
|
||||
uuid: uuid ?? this.uuid,
|
||||
tag: tag ?? this.tag,
|
||||
location: location ?? this.location,
|
||||
internalId: internalId ?? this.internalId,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
if (uuid != null) 'uuid': uuid,
|
||||
'name': tag,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [uuid, tag, internalId, location];
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
class LoadTagsParam {
|
||||
final String? projectUuid;
|
||||
|
||||
const LoadTagsParam({this.projectUuid});
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import 'package:syncrow_web/pages/space_management_v2/shared/tags/domain/models/tag_model.dart';
|
||||
import 'package:syncrow_web/pages/space_management_v2/shared/tags/domain/params/load_tags_param.dart';
|
||||
|
||||
abstract interface class TagsService {
|
||||
Future<List<TagModel>> loadTags(LoadTagsParam param);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/space_management_v2/shared/tags/domain/models/tag_model.dart';
|
||||
import 'package:syncrow_web/pages/space_management_v2/shared/tags/domain/params/load_tags_param.dart';
|
||||
import 'package:syncrow_web/pages/space_management_v2/shared/tags/domain/services/tags_service.dart';
|
||||
import 'package:syncrow_web/services/api/api_exception.dart';
|
||||
|
||||
part 'tags_event.dart';
|
||||
part 'tags_state.dart';
|
||||
|
||||
class TagsBloc extends Bloc<TagsEvent, TagsState> {
|
||||
final TagsService _tagsService;
|
||||
|
||||
TagsBloc(this._tagsService) : super(TagsInitial()) {
|
||||
on<LoadTags>(_onLoadTags);
|
||||
}
|
||||
|
||||
Future<void> _onLoadTags(
|
||||
LoadTags event,
|
||||
Emitter<TagsState> emit,
|
||||
) async {
|
||||
emit(TagsLoading());
|
||||
try {
|
||||
final tags = await _tagsService.loadTags(
|
||||
event.param,
|
||||
);
|
||||
emit(TagsLoaded(tags));
|
||||
} on APIException catch (e) {
|
||||
emit(TagsFailure(e.message));
|
||||
} catch (e) {
|
||||
emit(TagsFailure(e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
part of 'tags_bloc.dart';
|
||||
|
||||
abstract class TagsEvent extends Equatable {
|
||||
const TagsEvent();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class LoadTags extends TagsEvent {
|
||||
final LoadTagsParam param;
|
||||
|
||||
const LoadTags(this.param);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [param];
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
part of 'tags_bloc.dart';
|
||||
|
||||
abstract class TagsState extends Equatable {
|
||||
const TagsState();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class TagsInitial extends TagsState {}
|
||||
|
||||
class TagsLoading extends TagsState {}
|
||||
|
||||
class TagsLoaded extends TagsState {
|
||||
final List<TagModel> tags;
|
||||
|
||||
const TagsLoaded(this.tags);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [tags];
|
||||
}
|
||||
|
||||
class TagsFailure extends TagsState {
|
||||
final String message;
|
||||
|
||||
const TagsFailure(this.message);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [message];
|
||||
}
|
Reference in New Issue
Block a user