Search/filter refactor

This commit is contained in:
unknown 2018-08-01 20:04:06 +03:00
parent eb39ed55b5
commit 9615f72964
37 changed files with 227 additions and 228 deletions

View File

@ -243,50 +243,50 @@ abstract class ClientEntity extends Object
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (displayName.toLowerCase().contains(search)) { if (displayName.toLowerCase().contains(filter)) {
return true; return true;
} }
if (vatNumber.toLowerCase().contains(search)) { if (vatNumber.toLowerCase().contains(filter)) {
return true; return true;
} }
if (idNumber.toLowerCase().contains(search)) { if (idNumber.toLowerCase().contains(filter)) {
return true; return true;
} }
if (workPhone.toLowerCase().contains(search)) { if (workPhone.toLowerCase().contains(filter)) {
return true; return true;
} }
if (contacts.where((contact) => contact.matchesSearch(search)).isNotEmpty) { if (contacts.where((contact) => contact.matchesFilter(filter)).isNotEmpty) {
return true; return true;
} }
return false; return false;
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (vatNumber.toLowerCase().contains(search)) { if (vatNumber.toLowerCase().contains(filter)) {
return vatNumber; return vatNumber;
} }
if (idNumber.toLowerCase().contains(search)) { if (idNumber.toLowerCase().contains(filter)) {
return idNumber; return idNumber;
} }
if (workPhone.toLowerCase().contains(search)) { if (workPhone.toLowerCase().contains(filter)) {
return workPhone; return workPhone;
} }
final contact = contacts.firstWhere( final contact = contacts.firstWhere(
(contact) => contact.matchesSearch(search), (contact) => contact.matchesFilter(filter),
orElse: () => null); orElse: () => null);
if (contact != null) { if (contact != null) {
return contact.matchesSearchValue(search); return contact.matchesFilterValue(filter);
} }
return null; return null;
@ -375,38 +375,38 @@ abstract class ContactEntity extends Object
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (firstName.toLowerCase().contains(search)) { if (firstName.toLowerCase().contains(filter)) {
return true; return true;
} }
if (lastName.toLowerCase().contains(search)) { if (lastName.toLowerCase().contains(filter)) {
return true; return true;
} }
if (phone.toLowerCase().contains(search)) { if (phone.toLowerCase().contains(filter)) {
return true; return true;
} }
if (email.toLowerCase().contains(search)) { if (email.toLowerCase().contains(filter)) {
return true; return true;
} }
return false; return false;
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (fullName.toLowerCase().contains(search)) { if (fullName.toLowerCase().contains(filter)) {
return fullName; return fullName;
} else if (email.toLowerCase().contains(search)) { } else if (email.toLowerCase().contains(filter)) {
return email; return email;
} else if (phone.toLowerCase().contains(search)) { } else if (phone.toLowerCase().contains(filter)) {
return phone; return phone;
} }

View File

@ -100,17 +100,17 @@ abstract class CreditEntity extends Object with BaseEntity implements Built<Cred
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
return publicNotes.contains(search); return publicNotes.contains(filter);
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }

View File

@ -61,8 +61,8 @@ abstract class SelectableEntity {
@nullable @nullable
int get id; int get id;
bool matchesSearch(String search) => true; bool matchesFilter(String filter) => true;
String matchesSearchValue(String search) => null; String matchesFilterValue(String filter) => null;
String get listDisplayName => 'Error: listDisplayName not set'; String get listDisplayName => 'Error: listDisplayName not set';

View File

@ -176,17 +176,17 @@ abstract class ExpenseEntity extends Object
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
return privateNotes.contains(search); return privateNotes.contains(filter);
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
@ -216,8 +216,8 @@ abstract class ExpenseCategoryEntity extends Object
ExpenseCategoryEntity._(); ExpenseCategoryEntity._();
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
@ -225,8 +225,8 @@ abstract class ExpenseCategoryEntity extends Object
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }

View File

@ -293,18 +293,18 @@ abstract class InvoiceEntity extends Object
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
if (invoiceNumber.toLowerCase().contains(search)) { if (invoiceNumber.toLowerCase().contains(filter)) {
return true; return true;
} else if (customTextValue1.isNotEmpty && } else if (customTextValue1.isNotEmpty &&
customTextValue1.toLowerCase().contains(search)) { customTextValue1.toLowerCase().contains(filter)) {
return true; return true;
} else if (customTextValue2.isNotEmpty && } else if (customTextValue2.isNotEmpty &&
customTextValue2.toLowerCase().contains(search)) { customTextValue2.toLowerCase().contains(filter)) {
return true; return true;
} }
@ -312,19 +312,19 @@ abstract class InvoiceEntity extends Object
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (invoiceNumber.toLowerCase().contains(search)) { if (invoiceNumber.toLowerCase().contains(filter)) {
return invoiceNumber; return invoiceNumber;
} else if (customTextValue1.isNotEmpty && } else if (customTextValue1.isNotEmpty &&
customTextValue1.toLowerCase().contains(search)) { customTextValue1.toLowerCase().contains(filter)) {
return customTextValue1; return customTextValue1;
} else if (customTextValue2.isNotEmpty && } else if (customTextValue2.isNotEmpty &&
customTextValue2.toLowerCase().contains(search)) { customTextValue2.toLowerCase().contains(filter)) {
return customTextValue2; return customTextValue2;
} }
return null; return null;
@ -427,8 +427,8 @@ abstract class InvoiceItemEntity extends Object
double get total => qty * cost; double get total => qty * cost;
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
@ -436,8 +436,8 @@ abstract class InvoiceItemEntity extends Object
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
@ -491,8 +491,8 @@ abstract class InvitationEntity extends Object
String get downloadLink => link.replaceFirst('/view/', '/download/'); String get downloadLink => link.replaceFirst('/view/', '/download/');
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
@ -500,8 +500,8 @@ abstract class InvitationEntity extends Object
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }

View File

@ -111,17 +111,17 @@ abstract class PaymentEntity extends Object with BaseEntity implements Built<Pay
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
return privateNotes.contains(search); return privateNotes.contains(filter);
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }

View File

@ -146,22 +146,22 @@ abstract class ProductEntity extends Object
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (productKey.toLowerCase().contains(search)) { if (productKey.toLowerCase().contains(filter)) {
return true; return true;
} else if (notes.toLowerCase().contains(search)) { } else if (notes.toLowerCase().contains(filter)) {
return true; return true;
} else if (customValue1.isNotEmpty && } else if (customValue1.isNotEmpty &&
customValue1.toLowerCase().contains(search)) { customValue1.toLowerCase().contains(filter)) {
return true; return true;
} else if (customValue2.isNotEmpty && } else if (customValue2.isNotEmpty &&
customValue2.toLowerCase().contains(search)) { customValue2.toLowerCase().contains(filter)) {
return true; return true;
} }
@ -169,19 +169,19 @@ abstract class ProductEntity extends Object
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (notes.toLowerCase().contains(search)) { if (notes.toLowerCase().contains(filter)) {
return notes; return notes;
} else if (customValue1.isNotEmpty && } else if (customValue1.isNotEmpty &&
customValue1.toLowerCase().contains(search)) { customValue1.toLowerCase().contains(filter)) {
return customValue1; return customValue1;
} else if (customValue2.isNotEmpty && } else if (customValue2.isNotEmpty &&
customValue2.toLowerCase().contains(search)) { customValue2.toLowerCase().contains(filter)) {
return customValue2; return customValue2;
} }
return null; return null;

View File

@ -109,17 +109,17 @@ abstract class ProjectEntity extends Object with BaseEntity implements Built<Pro
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
return name.contains(search); return name.contains(filter);
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }

View File

@ -141,18 +141,18 @@ abstract class CountryEntity extends Object with SelectableEntity implements Bui
*/ */
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (name.toLowerCase().contains(search)) { if (name.toLowerCase().contains(filter)) {
return true; return true;
} else if (iso2.toLowerCase().contains(search)) { } else if (iso2.toLowerCase().contains(filter)) {
return true; return true;
} else if (iso3.toLowerCase().contains(search)) { } else if (iso3.toLowerCase().contains(filter)) {
return true; return true;
} }
@ -160,16 +160,16 @@ abstract class CountryEntity extends Object with SelectableEntity implements Bui
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (iso2.toLowerCase().contains(search)) { if (iso2.toLowerCase().contains(filter)) {
return iso2; return iso2;
} else if (iso3.toLowerCase().contains(search)) { } else if (iso3.toLowerCase().contains(filter)) {
return iso3; return iso3;
} }

View File

@ -76,16 +76,16 @@ abstract class CurrencyEntity extends Object with SelectableEntity implements Bu
double get exchangeRate; double get exchangeRate;
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (name.toLowerCase().contains(search)) { if (name.toLowerCase().contains(filter)) {
return true; return true;
} else if (code.toLowerCase().contains(search)) { } else if (code.toLowerCase().contains(filter)) {
return true; return true;
} }
@ -93,14 +93,14 @@ abstract class CurrencyEntity extends Object with SelectableEntity implements Bu
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (code.toLowerCase().contains(search)) { if (code.toLowerCase().contains(filter)) {
return code; return code;
} }

View File

@ -46,16 +46,16 @@ abstract class LanguageEntity extends Object with SelectableEntity implements Bu
String get locale; String get locale;
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (name.toLowerCase().contains(search)) { if (name.toLowerCase().contains(filter)) {
return true; return true;
} else if (locale.toLowerCase().contains(search)) { } else if (locale.toLowerCase().contains(filter)) {
return true; return true;
} }
@ -63,14 +63,14 @@ abstract class LanguageEntity extends Object with SelectableEntity implements Bu
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
search = search.toLowerCase(); filter = filter.toLowerCase();
if (locale.toLowerCase().contains(search)) { if (locale.toLowerCase().contains(filter)) {
return locale; return locale;
} }

View File

@ -114,17 +114,17 @@ abstract class TaskEntity extends Object with BaseEntity implements Built<TaskEn
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
return description.contains(search); return description.contains(filter);
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }

View File

@ -155,17 +155,17 @@ abstract class VendorEntity extends Object with BaseEntity implements Built<Vend
} }
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
return name.contains(search); return name.contains(filter);
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }
@ -219,8 +219,8 @@ abstract class VendorContactEntity extends Object with BaseEntity implements Bui
String get phone; String get phone;
@override @override
bool matchesSearch(String search) { bool matchesFilter(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return true; return true;
} }
@ -228,8 +228,8 @@ abstract class VendorContactEntity extends Object with BaseEntity implements Bui
} }
@override @override
String matchesSearchValue(String search) { String matchesFilterValue(String filter) {
if (search == null || search.isEmpty) { if (filter == null || filter.isEmpty) {
return null; return null;
} }

View File

@ -185,9 +185,9 @@ class RestoreClientFailure implements StopSaving {
class SearchClients { class FilterClients {
final String search; final String filter;
SearchClients(this.search); FilterClients(this.filter);
} }
class SortClients implements PersistUI { class SortClients implements PersistUI {

View File

@ -72,7 +72,7 @@ ClientEntity _updateContact(ClientEntity client, UpdateContact action) {
final clientListReducer = combineReducers<ListUIState>([ final clientListReducer = combineReducers<ListUIState>([
TypedReducer<ListUIState, SortClients>(_sortClients), TypedReducer<ListUIState, SortClients>(_sortClients),
TypedReducer<ListUIState, FilterClientsByState>(_filterClientsByState), TypedReducer<ListUIState, FilterClientsByState>(_filterClientsByState),
TypedReducer<ListUIState, SearchClients>(_searchClients), TypedReducer<ListUIState, FilterClients>(_filterClients),
]); ]);
ListUIState _filterClientsByState(ListUIState clientListState, FilterClientsByState action) { ListUIState _filterClientsByState(ListUIState clientListState, FilterClientsByState action) {
@ -87,9 +87,9 @@ ListUIState _filterClientsByState(ListUIState clientListState, FilterClientsBySt
} }
} }
ListUIState _searchClients(ListUIState clientListState, SearchClients action) { ListUIState _filterClients(ListUIState clientListState, FilterClients action) {
return clientListState.rebuild((b) => b return clientListState.rebuild((b) => b
..search = action.search ..filter = action.filter
); );
} }

View File

@ -32,7 +32,7 @@ List<int> filteredClientsSelector(BuiltMap<int, ClientEntity> clientMap,
if (!client.matchesStates(clientListState.stateFilters)) { if (!client.matchesStates(clientListState.stateFilters)) {
return false; return false;
} }
return client.matchesSearch(clientListState.search); return client.matchesFilter(clientListState.filter);
}).toList(); }).toList();
list.sort((clientAId, clientBId) { list.sort((clientAId, clientBId) {

View File

@ -219,10 +219,9 @@ class RestoreInvoiceFailure implements StopSaving {
class FilterInvoices {
class SearchInvoices { final String filter;
final String search; FilterInvoices(this.filter);
SearchInvoices(this.search);
} }
class SortInvoices implements PersistUI { class SortInvoices implements PersistUI {

View File

@ -90,7 +90,7 @@ final invoiceListReducer = combineReducers<ListUIState>([
TypedReducer<ListUIState, FilterInvoicesByState>(_filterInvoicesByState), TypedReducer<ListUIState, FilterInvoicesByState>(_filterInvoicesByState),
TypedReducer<ListUIState, FilterInvoicesByStatus>(_filterInvoicesByStatus), TypedReducer<ListUIState, FilterInvoicesByStatus>(_filterInvoicesByStatus),
TypedReducer<ListUIState, FilterInvoicesByClient>(_filterInvoicesByClient), TypedReducer<ListUIState, FilterInvoicesByClient>(_filterInvoicesByClient),
TypedReducer<ListUIState, SearchInvoices>(_searchInvoices), TypedReducer<ListUIState, FilterInvoices>(_filterInvoices),
]); ]);
ListUIState _filterInvoicesByState(ListUIState invoiceListState, FilterInvoicesByState action) { ListUIState _filterInvoicesByState(ListUIState invoiceListState, FilterInvoicesByState action) {
@ -123,9 +123,9 @@ ListUIState _filterInvoicesByClient(ListUIState invoiceListState, FilterInvoices
); );
} }
ListUIState _searchInvoices(ListUIState invoiceListState, SearchInvoices action) { ListUIState _filterInvoices(ListUIState invoiceListState, FilterInvoices action) {
return invoiceListState.rebuild((b) => b return invoiceListState.rebuild((b) => b
..search = action.search ..filter = action.filter
); );
} }

View File

@ -32,7 +32,7 @@ List<int> filteredInvoicesSelector(
if (!invoice.matchesStatuses(invoiceListState.statusFilters)) { if (!invoice.matchesStatuses(invoiceListState.statusFilters)) {
return false; return false;
} }
if (!invoice.matchesSearch(invoiceListState.search)) { if (!invoice.matchesFilter(invoiceListState.filter)) {
return false; return false;
} }
if (invoiceListState.filterClientId != null && if (invoiceListState.filterClientId != null &&

View File

@ -123,9 +123,9 @@ class RestoreProductFailure implements StopSaving {
} }
class SearchProducts { class FilterProducts {
final String search; final String filter;
SearchProducts(this.search); FilterProducts(this.filter);
} }
class SortProducts implements PersistUI { class SortProducts implements PersistUI {

View File

@ -43,7 +43,7 @@ ProductEntity _updateEditing(ProductEntity client, dynamic action) {
final productListReducer = combineReducers<ListUIState>([ final productListReducer = combineReducers<ListUIState>([
TypedReducer<ListUIState, SortProducts>(_sortProducts), TypedReducer<ListUIState, SortProducts>(_sortProducts),
TypedReducer<ListUIState, FilterProductsByState>(_filterProductsByState), TypedReducer<ListUIState, FilterProductsByState>(_filterProductsByState),
TypedReducer<ListUIState, SearchProducts>(_searchProducts), TypedReducer<ListUIState, FilterProducts>(_filterProducts),
]); ]);
ListUIState _filterProductsByState(ListUIState productListState, FilterProductsByState action) { ListUIState _filterProductsByState(ListUIState productListState, FilterProductsByState action) {
@ -58,9 +58,9 @@ ListUIState _filterProductsByState(ListUIState productListState, FilterProductsB
} }
} }
ListUIState _searchProducts(ListUIState productListState, SearchProducts action) { ListUIState _filterProducts(ListUIState productListState, FilterProducts action) {
return productListState.rebuild((b) => b return productListState.rebuild((b) => b
..search = action.search ..filter = action.filter
); );
} }

View File

@ -31,7 +31,7 @@ List<int> filteredProductsSelector(
if (! product.matchesStates(productListState.stateFilters)) { if (! product.matchesStates(productListState.stateFilters)) {
return false; return false;
} }
if (! product.matchesSearch(productListState.search)) { if (! product.matchesFilter(productListState.filter)) {
return false; return false;
} }
return true; return true;

View File

@ -20,7 +20,7 @@ abstract class ListUIState implements Built<ListUIState, ListUIStateBuilder> {
ListUIState._(); ListUIState._();
@nullable @nullable
String get search; String get filter;
@nullable @nullable
int get filterClientId; int get filterClientId;

View File

@ -41,10 +41,10 @@ class _$ListUIStateSerializer implements StructuredSerializer<ListUIState> {
specifiedType: specifiedType:
const FullType(BuiltList, const [const FullType(EntityStatus)])), const FullType(BuiltList, const [const FullType(EntityStatus)])),
]; ];
if (object.search != null) { if (object.filter != null) {
result result
..add('search') ..add('filter')
..add(serializers.serialize(object.search, ..add(serializers.serialize(object.filter,
specifiedType: const FullType(String))); specifiedType: const FullType(String)));
} }
if (object.filterClientId != null) { if (object.filterClientId != null) {
@ -68,8 +68,8 @@ class _$ListUIStateSerializer implements StructuredSerializer<ListUIState> {
iterator.moveNext(); iterator.moveNext();
final dynamic value = iterator.current; final dynamic value = iterator.current;
switch (key) { switch (key) {
case 'search': case 'filter':
result.search = serializers.deserialize(value, result.filter = serializers.deserialize(value,
specifiedType: const FullType(String)) as String; specifiedType: const FullType(String)) as String;
break; break;
case 'filterClientId': case 'filterClientId':
@ -105,7 +105,7 @@ class _$ListUIStateSerializer implements StructuredSerializer<ListUIState> {
class _$ListUIState extends ListUIState { class _$ListUIState extends ListUIState {
@override @override
final String search; final String filter;
@override @override
final int filterClientId; final int filterClientId;
@override @override
@ -121,7 +121,7 @@ class _$ListUIState extends ListUIState {
(new ListUIStateBuilder()..update(updates)).build(); (new ListUIStateBuilder()..update(updates)).build();
_$ListUIState._( _$ListUIState._(
{this.search, {this.filter,
this.filterClientId, this.filterClientId,
this.sortField, this.sortField,
this.sortAscending, this.sortAscending,
@ -149,7 +149,7 @@ class _$ListUIState extends ListUIState {
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(other, this)) return true; if (identical(other, this)) return true;
if (other is! ListUIState) return false; if (other is! ListUIState) return false;
return search == other.search && return filter == other.filter &&
filterClientId == other.filterClientId && filterClientId == other.filterClientId &&
sortField == other.sortField && sortField == other.sortField &&
sortAscending == other.sortAscending && sortAscending == other.sortAscending &&
@ -162,7 +162,7 @@ class _$ListUIState extends ListUIState {
return $jf($jc( return $jf($jc(
$jc( $jc(
$jc( $jc(
$jc($jc($jc(0, search.hashCode), filterClientId.hashCode), $jc($jc($jc(0, filter.hashCode), filterClientId.hashCode),
sortField.hashCode), sortField.hashCode),
sortAscending.hashCode), sortAscending.hashCode),
stateFilters.hashCode), stateFilters.hashCode),
@ -172,7 +172,7 @@ class _$ListUIState extends ListUIState {
@override @override
String toString() { String toString() {
return (newBuiltValueToStringHelper('ListUIState') return (newBuiltValueToStringHelper('ListUIState')
..add('search', search) ..add('filter', filter)
..add('filterClientId', filterClientId) ..add('filterClientId', filterClientId)
..add('sortField', sortField) ..add('sortField', sortField)
..add('sortAscending', sortAscending) ..add('sortAscending', sortAscending)
@ -185,9 +185,9 @@ class _$ListUIState extends ListUIState {
class ListUIStateBuilder implements Builder<ListUIState, ListUIStateBuilder> { class ListUIStateBuilder implements Builder<ListUIState, ListUIStateBuilder> {
_$ListUIState _$v; _$ListUIState _$v;
String _search; String _filter;
String get search => _$this._search; String get filter => _$this._filter;
set search(String search) => _$this._search = search; set filter(String filter) => _$this._filter = filter;
int _filterClientId; int _filterClientId;
int get filterClientId => _$this._filterClientId; int get filterClientId => _$this._filterClientId;
@ -219,7 +219,7 @@ class ListUIStateBuilder implements Builder<ListUIState, ListUIStateBuilder> {
ListUIStateBuilder get _$this { ListUIStateBuilder get _$this {
if (_$v != null) { if (_$v != null) {
_search = _$v.search; _filter = _$v.filter;
_filterClientId = _$v.filterClientId; _filterClientId = _$v.filterClientId;
_sortField = _$v.sortField; _sortField = _$v.sortField;
_sortAscending = _$v.sortAscending; _sortAscending = _$v.sortAscending;
@ -247,7 +247,7 @@ class ListUIStateBuilder implements Builder<ListUIState, ListUIStateBuilder> {
try { try {
_$result = _$v ?? _$result = _$v ??
new _$ListUIState._( new _$ListUIState._(
search: search, filter: filter,
filterClientId: filterClientId, filterClientId: filterClientId,
sortField: sortField, sortField: sortField,
sortAscending: sortAscending, sortAscending: sortAscending,

View File

@ -155,7 +155,7 @@ class _EntityDropdownDialogState extends State<EntityDropdownDialog> {
Widget _createList() { Widget _createList() {
final matches = widget.entityList final matches = widget.entityList
.where( .where(
(entityId) => widget.entityMap[entityId].matchesSearch(_filter)) (entityId) => widget.entityMap[entityId].matchesFilter(_filter))
.toList(); .toList();
return ListView.builder( return ListView.builder(
@ -164,7 +164,7 @@ class _EntityDropdownDialogState extends State<EntityDropdownDialog> {
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
final int entityId = matches[index]; final int entityId = matches[index];
final entity = widget.entityMap[entityId]; final entity = widget.entityMap[entityId];
final String subtitle = entity.matchesSearchValue(_filter); final String subtitle = entity.matchesFilterValue(_filter);
return ListTile( return ListTile(
dense: true, dense: true,
title: Row( title: Row(

View File

@ -5,15 +5,15 @@ import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
class AppSearch extends StatelessWidget { class ListFilter extends StatelessWidget {
final EntityType entityType; final EntityType entityType;
final String search; final String filter;
final Function(String) onSearchChanged; final Function(String) onFilterChanged;
const AppSearch({ const ListFilter({
this.entityType, this.entityType,
this.search, this.filter,
this.onSearchChanged, this.onFilterChanged,
}); });
@override @override
@ -25,15 +25,15 @@ class AppSearch extends StatelessWidget {
builder: (BuildContext context, state) { builder: (BuildContext context, state) {
final listUIState = state.getListState(entityType); final listUIState = state.getListState(entityType);
final bool enableDarkMode = state.uiState.enableDarkMode; final bool enableDarkMode = state.uiState.enableDarkMode;
return listUIState.search == null return listUIState.filter == null
? Text(localization.lookup(entityType.plural.toString())) ? Text(localization.lookup(entityType.plural.toString()))
: Container( : Container(
padding: const EdgeInsets.only(left: 8.0), padding: const EdgeInsets.only(left: 8.0),
height: 38.0, height: 38.0,
margin: EdgeInsets.only(bottom: 2.0), margin: EdgeInsets.only(bottom: 2.0),
decoration: BoxDecoration( decoration: BoxDecoration(
color: listUIState.search != null && color: listUIState.filter != null &&
listUIState.search.isNotEmpty listUIState.filter.isNotEmpty
? enableDarkMode ? enableDarkMode
? Colors.yellow.shade900 ? Colors.yellow.shade900
: Colors.yellow.shade200 : Colors.yellow.shade200
@ -51,10 +51,10 @@ class AppSearch extends StatelessWidget {
child: Icon(Icons.search), child: Icon(Icons.search),
), ),
border: InputBorder.none, border: InputBorder.none,
hintText: localization.search), hintText: localization.filter),
autofocus: true, autofocus: true,
autocorrect: false, autocorrect: false,
onChanged: (value) => onSearchChanged(value), onChanged: (value) => onFilterChanged(value),
), ),
); );
}, },

View File

@ -6,14 +6,14 @@ import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class AppSearchButton extends StatelessWidget { class ListFilterButton extends StatelessWidget {
final EntityType entityType; final EntityType entityType;
final Function onSearchPressed; final Function onFilterPressed;
const AppSearchButton({ const ListFilterButton({
this.entityType, this.entityType,
this.onSearchPressed, this.onFilterPressed,
}); });
@override @override
@ -26,9 +26,9 @@ class AppSearchButton extends StatelessWidget {
distinct: true, distinct: true,
builder: (BuildContext context, listUIState) { builder: (BuildContext context, listUIState) {
return IconButton( return IconButton(
icon: Icon(listUIState.search == null ? Icons.search : Icons.close), icon: Icon(listUIState.filter == null ? Icons.search : Icons.close),
tooltip: localization.search, tooltip: localization.filter,
onPressed: () => onSearchPressed(listUIState.search == null ? '' : null), onPressed: () => onFilterPressed(listUIState.filter == null ? '' : null),
); );
}, },
); );

View File

@ -25,8 +25,8 @@ class ClientListItem extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
//var localization = AppLocalization.of(context); //var localization = AppLocalization.of(context);
final searchMatch = filter != null && filter.isNotEmpty final filterMatch = filter != null && filter.isNotEmpty
? client.matchesSearchValue(filter) ? client.matchesFilterValue(filter)
: null; : null;
return DismissibleEntity( return DismissibleEntity(
@ -50,10 +50,10 @@ class ClientListItem extends StatelessWidget {
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
searchMatch == null filterMatch == null
? Container() ? Container()
: Text( : Text(
searchMatch, filterMatch,
maxLines: 3, maxLines: 3,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),

View File

@ -69,7 +69,7 @@ class ClientListVM {
clientMap: store.state.clientState.map, clientMap: store.state.clientState.map,
isLoading: store.state.isLoading, isLoading: store.state.isLoading,
isLoaded: store.state.clientState.isLoaded, isLoaded: store.state.clientState.isLoaded,
filter: store.state.clientListState.search, filter: store.state.clientListState.filter,
onClientTap: (context, client) { onClientTap: (context, client) {
store.dispatch(ViewClient(clientId: client.id, context: context)); store.dispatch(ViewClient(clientId: client.id, context: context));
}, },

View File

@ -1,5 +1,5 @@
import 'package:invoiceninja_flutter/ui/app/app_search.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
import 'package:invoiceninja_flutter/ui/app/app_search_button.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -20,17 +20,17 @@ class ClientScreen extends StatelessWidget {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: AppSearch( title: ListFilter(
entityType: EntityType.client, entityType: EntityType.client,
onSearchChanged: (value) { onFilterChanged: (value) {
store.dispatch(SearchClients(value)); store.dispatch(FilterClients(value));
}, },
), ),
actions: [ actions: [
AppSearchButton( ListFilterButton(
entityType: EntityType.client, entityType: EntityType.client,
onSearchPressed: (String value) { onFilterPressed: (String value) {
store.dispatch(SearchClients(value)); store.dispatch(FilterClients(value));
}, },
), ),
], ],

View File

@ -138,7 +138,7 @@ class _InvoiceItemSelectorState extends State<InvoiceItemSelector> {
Widget _entityList() { Widget _entityList() {
final matches = memoizedProductList(widget.productMap).where((entityId) { final matches = memoizedProductList(widget.productMap).where((entityId) {
final entity = widget.productMap[entityId]; final entity = widget.productMap[entityId];
return entity.isActive && entity.matchesSearch(_filter); return entity.isActive && entity.matchesFilter(_filter);
}).toList(); }).toList();
matches.sort((idA, idB) => matches.sort((idA, idB) =>
@ -150,7 +150,7 @@ class _InvoiceItemSelectorState extends State<InvoiceItemSelector> {
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
final int entityId = matches[index]; final int entityId = matches[index];
final entity = widget.productMap[entityId]; final entity = widget.productMap[entityId];
final String subtitle = entity.matchesSearchValue(_filter); final String subtitle = entity.matchesFilterValue(_filter);
return ListTile( return ListTile(
dense: true, dense: true,
leading: Checkbox( leading: Checkbox(

View File

@ -25,8 +25,8 @@ class InvoiceListItem extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
final searchMatch = filter != null && filter.isNotEmpty final filterMatch = filter != null && filter.isNotEmpty
? invoice.matchesSearchValue(filter) ? invoice.matchesFilterValue(filter)
: null; : null;
return DismissibleEntity( return DismissibleEntity(
@ -58,10 +58,10 @@ class InvoiceListItem extends StatelessWidget {
Row( Row(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: searchMatch == null child: filterMatch == null
? Text(invoice.invoiceNumber) ? Text(invoice.invoiceNumber)
: Text( : Text(
searchMatch, filterMatch,
maxLines: 3, maxLines: 3,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),

View File

@ -87,7 +87,7 @@ class InvoiceListVM {
clientMap: state.clientState.map, clientMap: state.clientState.map,
isLoading: state.isLoading, isLoading: state.isLoading,
isLoaded: state.invoiceState.isLoaded && state.clientState.isLoaded, isLoaded: state.invoiceState.isLoaded && state.clientState.isLoaded,
filter: state.invoiceListState.search, filter: state.invoiceListState.filter,
onInvoiceTap: (context, invoice) { onInvoiceTap: (context, invoice) {
store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context)); store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context));
}, },

View File

@ -1,5 +1,5 @@
import 'package:invoiceninja_flutter/ui/app/app_search.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
import 'package:invoiceninja_flutter/ui/app/app_search_button.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -22,17 +22,17 @@ class InvoiceScreen extends StatelessWidget {
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
appBar: AppBar( appBar: AppBar(
title: AppSearch( title: ListFilter(
entityType: EntityType.invoice, entityType: EntityType.invoice,
onSearchChanged: (value) { onFilterChanged: (value) {
store.dispatch(SearchInvoices(value)); store.dispatch(FilterInvoices(value));
}, },
), ),
actions: [ actions: [
AppSearchButton( ListFilterButton(
entityType: EntityType.invoice, entityType: EntityType.invoice,
onSearchPressed: (String value) { onFilterPressed: (String value) {
store.dispatch(SearchInvoices(value)); store.dispatch(FilterInvoices(value));
}, },
), ),
], ],

View File

@ -24,10 +24,10 @@ class ProductListItem extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final searchMatch = filter != null && filter.isNotEmpty final filterMatch = filter != null && filter.isNotEmpty
? product.matchesSearchValue(filter) ? product.matchesFilterValue(filter)
: null; : null;
final subtitle = searchMatch ?? product.notes; final subtitle = filterMatch ?? product.notes;
return DismissibleEntity( return DismissibleEntity(
entity: product, entity: product,

View File

@ -68,7 +68,7 @@ class ProductListVM {
productMap: store.state.productState.map, productMap: store.state.productState.map,
isLoading: store.state.isLoading, isLoading: store.state.isLoading,
isLoaded: store.state.productState.isLoaded, isLoaded: store.state.productState.isLoaded,
filter: store.state.productUIState.listUIState.search, filter: store.state.productUIState.listUIState.filter,
onProductTap: (context, product) { onProductTap: (context, product) {
store.dispatch(EditProduct(product: product, context: context)); store.dispatch(EditProduct(product: product, context: context));
}, },

View File

@ -1,5 +1,5 @@
import 'package:invoiceninja_flutter/ui/app/app_search.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
import 'package:invoiceninja_flutter/ui/app/app_search_button.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -21,17 +21,17 @@ class ProductScreen extends StatelessWidget {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: AppSearch( title: ListFilter(
entityType: EntityType.product, entityType: EntityType.product,
onSearchChanged: (value) { onFilterChanged: (value) {
store.dispatch(SearchProducts(value)); store.dispatch(FilterProducts(value));
}, },
), ),
actions: [ actions: [
AppSearchButton( ListFilterButton(
entityType: EntityType.product, entityType: EntityType.product,
onSearchPressed: (String value) { onFilterPressed: (String value) {
store.dispatch(SearchProducts(value)); store.dispatch(FilterProducts(value));
}, },
), ),
], ],