Skip to content

Commit

Permalink
added filters
Browse files Browse the repository at this point in the history
  • Loading branch information
enoy19 committed May 22, 2023
1 parent be8b3b1 commit bf03a81
Show file tree
Hide file tree
Showing 9 changed files with 316 additions and 29 deletions.
6 changes: 3 additions & 3 deletions lib/cubit/time_entries_filter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ abstract class TimeEntriesFilter implements Built<TimeEntriesFilter, TimeEntries
DateTime? get filterEnd;
Duration? get filterDuration;
bool? get filterBooked;
int? get filterWeekday;
Set<int?> get filterWeekday;
Task? get filterTask;
List<String?> get filterWorkInterfaceId;
List<String?> get filterActivityNames;
Set<String?> get filterWorkInterfaceId;
Set<String?> get filterActivityNames;

TimeEntriesFilter._();

Expand Down
53 changes: 42 additions & 11 deletions lib/cubit/time_entries_filter_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import 'package:syntrack/cubit/time_entries_filter.dart';
import 'package:syntrack/model/common/time_entry.dart';
import 'package:syntrack/util/date_time_extension.dart';

const _durationFilterTolerance = 300;

class TimeEntriesFilterCubit extends Cubit<TimeEntriesFilter> {
TimeEntriesFilterCubit() : super(TimeEntriesFilterBuilder().build());
TimeEntriesFilterCubit()
: super((TimeEntriesFilterBuilder()
..filterActivityNames = {}
..filterWorkInterfaceId = {}
..filterWeekday = {})
.build());

Iterable<TimeEntry> filter(List<TimeEntry> timeEntries) {
final TimeEntriesFilter(
Expand All @@ -27,7 +30,7 @@ class TimeEntriesFilterCubit extends Cubit<TimeEntriesFilter> {
filterBooked == null &&
filterTask == null &&
filterDuration == null &&
filterWeekday == null &&
filterWeekday.isEmpty &&
filterWorkInterfaceId.isEmpty &&
filterStart == null &&
filterEnd == null) {
Expand All @@ -36,7 +39,11 @@ class TimeEntriesFilterCubit extends Cubit<TimeEntriesFilter> {

return timeEntries
.where(
(element) => query != null ? element.comment.trim().toLowerCase().contains(query) : true,
(element) => query != null
? '${element.comment.trim()}${element.task?.name ?? '<NO TASK>'}${element.activity?.name ?? '<NO ACTIVITY>'}'
.toLowerCase()
.contains(query.trim().toLowerCase())
: true,
)
.where(
(element) => filterActivityNames.isNotEmpty ? filterActivityNames.contains(element.activity?.name) : true,
Expand All @@ -52,7 +59,7 @@ class TimeEntriesFilterCubit extends Cubit<TimeEntriesFilter> {
(element) => filterTask != null ? element.task?.id == filterTask.id : true,
)
.where(
(element) => filterWeekday != null ? element.start.weekday == filterWeekday : true,
(element) => filterWeekday.isNotEmpty ? filterWeekday.contains(element.start.weekday) : true,
)
.where(
(element) =>
Expand All @@ -65,19 +72,43 @@ class TimeEntriesFilterCubit extends Cubit<TimeEntriesFilter> {
(element) => filterEnd != null ? element.end.startOfDay == filterEnd.startOfDay : true,
)
.where(
(element) => filterDuration != null
? (element.duration.inSeconds - filterDuration.inSeconds).abs() <= _durationFilterTolerance
: true,
(element) => filterDuration != null ? filterDuration.inSeconds <= element.duration.inSeconds : true,
);
}

void debouncedQuery(String query) {
void debouncedFilters(Function(TimeEntriesFilterBuilder) updates) {
EasyDebounce.debounce('time_entries_filter_cubit.debouncedFilters', const Duration(milliseconds: 500), () {
setFilters(updates);
});
}

void setFilters(Function(TimeEntriesFilterBuilder) updates) {
emit(state.rebuild(updates));
}

void clearFilters() {
emit(state.rebuild((p0) => p0
..filterActivityNames = const {}
..filterBooked = null
..filterTask = null
..filterDuration = null
..filterWeekday = const {}
..filterWorkInterfaceId = const {}
..filterStart = null
..filterEnd = null));
}

void debouncedQuery(String? query) {
EasyDebounce.debounce(
'time_entries_filter_cubit.debouncedQuery',
const Duration(milliseconds: 750),
() {
emit(state.rebuild((state) => state..query = query));
immediateQuery(query);
},
);
}

void immediateQuery(String? query) {
emit(state.rebuild((state) => state..query = query));
}
}
12 changes: 12 additions & 0 deletions lib/cubit/work_interface_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,16 @@ class WorkInterfaceCubit extends HydratedCubit<WorkInterfaceConfigs> {
})
.firstWhereOrNull((element) => element != null);
}

String getNameFor(dynamic workInterface) => switch (workInterface) {
ErpNextConfig() => workInterface.name,
RedmineConfig() => workInterface.name,
_ => '',
};

String getIdFor(dynamic workInterface) => switch (workInterface) {
ErpNextConfig() => workInterface.id,
RedmineConfig() => workInterface.id,
_ => '',
};
}
4 changes: 4 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:syntrack/cubit/booking_cubit.dart';
import 'package:syntrack/cubit/theme_mode_cubit.dart';
import 'package:syntrack/cubit/task_search_cubit.dart';
import 'package:syntrack/cubit/time_entries_cubit.dart';
import 'package:syntrack/cubit/time_entries_filter_cubit.dart';
import 'package:syntrack/cubit/time_tracking_cubit.dart';
import 'package:syntrack/cubit/work_interface_cubit.dart';
import 'package:syntrack/repository/data/latest_bookings_data_provider.dart';
Expand Down Expand Up @@ -77,6 +78,9 @@ class SynTrack extends StatelessWidget {
BlocProvider(
create: (context) => TimeEntriesCubit(),
),
BlocProvider(
create: (context) => TimeEntriesFilterCubit(),
),
BlocProvider(
lazy: false,
create: (context) {
Expand Down
21 changes: 7 additions & 14 deletions lib/ui/track_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:sizer/sizer.dart';
import 'package:syntrack/cubit/booking_cubit.dart';
import 'package:syntrack/cubit/time_entries_cubit.dart';
import 'package:syntrack/cubit/time_entries_filter_cubit.dart';
import 'package:syntrack/cubit/time_tracking_cubit.dart';
import 'package:syntrack/exception/work_interface_not_found.dart';
import 'package:syntrack/router.gr.dart';
import 'package:syntrack/ui/widget/time_entries_filter_bar.dart';
import 'package:syntrack/ui/widget/time_entries_list.dart';
import 'package:syntrack/ui/widget/time_tracking_header.dart';

Expand Down Expand Up @@ -56,28 +58,19 @@ class TrackPage extends StatelessWidget {
onPressed: () => _bookAll(context),
),
body: const TimeEntriesList(),
/*floatingActionButtonLocation: FloatingActionButtonLocation.endContained,
bottomNavigationBar: BottomAppBar(
// TODO: search and filter
child: Row(
children: [
IconButton(
tooltip: 'Search',
icon: const Icon(Icons.search),
onPressed: () {},
),
],
),
),*/
floatingActionButtonLocation: FloatingActionButtonLocation.endContained,
bottomNavigationBar: const TimeEntriesFilterBar(),
);
}

_bookAll(BuildContext context) async {
try {
final notBooked = context.read<TimeEntriesCubit>().state.where((element) => element.bookingId == null).toList();
final notBookedFiltered = context.read<TimeEntriesFilterCubit>().filter(notBooked);

await context.read<BookingCubit>().bookMany(
context,
notBooked,
notBookedFiltered.toList(),
);
} on WorkInterfaceNotFound {
ScaffoldMessenger.of(context).showSnackBar(
Expand Down
1 change: 1 addition & 0 deletions lib/ui/widget/comment_edit_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class _CommentEditFieldState extends State<CommentEditField> {
@override
Widget build(BuildContext context) {
return SearchBar(
hintText: 'Comment',
focusNode: _focusNode,
controller: _controller,
trailing: [
Expand Down
Loading

0 comments on commit bf03a81

Please sign in to comment.