Skip to content

Commit 38e7a94

Browse files
authored
Merge pull request #29 from CoderJava/feature/tambahkan-note-di-fitur-add-manual-time
Feature - Tambahkan note di fitur add manual track
2 parents 77b1ea8 + ffe554a commit 38e7a94

File tree

9 files changed

+129
-62
lines changed

9 files changed

+129
-62
lines changed

assets/translations/en-US.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,5 +291,7 @@
291291
"set_finish_date": "Set finish date",
292292
"please_set_start_date": "Please set start date",
293293
"please_set_finish_date": "Please set finish date",
294-
"finish_date_time_must_be_after_of_start_date_time": "The finish date time must be after the start date time"
294+
"finish_date_time_must_be_after_of_start_date_time": "The finish date time must be after the start date time",
295+
"reason": "Reason",
296+
"why_are_you_adding_manual_track": "e.g. Forgot to start timer"
295297
}

lib/feature/data/model/manual_create_track/manual_create_track_body.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ class ManualCreateTrackBody extends Equatable {
1313
final String finishDate;
1414
@JsonKey(name: 'duration')
1515
final int duration;
16+
@JsonKey(name: 'note')
17+
final String? note;
1618

1719
ManualCreateTrackBody({
1820
required this.taskId,
1921
required this.startDate,
2022
required this.finishDate,
2123
required this.duration,
24+
required this.note,
2225
});
2326

2427
factory ManualCreateTrackBody.fromJson(Map<String, dynamic> json) => _$ManualCreateTrackBodyFromJson(json);
@@ -31,10 +34,12 @@ class ManualCreateTrackBody extends Equatable {
3134
startDate,
3235
finishDate,
3336
duration,
37+
note,
3438
];
3539

3640
@override
3741
String toString() {
38-
return 'ManualCreateTrackBody{taskId: $taskId, startDate: $startDate, finishDate: $finishDate, duration: $duration}';
42+
return 'ManualCreateTrackBody{taskId: $taskId, startDate: $startDate, finishDate: $finishDate, duration: $duration, '
43+
'note: $note}';
3944
}
4045
}

lib/feature/data/model/track_user/track_user_response.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class ItemTrackUserResponse extends Equatable {
5353
final String? user;
5454
@JsonKey(name: 'files')
5555
final List<ItemFileTrackUserResponse>? files;
56+
@JsonKey(name: 'note')
57+
final String? note;
5658

5759
ItemTrackUserResponse({
5860
required this.id,
@@ -67,6 +69,7 @@ class ItemTrackUserResponse extends Equatable {
6769
required this.userId,
6870
required this.user,
6971
required this.files,
72+
required this.note,
7073
});
7174

7275
factory ItemTrackUserResponse.fromJson(Map<String, dynamic> json) => _$ItemTrackUserResponseFromJson(json);
@@ -87,14 +90,15 @@ class ItemTrackUserResponse extends Equatable {
8790
userId,
8891
user,
8992
files,
93+
note,
9094
];
9195

9296
@override
9397
String toString() {
9498
return 'ItemTrackUserResponse{id: $id, taskId: $taskId, taskName: $taskName, projectId: $projectId, '
9599
'projectName: $projectName, startDate: $startDate, finishDate: $finishDate, '
96100
'activityInPercent: $activityInPercent, durationInSeconds: $durationInSeconds, userId: $userId, user: $user, '
97-
'files: $files}';
101+
'files: $files, note: $note}';
98102
}
99103
}
100104

lib/feature/presentation/page/manual_tracking/manual_tracking_page.dart

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class _ManualTrackingPageState extends State<ManualTrackingPage> {
3737
final controllerFinishDate = TextEditingController();
3838
final controllerFinishTime = TextEditingController();
3939
final controllerDuration = TextEditingController();
40+
final controllerNote = TextEditingController();
4041
final valueNotifierEnableButtonSave = ValueNotifier(false);
4142

4243
var isLoading = false;
@@ -412,6 +413,20 @@ class _ManualTrackingPageState extends State<ManualTrackingPage> {
412413
isEnabled: false,
413414
),
414415
const SizedBox(height: 24),
416+
buildWidgetField(
417+
controllerNote,
418+
label: 'reason'.tr(),
419+
hint: 'why_are_you_adding_manual_track'.tr(),
420+
isEnabled: true,
421+
readOnly: false,
422+
maxLength: 100,
423+
onChanged: (_) {
424+
doCheckEnableButtonSubmit();
425+
},
426+
minLines: 1,
427+
maxLines: 3,
428+
),
429+
const SizedBox(height: 24),
415430
buildWidgetButtonSave(),
416431
],
417432
),
@@ -551,6 +566,7 @@ class _ManualTrackingPageState extends State<ManualTrackingPage> {
551566
startDate: formattedStartDateTime,
552567
finishDate: formattedFinishDateTime,
553568
duration: durationInSeconds!,
569+
note: controllerNote.text.trim(),
554570
);
555571
manualTrackingBloc.add(
556572
CreateManualTrackingEvent(
@@ -612,18 +628,27 @@ class _ManualTrackingPageState extends State<ManualTrackingPage> {
612628
Function()? onTap,
613629
bool isEnabled = true,
614630
FormFieldValidator<String>? validator,
631+
bool readOnly = true,
632+
int? maxLength,
633+
ValueChanged<String>? onChanged,
634+
int? minLines,
635+
int? maxLines,
615636
}) {
616637
return TextFormField(
617638
controller: controller,
618639
decoration: widgetHelper.setDefaultTextFieldDecoration(
619640
labelText: label,
620641
hintText: hint,
621642
),
622-
readOnly: true,
643+
readOnly: readOnly,
623644
mouseCursor: MaterialStateMouseCursor.clickable,
624645
onTap: onTap,
625646
validator: validator,
626647
enabled: isEnabled,
648+
maxLength: maxLength,
649+
onChanged: onChanged,
650+
minLines: minLines,
651+
maxLines: maxLines,
627652
);
628653
}
629654

@@ -655,22 +680,24 @@ class _ManualTrackingPageState extends State<ManualTrackingPage> {
655680
validator: validator,
656681
autovalidateMode: AutovalidateMode.onUserInteraction,
657682
padding: EdgeInsets.zero,
683+
hint: Text(hintText),
658684
decoration: widgetHelper.setDefaultTextFieldDecoration(
659685
labelText: labelText,
660-
hintText: hintText,
661686
floatingLabelBehavior: FloatingLabelBehavior.always,
662687
),
663688
);
664689
}
665690

666691
void doCheckEnableButtonSubmit() {
667692
var isEnableTemp = false;
693+
final reason = controllerNote.text.trim();
668694
if (selectedProject != null &&
669695
selectedTask != null &&
670696
startDate != null &&
671697
finishDate != null &&
672698
durationInSeconds != null &&
673-
durationInSeconds! > 0) {
699+
durationInSeconds! > 0 &&
700+
reason.isNotEmpty) {
674701
isEnableTemp = true;
675702
}
676703
if (isEnableTemp != valueNotifierEnableButtonSave.value) {

lib/feature/presentation/page/report_screenshot/report_screenshot_page.dart

Lines changed: 77 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -808,71 +808,97 @@ class _ReportScreenshotPageState extends State<ReportScreenshotPage> {
808808
}
809809

810810
final trackId = element.id;
811+
final note = element.note ?? '';
811812
return Align(
812813
alignment: Alignment.center,
813814
child: Padding(
814815
padding: EdgeInsets.only(top: heightImage),
815816
child: Row(
816817
mainAxisSize: MainAxisSize.max,
817-
mainAxisAlignment: MainAxisAlignment.end,
818+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
818819
children: [
819-
Material(
820-
borderRadius: BorderRadius.circular(999),
821-
child: InkWell(
822-
borderRadius: BorderRadius.circular(999),
823-
onTap: () {
824-
if (trackId == null) {
825-
widgetHelper.showSnackBar(
826-
context,
827-
'track_id_invalid'.tr(),
828-
);
829-
return;
830-
}
820+
note.isEmpty
821+
? Container()
822+
: Tooltip(
823+
message: note,
824+
child: Padding(
825+
padding: const EdgeInsets.all(8.0),
826+
child: FaIcon(
827+
FontAwesomeIcons.penToSquare,
828+
color: Theme.of(context).colorScheme.primary,
829+
size: 14,
830+
),
831+
),
832+
),
833+
buildWidgetIconDelete(
834+
const FaIcon(
835+
FontAwesomeIcons.trashCan,
836+
color: Colors.red,
837+
size: 14,
838+
),
839+
onTap: () {
840+
if (trackId == null) {
841+
widgetHelper.showSnackBar(
842+
context,
843+
'track_id_invalid'.tr(),
844+
);
845+
return;
846+
}
831847

832-
showDialog<bool?>(
833-
context: context,
834-
builder: (context) {
835-
return AlertDialog(
836-
title: Text('title_delete_track'.tr()),
837-
content: Text('content_delete_track'.tr()),
838-
actions: [
839-
TextButton(
840-
onPressed: () => context.pop(false),
841-
child: Text('cancel'.tr()),
842-
),
843-
TextButton(
844-
onPressed: () => context.pop(true),
845-
style: TextButton.styleFrom(
846-
foregroundColor: Colors.red,
847-
),
848-
child: Text('delete'.tr()),
848+
showDialog<bool?>(
849+
context: context,
850+
builder: (context) {
851+
return AlertDialog(
852+
title: Text('title_delete_track'.tr()),
853+
content: Text('content_delete_track'.tr()),
854+
actions: [
855+
TextButton(
856+
onPressed: () => context.pop(false),
857+
child: Text('cancel'.tr()),
858+
),
859+
TextButton(
860+
onPressed: () => context.pop(true),
861+
style: TextButton.styleFrom(
862+
foregroundColor: Colors.red,
849863
),
850-
],
851-
);
852-
},
853-
).then((value) {
854-
if (value != null && value) {
855-
trackingBloc.add(
856-
DeleteTrackUserTrackingEvent(
857-
trackId: trackId,
864+
child: Text('delete'.tr()),
858865
),
859-
);
860-
}
861-
});
862-
},
863-
child: const Padding(
864-
padding: EdgeInsets.all(8.0),
865-
child: FaIcon(
866-
FontAwesomeIcons.trashCan,
867-
color: Colors.red,
868-
size: 14,
869-
),
870-
),
871-
),
866+
],
867+
);
868+
},
869+
).then((value) {
870+
if (value != null && value) {
871+
trackingBloc.add(
872+
DeleteTrackUserTrackingEvent(
873+
trackId: trackId,
874+
),
875+
);
876+
}
877+
});
878+
},
872879
),
873880
],
874881
),
875882
),
876883
);
877884
}
885+
886+
Widget buildWidgetIconDelete(
887+
Widget icon, {
888+
Function()? onTap,
889+
ValueChanged<bool>? onHover,
890+
}) {
891+
return Material(
892+
borderRadius: BorderRadius.circular(999),
893+
child: InkWell(
894+
borderRadius: BorderRadius.circular(999),
895+
onTap: onTap,
896+
onHover: onHover,
897+
child: Padding(
898+
padding: const EdgeInsets.all(8.0),
899+
child: icon,
900+
),
901+
),
902+
);
903+
}
878904
}

macos/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,6 @@ SPEC CHECKSUMS:
9090
tray_manager: 9064e219c56d75c476e46b9a21182087930baf90
9191
window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8
9292

93-
PODFILE CHECKSUM: 8d40c19d3cbdb380d870685c3a564c989f1efa52
93+
PODFILE CHECKSUM: 7b8886a4ad89b3a2f7a16642e81ab6bed5c5d3ac
9494

95-
COCOAPODS: 1.12.1
95+
COCOAPODS: 1.13.0

test/feature/data/model/manual_create_track/manual_create_track_body_test.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ void main() {
2424
tModel.startDate,
2525
tModel.finishDate,
2626
tModel.duration,
27+
tModel.note,
2728
],
2829
);
2930
},
@@ -36,7 +37,7 @@ void main() {
3637
expect(
3738
tModel.toString(),
3839
'ManualCreateTrackBody{taskId: ${tModel.taskId}, startDate: ${tModel.startDate}, '
39-
'finishDate: ${tModel.finishDate}, duration: ${tModel.duration}}',
40+
'finishDate: ${tModel.finishDate}, duration: ${tModel.duration}, note: ${tModel.note}}',
4041
);
4142
},
4243
);

test/fixture/manual_create_track_body.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"task_id": 1,
33
"start_date": "testStartDate",
44
"finish_date": "testFinishDate",
5-
"duration": 0
5+
"duration": 0,
6+
"note": "testNote"
67
}

test/fixture/track_user_response.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"url_blur": "testUrlBlur",
2121
"size_blur": 1
2222
}
23-
]
23+
],
24+
"note": "testNote"
2425
}
2526
]
2627
}

0 commit comments

Comments
 (0)