Skip to content

Commit

Permalink
Switch User Filter to users collection
Browse files Browse the repository at this point in the history
  • Loading branch information
ANDREYDEN committed Apr 8, 2024
1 parent 2399a7d commit afe42d5
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:spare_parts/entities/custom_user.dart';
import 'package:spare_parts/pages/home_page/inventory_view/filters/available_items_filter.dart';
import 'package:spare_parts/pages/home_page/inventory_view/filters/item_type_filter.dart';
import 'package:spare_parts/pages/home_page/inventory_view/filters/user_filter.dart';
import 'package:spare_parts/utilities/constants.dart';

class InventoryViewFilters extends StatelessWidget {
final List<String> selectedItemTypes;
final List<String> selectedBorrowers;
final List<CustomUser> selectedBorrowers;
final bool showOnlyAvailableItems;
final void Function(List<String>) handleTypesFilterChanged;
final void Function(List<String>) handleBorrowersFilterChanged;
final void Function(List<CustomUser>) handleBorrowersFilterChanged;
final void Function() handleAvailableItemsFilterChanged;

const InventoryViewFilters({
Expand Down Expand Up @@ -39,7 +40,6 @@ class InventoryViewFilters extends StatelessWidget {
if (isAdmin) ...[
SizedBox(width: 10),
UserFilter(
icon: Icons.filter_list,
selectedUsers: selectedBorrowers,
onChanged: handleBorrowersFilterChanged,
),
Expand Down
58 changes: 14 additions & 44 deletions lib/pages/home_page/inventory_view/filters/user_filter.dart
Original file line number Diff line number Diff line change
@@ -1,65 +1,35 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:spare_parts/dtos/user_dto.dart';
import 'package:spare_parts/services/callable_service.dart';
import 'package:spare_parts/entities/custom_user.dart';
import 'package:spare_parts/widgets/dialogs/user_selection_dialog.dart';
import 'package:spare_parts/widgets/inputs/multiselect_button.dart';
import 'package:spare_parts/widgets/user_avatar.dart';

class UserFilter extends StatefulWidget {
final List<String> selectedUsers;
final void Function(List<String>) onChanged;
final IconData? icon;
final List<CustomUser> selectedUsers;
final void Function(List<CustomUser>) onChanged;

const UserFilter({
super.key,
required this.selectedUsers,
required this.onChanged,
this.icon,
});

@override
State<UserFilter> createState() => _UserFilterState();
}

class _UserFilterState extends State<UserFilter> {
late Future<List<UserDto>> _userQuery;

@override
void initState() {
final callableService = context.read<CallableService>();
_userQuery = callableService.getUsers();

super.initState();
}

@override
Widget build(BuildContext context) {
return FutureBuilder<List<UserDto>>(
future: _userQuery,
builder: (context, snap) {
if (!snap.hasData || snap.hasError) {
return SizedBox.square(
dimension: 20,
child: CircularProgressIndicator(strokeWidth: 3),
);
}

final users = snap.data!;

return MultiselectButton(
buttonLabel: 'Borrowers',
values: users.map((u) => u.id).toList(),
selectedValues: widget.selectedUsers,
onConfirm: widget.onChanged,
icon: widget.icon,
labelBuilder: (uid) =>
users.singleWhere((user) => user.id == uid).name,
leadingBuilder: (uid) {
final user = users.singleWhere((user) => user.id == uid);
return UserAvatar(photoUrl: user.photoUrl);
},
);
},
return MultiselectButton<CustomUser>(
buttonLabel: 'Borrowers',
values: [],
selectedValues: [],
onConfirm: widget.onChanged,
icon: Icons.filter_list,
dialog: UserSelectionDialog(
selectedUsers: widget.selectedUsers,
title: 'Pick Borrowers',
),
);
}
}
10 changes: 6 additions & 4 deletions lib/pages/home_page/inventory_view/inventory_view.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:spare_parts/entities/custom_user.dart';
import 'package:spare_parts/entities/inventory_item.dart';
import 'package:spare_parts/pages/home_page/inventory_view/filters/inventory_view_filters.dart';
import 'package:spare_parts/pages/home_page/inventory_view/inventory_view_list.dart';
Expand All @@ -17,7 +18,7 @@ class InventoryView extends StatefulWidget {

class _InventoryViewState extends State<InventoryView> {
List<String> _selectedItemTypes = [];
List<String> _selectedBorrowers = [];
List<CustomUser> _selectedBorrowers = [];
late bool _showOnlyAvailableItems;
bool _inSelectionMode = false;
int _itemsLimit = kItemsPerPage;
Expand All @@ -35,7 +36,7 @@ class _InventoryViewState extends State<InventoryView> {
setState(() => _selectedItemTypes = newTypes);
}

void _handleBorrowersFilterChanged(List<String> newBorrowers) {
void _handleBorrowersFilterChanged(List<CustomUser> newBorrowers) {
setState(() => _selectedBorrowers = newBorrowers);
}

Expand Down Expand Up @@ -76,8 +77,9 @@ class _InventoryViewState extends State<InventoryView> {
withNoBorrower: _showOnlyAvailableItems,
whereTypeIn:
_selectedItemTypes.isEmpty ? null : _selectedItemTypes,
whereBorrowerIn:
_selectedBorrowers.isEmpty ? null : _selectedBorrowers,
whereBorrowerIn: _selectedBorrowers.isEmpty
? null
: _selectedBorrowers.map((e) => e.uid).toList(),
excludePrivates: !isAdmin,
limit: _itemsLimit,
),
Expand Down
32 changes: 18 additions & 14 deletions lib/widgets/inputs/multiselect_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import 'package:flutter/material.dart';
import 'package:spare_parts/utilities/helpers.dart';
import 'package:spare_parts/widgets/dialogs/value_selection_dialog.dart';

class MultiselectButton extends StatelessWidget {
final List<String> values;
final List<String> selectedValues;
class MultiselectButton<T> extends StatelessWidget {
final List<T> values;
final List<T> selectedValues;
final String buttonLabel;
final void Function(List<String>) onConfirm;
final Widget Function(String value)? leadingBuilder;
final String Function(String value) labelBuilder;
final void Function(List<T>) onConfirm;
final Widget Function(T value)? leadingBuilder;
final String Function(T value) labelBuilder;
final IconData? icon;
final Widget? dialog;

const MultiselectButton({
super.key,
Expand All @@ -20,18 +21,21 @@ class MultiselectButton extends StatelessWidget {
this.labelBuilder = stringIdentity,
this.leadingBuilder,
this.icon,
this.dialog,
});

void _handleChangeSelection(BuildContext context) async {
final newSelectedValues = await showDialog<List<String>?>(
final newSelectedValues = await showDialog<List<T>?>(
context: context,
builder: (context) => ValueSelectionDialog(
title: 'Pick $buttonLabel',
values: values,
selectedValues: selectedValues,
leadingBuilder: leadingBuilder,
labelBuilder: labelBuilder,
),
builder: (context) =>
dialog ??
ValueSelectionDialog<T>(
title: 'Pick $buttonLabel',
values: values,
selectedValues: selectedValues,
leadingBuilder: leadingBuilder,
labelBuilder: labelBuilder,
),
);

if (newSelectedValues != null) {
Expand Down
10 changes: 2 additions & 8 deletions test/pages/home_page/inventory_view/inventory_view_test.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import 'package:fake_cloud_firestore/fake_cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:spare_parts/dtos/user_dto.dart';
import 'package:spare_parts/entities/custom_user.dart';
import 'package:spare_parts/entities/inventory_item.dart';
import 'package:spare_parts/factories/inventory_item_factory.dart';
import 'package:spare_parts/pages/home_page/home_page.dart';
import 'package:spare_parts/pages/home_page/inventory_view/inventory_view.dart';
import 'package:spare_parts/pages/item_page/item_page.dart';
import 'package:spare_parts/services/callable_service.mocks.dart';
import 'package:spare_parts/utilities/constants.dart';
import 'package:spare_parts/widgets/dialogs/user_selection_dialog.dart';
import 'package:spare_parts/widgets/inputs/new_user_input.dart';
Expand Down Expand Up @@ -659,10 +656,8 @@ void main() {
final user1 = CustomUser(uid: 'first', name: 'First');
final user2 = CustomUser(uid: 'second', name: 'Second');

final callableService = MockCallableService();
when(callableService.getUsers()).thenAnswer((_) => Future.value(
[user1, user2].map(UserDto.fromCustomUser).toList(),
));
firestore.collection('users').doc(user1.uid).set(user1.toFirestore());
firestore.collection('users').doc(user2.uid).set(user2.toFirestore());

final item1 = InventoryItemFactory().create(borrower: user1);
final item2 = InventoryItemFactory().create(borrower: user2);
Expand All @@ -675,7 +670,6 @@ void main() {
tester,
userRole: UserRole.admin,
firestore: firestore,
callableService: callableService,
);

await tester.tap(find.text('Borrowers'));
Expand Down

0 comments on commit afe42d5

Please sign in to comment.