diff --git a/lib/redux/product/product_actions.dart b/lib/redux/product/product_actions.dart index 6d733b380..a6040e2b0 100644 --- a/lib/redux/product/product_actions.dart +++ b/lib/redux/product/product_actions.dart @@ -86,3 +86,9 @@ class SortProducts { final String field; SortProducts(this.field); } + +class FilterProductsByState { + final EntityState state; + + FilterProductsByState(this.state); +} diff --git a/lib/redux/product/product_reducer.dart b/lib/redux/product/product_reducer.dart index 251035167..a9d527bfd 100644 --- a/lib/redux/product/product_reducer.dart +++ b/lib/redux/product/product_reducer.dart @@ -12,8 +12,21 @@ EntityUIState productUIReducer(EntityUIState state, action) { final productListReducer = combineReducers([ TypedReducer(_sortProducts), + TypedReducer(_filterProductsByState), ]); +ListUIState _filterProductsByState(ListUIState productListState, FilterProductsByState action) { + if (productListState.stateFilters.contains(action.state)) { + return productListState.rebuild((b) => b + ..stateFilters.remove(action.state) + ); + } else { + return productListState.rebuild((b) => b + ..stateFilters.add(action.state) + ); + } +} + ListUIState _sortProducts(ListUIState productListState, SortProducts action) { return productListState.rebuild((b) => b ..sortAscending = b.sortField != action.field || ! b.sortAscending diff --git a/lib/redux/ui/list_ui_state.dart b/lib/redux/ui/list_ui_state.dart index 8ef5d3c85..e4c49cecb 100644 --- a/lib/redux/ui/list_ui_state.dart +++ b/lib/redux/ui/list_ui_state.dart @@ -1,6 +1,7 @@ import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; +import 'package:invoiceninja/data/models/models.dart'; part 'list_ui_state.g.dart'; @@ -8,15 +9,15 @@ abstract class ListUIState implements Built { String get sortField; bool get sortAscending; - BuiltList get stateFilterIds; - BuiltList get statusFilterIds; + BuiltList get stateFilters; + BuiltList get statusFilters; factory ListUIState(sortField) { return _$ListUIState._( sortField: sortField, sortAscending: true, - stateFilterIds: BuiltList(), - statusFilterIds: BuiltList(), + stateFilters: BuiltList(), + statusFilters: BuiltList(), ); } diff --git a/lib/redux/ui/list_ui_state.g.dart b/lib/redux/ui/list_ui_state.g.dart index 6cdffca0b..78e357cca 100644 --- a/lib/redux/ui/list_ui_state.g.dart +++ b/lib/redux/ui/list_ui_state.g.dart @@ -32,12 +32,12 @@ class _$ListUIStateSerializer implements StructuredSerializer { 'sortAscending', serializers.serialize(object.sortAscending, specifiedType: const FullType(bool)), - 'stateFilterIds', - serializers.serialize(object.stateFilterIds, + 'stateFilters', + serializers.serialize(object.stateFilters, specifiedType: - const FullType(BuiltList, const [const FullType(int)])), - 'statusFilterIds', - serializers.serialize(object.statusFilterIds, + const FullType(BuiltList, const [const FullType(EntityState)])), + 'statusFilters', + serializers.serialize(object.statusFilters, specifiedType: const FullType(BuiltList, const [const FullType(int)])), ]; @@ -64,14 +64,14 @@ class _$ListUIStateSerializer implements StructuredSerializer { result.sortAscending = serializers.deserialize(value, specifiedType: const FullType(bool)) as bool; break; - case 'stateFilterIds': - result.stateFilterIds.replace(serializers.deserialize(value, - specifiedType: - const FullType(BuiltList, const [const FullType(int)])) + case 'stateFilters': + result.stateFilters.replace(serializers.deserialize(value, + specifiedType: const FullType( + BuiltList, const [const FullType(EntityState)])) as BuiltList); break; - case 'statusFilterIds': - result.statusFilterIds.replace(serializers.deserialize(value, + case 'statusFilters': + result.statusFilters.replace(serializers.deserialize(value, specifiedType: const FullType(BuiltList, const [const FullType(int)])) as BuiltList); @@ -89,9 +89,9 @@ class _$ListUIState extends ListUIState { @override final bool sortAscending; @override - final BuiltList stateFilterIds; + final BuiltList stateFilters; @override - final BuiltList statusFilterIds; + final BuiltList statusFilters; factory _$ListUIState([void updates(ListUIStateBuilder b)]) => (new ListUIStateBuilder()..update(updates)).build(); @@ -99,17 +99,17 @@ class _$ListUIState extends ListUIState { _$ListUIState._( {this.sortField, this.sortAscending, - this.stateFilterIds, - this.statusFilterIds}) + this.stateFilters, + this.statusFilters}) : super._() { if (sortField == null) throw new BuiltValueNullFieldError('ListUIState', 'sortField'); if (sortAscending == null) throw new BuiltValueNullFieldError('ListUIState', 'sortAscending'); - if (stateFilterIds == null) - throw new BuiltValueNullFieldError('ListUIState', 'stateFilterIds'); - if (statusFilterIds == null) - throw new BuiltValueNullFieldError('ListUIState', 'statusFilterIds'); + if (stateFilters == null) + throw new BuiltValueNullFieldError('ListUIState', 'stateFilters'); + if (statusFilters == null) + throw new BuiltValueNullFieldError('ListUIState', 'statusFilters'); } @override @@ -125,16 +125,16 @@ class _$ListUIState extends ListUIState { if (other is! ListUIState) return false; return sortField == other.sortField && sortAscending == other.sortAscending && - stateFilterIds == other.stateFilterIds && - statusFilterIds == other.statusFilterIds; + stateFilters == other.stateFilters && + statusFilters == other.statusFilters; } @override int get hashCode { return $jf($jc( $jc($jc($jc(0, sortField.hashCode), sortAscending.hashCode), - stateFilterIds.hashCode), - statusFilterIds.hashCode)); + stateFilters.hashCode), + statusFilters.hashCode)); } @override @@ -142,8 +142,8 @@ class _$ListUIState extends ListUIState { return (newBuiltValueToStringHelper('ListUIState') ..add('sortField', sortField) ..add('sortAscending', sortAscending) - ..add('stateFilterIds', stateFilterIds) - ..add('statusFilterIds', statusFilterIds)) + ..add('stateFilters', stateFilters) + ..add('statusFilters', statusFilters)) .toString(); } } @@ -160,17 +160,17 @@ class ListUIStateBuilder implements Builder { set sortAscending(bool sortAscending) => _$this._sortAscending = sortAscending; - ListBuilder _stateFilterIds; - ListBuilder get stateFilterIds => - _$this._stateFilterIds ??= new ListBuilder(); - set stateFilterIds(ListBuilder stateFilterIds) => - _$this._stateFilterIds = stateFilterIds; + ListBuilder _stateFilters; + ListBuilder get stateFilters => + _$this._stateFilters ??= new ListBuilder(); + set stateFilters(ListBuilder stateFilters) => + _$this._stateFilters = stateFilters; - ListBuilder _statusFilterIds; - ListBuilder get statusFilterIds => - _$this._statusFilterIds ??= new ListBuilder(); - set statusFilterIds(ListBuilder statusFilterIds) => - _$this._statusFilterIds = statusFilterIds; + ListBuilder _statusFilters; + ListBuilder get statusFilters => + _$this._statusFilters ??= new ListBuilder(); + set statusFilters(ListBuilder statusFilters) => + _$this._statusFilters = statusFilters; ListUIStateBuilder(); @@ -178,8 +178,8 @@ class ListUIStateBuilder implements Builder { if (_$v != null) { _sortField = _$v.sortField; _sortAscending = _$v.sortAscending; - _stateFilterIds = _$v.stateFilterIds?.toBuilder(); - _statusFilterIds = _$v.statusFilterIds?.toBuilder(); + _stateFilters = _$v.stateFilters?.toBuilder(); + _statusFilters = _$v.statusFilters?.toBuilder(); _$v = null; } return this; @@ -204,15 +204,15 @@ class ListUIStateBuilder implements Builder { new _$ListUIState._( sortField: sortField, sortAscending: sortAscending, - stateFilterIds: stateFilterIds.build(), - statusFilterIds: statusFilterIds.build()); + stateFilters: stateFilters.build(), + statusFilters: statusFilters.build()); } catch (_) { String _$failedField; try { - _$failedField = 'stateFilterIds'; - stateFilterIds.build(); - _$failedField = 'statusFilterIds'; - statusFilterIds.build(); + _$failedField = 'stateFilters'; + stateFilters.build(); + _$failedField = 'statusFilters'; + statusFilters.build(); } catch (e) { throw new BuiltValueNestedFieldError( 'ListUIState', _$failedField, e.toString()); diff --git a/lib/ui/app/app_bottom_bar.dart b/lib/ui/app/app_bottom_bar.dart index d58daea75..23d5b45f2 100644 --- a/lib/ui/app/app_bottom_bar.dart +++ b/lib/ui/app/app_bottom_bar.dart @@ -1,3 +1,4 @@ +import 'package:built_collection/built_collection.dart'; import 'package:flutter/material.dart'; import 'package:invoiceninja/utils/localization.dart'; import 'package:invoiceninja/data/models/models.dart'; @@ -10,10 +11,10 @@ class AppBottomBar extends StatefulWidget { final String selectedSortField; final bool selectedSortAscending; - final List selectStatusIds; - final List selectStateIds; - final Function(List) onSelectedStatusIds; - final Function(List) onSelectedStateIds; + final BuiltList selectedStatuses; + final BuiltList selectedStates; + final Function(List) onSelectedStatus; + final Function(EntityState, bool) onSelectedState; AppBottomBar( {this.scaffoldKey, @@ -21,10 +22,10 @@ class AppBottomBar extends StatefulWidget { this.onSelectedSortField, this.selectedSortField, this.selectedSortAscending, - this.selectStateIds, - this.selectStatusIds, - this.onSelectedStateIds, - this.onSelectedStatusIds}); + this.selectedStates, + this.selectedStatuses, + this.onSelectedState, + this.onSelectedStatus}); @override _AppBottomBarState createState() => new _AppBottomBarState(); @@ -51,10 +52,10 @@ class _AppBottomBarState extends State { return CheckboxListTile( title: Text(AppLocalization.of(context).lookup(state.toString())), controlAffinity: ListTileControlAffinity.leading, - value: true, + value: widget.selectedStates.contains(state), dense: true, onChanged: (value) { - + widget.onSelectedState(state, value); }, ); }).toList(), diff --git a/lib/ui/product/product_screen.dart b/lib/ui/product/product_screen.dart index 53f0d797b..6b5bfec89 100644 --- a/lib/ui/product/product_screen.dart +++ b/lib/ui/product/product_screen.dart @@ -56,6 +56,10 @@ class ProductScreen extends StatelessWidget { ProductFields.productKey, ProductFields.cost, ], + selectedStates: StoreProvider.of(context).state.productListState().stateFilters, + onSelectedState: (EntityState state, value) { + StoreProvider.of(context).dispatch(FilterProductsByState(state)); + }, ), floatingActionButtonLocation: FloatingActionButtonLocation.endDocked, floatingActionButton: StoreConnector(