Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - Buat add manual track #21

Merged
merged 18 commits into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ccbe219
feat: Handle durasi jam di halaman report_screenshot_page.dart dan sy…
CoderJava Aug 27, 2023
0f6f9ed
feat: Buat class model manual_create_track_body.dart
CoderJava Aug 28, 2023
8b56f49
feat: Buat endpoint `createManualTrack`
CoderJava Aug 28, 2023
9373a45
feat: Buat implement function endpoint `createManualTrack`
CoderJava Aug 28, 2023
f4e3689
feat: Buat use case endpoint `createManualTrack`
CoderJava Aug 28, 2023
932934d
feat: Buat business logic create manual tracking
CoderJava Aug 28, 2023
2e3b564
feat: Daftarkan use case endpoint `CreateManualTrack` kedalam mock_he…
CoderJava Aug 28, 2023
0c4abdb
feat: Daftarkan `ManualTrackingBloc` dan use case `CreateManualTrack`…
CoderJava Aug 28, 2023
c2be7bf
feat: Buat class model project_task_response.dart
CoderJava Sep 1, 2023
f0a1b63
feat: Buat endpoint `getProjectTaskByUserId`
CoderJava Sep 1, 2023
ea61891
feat: Buat implement function endpoint `getProjectTaskByUserId`
CoderJava Sep 1, 2023
1d3f194
feat: Buat use case endpoint `getProjectTaskByUserId`
CoderJava Sep 2, 2023
8589f23
feat: Buat business logic untuk memuat project dan task di form manua…
CoderJava Sep 2, 2023
e05ea7e
feat: Tambahkan plugin `omni_datetime_picker`
CoderJava Sep 3, 2023
a44ecc9
feat: Buat UI dan fitur add manual tracking
CoderJava Sep 3, 2023
fb71982
feat: Daftarkan halaman manual tracking kedalam route
CoderJava Sep 3, 2023
80e4350
feat: Tambahkan menu add manual track di halaman home
CoderJava Sep 3, 2023
3176434
feat: Update localization bahasa English
CoderJava Sep 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion assets/translations/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -246,5 +246,24 @@
"new_password": "New Password",
"subtitle_new_password": "Please create a new password that you don't use on any other site",
"change": "Change",
"create_new_password": "Create new password"
"create_new_password": "Create new password",
"add_manual_track_successfully": "Add manual track successfully",
"add_manual_track": "Add Manual Track",
"project": "Project",
"select_project": "Select project",
"task": "Task",
"select_task": "Select task",
"select_a_project_first": "Select a project first",
"no_data_available": "No data available",
"please_choose_a_task": "Please choose a task",
"start_time": "Start time",
"set_start_time": "Set start time",
"time": "Time",
"date": "Date",
"finish_time": "Finish time",
"set_finish_time": "Set finish time",
"set_start_and_finish_time": "Set start and finish time",
"duration": "Duration",
"please_set_start_time": "Please set start time",
"please_set_finish_time": "Please set finish time"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:dio/dio.dart';
import 'package:dipantau_desktop_client/config/base_url_config.dart';
import 'package:dipantau_desktop_client/config/flavor_config.dart';
import 'package:dipantau_desktop_client/feature/data/model/project/project_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/project_task/project_task_response.dart';

abstract class ProjectRemoteDataSource {
/// Panggil endpoint [host]/project/user/:id
Expand All @@ -12,6 +13,15 @@ abstract class ProjectRemoteDataSource {
late String pathGetProject;

Future<ProjectResponse> getProject(String userId);

/// Panggil endpoint [host]/project/user/:id/detail
/// path parameter
/// id - nilai ID user
///
/// Throws [DioException] untuk semua error kode
late String pathGetProjectTaskByUserId;

Future<ProjectTaskResponse> getProjectTaskByUserId(String userId);
}

class ProjectRemoteDataSourceImpl implements ProjectRemoteDataSource {
Expand Down Expand Up @@ -44,4 +54,25 @@ class ProjectRemoteDataSourceImpl implements ProjectRemoteDataSource {
throw DioException(requestOptions: RequestOptions(path: pathGetProject));
}
}

@override
String pathGetProjectTaskByUserId = '';

@override
Future<ProjectTaskResponse> getProjectTaskByUserId(String userId) async {
pathGetProjectTaskByUserId = '$baseUrl/user/$userId/detail';
final response = await dio.get(
pathGetProjectTaskByUserId,
options: Options(
headers: {
baseUrlConfig.requiredToken: true,
},
),
);
if (response.statusCode.toString().startsWith('2')) {
return ProjectTaskResponse.fromJson(response.data);
} else {
throw DioException(requestOptions: RequestOptions(path: pathGetProjectTaskByUserId));
}
}
}
30 changes: 30 additions & 0 deletions lib/feature/data/datasource/track/track_remote_data_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_cre
import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_create_track_image_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/create_track/create_track_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/manual_create_track/manual_create_track_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/track_user/track_user_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/track_user_lite/track_user_lite_response.dart';

Expand Down Expand Up @@ -50,6 +51,13 @@ abstract class TrackRemoteDataSource {
late String pathDeleteTrack;

Future<GeneralResponse> deleteTrackUser(int trackId);

/// Panggil endpoint [host]/track/manual
///
/// Throws [DioException] untuk semua error kode
late String pathCreateManualTrack;

Future<GeneralResponse> createManualTrack(ManualCreateTrackBody body);
}

class TrackRemoteDataSourceImpl implements TrackRemoteDataSource {
Expand Down Expand Up @@ -222,4 +230,26 @@ class TrackRemoteDataSourceImpl implements TrackRemoteDataSource {
throw DioException(requestOptions: RequestOptions(path: pathDeleteTrack));
}
}

@override
String pathCreateManualTrack = '';

@override
Future<GeneralResponse> createManualTrack(ManualCreateTrackBody body) async {
pathCreateManualTrack = '$baseUrl/manual';
final response = await dio.post(
pathCreateManualTrack,
data: body.toJson(),
options: Options(
headers: {
baseUrlConfig.requiredToken: true,
},
),
);
if (response.statusCode.toString().startsWith('2')) {
return GeneralResponse.fromJson(response.data);
} else {
throw DioException(requestOptions: RequestOptions(path: pathCreateManualTrack));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';

part 'manual_create_track_body.g.dart';

@JsonSerializable()
class ManualCreateTrackBody extends Equatable {
@JsonKey(name: 'task_id')
final int taskId;
@JsonKey(name: 'start_date')
final String startDate;
@JsonKey(name: 'finish_date')
final String finishDate;
@JsonKey(name: 'duration')
final int duration;

ManualCreateTrackBody({
required this.taskId,
required this.startDate,
required this.finishDate,
required this.duration,
});

factory ManualCreateTrackBody.fromJson(Map<String, dynamic> json) => _$ManualCreateTrackBodyFromJson(json);

Map<String, dynamic> toJson() => _$ManualCreateTrackBodyToJson(this);

@override
List<Object?> get props => [
taskId,
startDate,
finishDate,
duration,
];

@override
String toString() {
return 'ManualCreateTrackBody{taskId: $taskId, startDate: $startDate, finishDate: $finishDate, duration: $duration}';
}
}
89 changes: 89 additions & 0 deletions lib/feature/data/model/project_task/project_task_response.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';

part 'project_task_response.g.dart';

@JsonSerializable()
class ProjectTaskResponse extends Equatable {
@JsonKey(name: 'data')
final List<ItemProjectTaskResponse>? data;

ProjectTaskResponse({
required this.data,
});

factory ProjectTaskResponse.fromJson(Map<String, dynamic> json) => _$ProjectTaskResponseFromJson(json);

Map<String, dynamic> toJson() => _$ProjectTaskResponseToJson(this);

@override
List<Object?> get props => [
data,
];

@override
String toString() {
return 'ProjectTaskResponse{data: $data}';
}
}

@JsonSerializable()
class ItemProjectTaskResponse extends Equatable {
@JsonKey(name: 'project_id')
final int? projectId;
@JsonKey(name: 'project_name')
final String? projectName;
@JsonKey(name: 'tasks')
final List<ItemTaskLiteProjectTaskResponse> tasks;

ItemProjectTaskResponse({
required this.projectId,
required this.projectName,
required this.tasks,
});

factory ItemProjectTaskResponse.fromJson(Map<String, dynamic> json) => _$ItemProjectTaskResponseFromJson(json);

Map<String, dynamic> toJson() => _$ItemProjectTaskResponseToJson(this);

@override
List<Object?> get props => [
projectId,
projectName,
tasks,
];

@override
String toString() {
return 'ItemProjectTaskResponse{projectId: $projectId, projectName: $projectName, tasks: $tasks}';
}
}

@JsonSerializable()
class ItemTaskLiteProjectTaskResponse extends Equatable {
@JsonKey(name: 'id')
final int? id;
@JsonKey(name: 'name')
final String? name;

ItemTaskLiteProjectTaskResponse({
required this.id,
required this.name,
});

factory ItemTaskLiteProjectTaskResponse.fromJson(Map<String, dynamic> json) =>
_$ItemTaskLiteProjectTaskResponseFromJson(json);

Map<String, dynamic> toJson() => _$ItemTaskLiteProjectTaskResponseToJson(this);

@override
List<Object?> get props => [
id,
name,
];

@override
String toString() {
return 'ItemTaskLiteProjectTaskResponse{id: $id, name: $name}';
}
}
31 changes: 31 additions & 0 deletions lib/feature/data/repository/project/project_repository_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:dipantau_desktop_client/core/error/failure.dart';
import 'package:dipantau_desktop_client/core/network/network_info.dart';
import 'package:dipantau_desktop_client/feature/data/datasource/project/project_remote_data_source.dart';
import 'package:dipantau_desktop_client/feature/data/model/project/project_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/project_task/project_task_response.dart';
import 'package:dipantau_desktop_client/feature/domain/repository/project/project_repository.dart';

class ProjectRepositoryImpl implements ProjectRepository {
Expand Down Expand Up @@ -51,4 +52,34 @@ class ProjectRepositoryImpl implements ProjectRepository {
return Left(ConnectionFailure());
}
}

@override
Future<({Failure? failure, ProjectTaskResponse? response})> getProjectTaskByUserId(String userId) async {
Failure? failure;
ProjectTaskResponse? response;
final isConnected = await networkInfo.isConnected;
if (isConnected) {
try {
response = await remoteDataSource.getProjectTaskByUserId(userId);
} on DioException catch (error) {
final message = error.message ?? error.toString();
if (error.response == null) {
failure = ServerFailure(message);
} else {
final errorMessage = getErrorMessageFromEndpoint(
error.response?.data,
message,
error.response?.statusCode,
);
failure = ServerFailure(errorMessage);
}
} on TypeError catch (error) {
final errorMessage = error.toString();
failure = ParsingFailure(errorMessage);
}
} else {
failure = ConnectionFailure();
}
return (failure: failure, response: response);
}
}
31 changes: 31 additions & 0 deletions lib/feature/data/repository/track/track_repository_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_cre
import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_create_track_image_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/create_track/create_track_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/manual_create_track/manual_create_track_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/track_user/track_user_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/track_user_lite/track_user_lite_response.dart';
import 'package:dipantau_desktop_client/feature/domain/repository/track/track_repository.dart';
Expand Down Expand Up @@ -206,4 +207,34 @@ class TrackRepositoryImpl implements TrackRepository {
}
return (failure: failure, response: response);
}

@override
Future<({Failure? failure, GeneralResponse? response})> createManualTrack(ManualCreateTrackBody body) async {
Failure? failure;
GeneralResponse? response;
final isConnected = await networkInfo.isConnected;
if (isConnected) {
try {
response = await remoteDataSource.createManualTrack(body);
} on DioException catch (error) {
final message = error.message ?? error.toString();
if (error.response == null) {
failure = ServerFailure(message);
} else {
final errorMessage = getErrorMessageFromEndpoint(
error.response?.data,
message,
error.response?.statusCode,
);
failure = ServerFailure(errorMessage);
}
} on TypeError catch (error) {
final errorMessage = error.toString();
failure = ParsingFailure(errorMessage);
}
} else {
failure = ConnectionFailure();
}
return (failure: failure, response: response);
}
}
3 changes: 3 additions & 0 deletions lib/feature/domain/repository/project/project_repository.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'package:dartz/dartz.dart';
import 'package:dipantau_desktop_client/core/error/failure.dart';
import 'package:dipantau_desktop_client/feature/data/model/project/project_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/project_task/project_task_response.dart';

abstract class ProjectRepository {
Future<Either<Failure, ProjectResponse>> getProject(String userId);

Future<({Failure? failure, ProjectTaskResponse? response})> getProjectTaskByUserId(String userId);
}
3 changes: 3 additions & 0 deletions lib/feature/domain/repository/track/track_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_cre
import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_create_track_image_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/create_track/create_track_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/manual_create_track/manual_create_track_body.dart';
import 'package:dipantau_desktop_client/feature/data/model/track_user/track_user_response.dart';
import 'package:dipantau_desktop_client/feature/data/model/track_user_lite/track_user_lite_response.dart';

Expand All @@ -19,4 +20,6 @@ abstract class TrackRepository {
Future<({Failure? failure, TrackUserResponse? response})> getTrackUser(String userId, String date);

Future<({Failure? failure, GeneralResponse? response})> deleteTrackUser(int trackId);

Future<({Failure? failure, GeneralResponse? response})> createManualTrack(ManualCreateTrackBody body);
}
Loading