Refactor
This commit is contained in:
parent
39a73558c3
commit
d171ef9b11
|
|
@ -42,6 +42,7 @@ analyzer:
|
|||
|
||||
linter:
|
||||
rules:
|
||||
# - prefer_const_literals_to_create_immutables
|
||||
# these rules are documented on and in the same order as
|
||||
# the Dart Lint rules page to make maintenance easier
|
||||
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
|
||||
|
|
@ -117,7 +118,6 @@ linter:
|
|||
# - prefer_const_constructors
|
||||
- prefer_const_constructors_in_immutables
|
||||
- prefer_const_declarations
|
||||
- prefer_const_literals_to_create_immutables
|
||||
# - prefer_constructors_over_static_methods # not yet tested
|
||||
- prefer_contains
|
||||
# - prefer_equal_for_default_values # not supported by built_value
|
||||
|
|
|
|||
|
|
@ -5,22 +5,26 @@ import 'package:invoiceninja/data/models/entities.dart';
|
|||
|
||||
part 'client_model.g.dart';
|
||||
|
||||
abstract class ClientListResponse implements Built<ClientListResponse, ClientListResponseBuilder> {
|
||||
|
||||
abstract class ClientListResponse
|
||||
implements Built<ClientListResponse, ClientListResponseBuilder> {
|
||||
BuiltList<ClientEntity> get data;
|
||||
|
||||
ClientListResponse._();
|
||||
factory ClientListResponse([updates(ClientListResponseBuilder b)]) = _$ClientListResponse;
|
||||
static Serializer<ClientListResponse> get serializer => _$clientListResponseSerializer;
|
||||
factory ClientListResponse([updates(ClientListResponseBuilder b)]) =
|
||||
_$ClientListResponse;
|
||||
static Serializer<ClientListResponse> get serializer =>
|
||||
_$clientListResponseSerializer;
|
||||
}
|
||||
|
||||
abstract class ClientItemResponse implements Built<ClientItemResponse, ClientItemResponseBuilder> {
|
||||
|
||||
abstract class ClientItemResponse
|
||||
implements Built<ClientItemResponse, ClientItemResponseBuilder> {
|
||||
ClientEntity get data;
|
||||
|
||||
ClientItemResponse._();
|
||||
factory ClientItemResponse([updates(ClientItemResponseBuilder b)]) = _$ClientItemResponse;
|
||||
static Serializer<ClientItemResponse> get serializer => _$clientItemResponseSerializer;
|
||||
factory ClientItemResponse([updates(ClientItemResponseBuilder b)]) =
|
||||
_$ClientItemResponse;
|
||||
static Serializer<ClientItemResponse> get serializer =>
|
||||
_$clientItemResponseSerializer;
|
||||
}
|
||||
|
||||
class ClientFields {
|
||||
|
|
@ -36,9 +40,9 @@ class ClientFields {
|
|||
static const String workPhone = 'workPhone';
|
||||
}
|
||||
|
||||
|
||||
abstract class ClientEntity extends Object with BaseEntity implements Built<ClientEntity, ClientEntityBuilder> {
|
||||
|
||||
abstract class ClientEntity extends Object
|
||||
with BaseEntity
|
||||
implements Built<ClientEntity, ClientEntityBuilder> {
|
||||
@override
|
||||
EntityType get entityType {
|
||||
return EntityType.client;
|
||||
|
|
@ -48,47 +52,46 @@ abstract class ClientEntity extends Object with BaseEntity implements Built<Clie
|
|||
|
||||
factory ClientEntity() {
|
||||
return _$ClientEntity._(
|
||||
id: --ClientEntity.counter,
|
||||
name: '',
|
||||
displayName: '',
|
||||
balance: 0.0,
|
||||
paidToDate: 0.0,
|
||||
address1: '',
|
||||
address2: '',
|
||||
city: '',
|
||||
state: '',
|
||||
postalCode: '',
|
||||
countryId: 0,
|
||||
workPhone: '',
|
||||
privateNotes: '',
|
||||
publicNotes: '',
|
||||
website: '',
|
||||
industryId: 0,
|
||||
sizeId: 0,
|
||||
paymentTerms: 0,
|
||||
vatNumber: '',
|
||||
idNumber: '',
|
||||
languageId: 0,
|
||||
currencyId: 0,
|
||||
invoiceNumberCounter: 0,
|
||||
quoteNumberCounter: 0,
|
||||
taskRate: 0.0,
|
||||
shippingAddress1: '',
|
||||
shippingAddress2: '',
|
||||
shippingCity: '',
|
||||
shippingState: '',
|
||||
shippingPostalCode: '',
|
||||
shippingCountryId: 0,
|
||||
showTasksInPortal: false,
|
||||
sendReminders: false,
|
||||
creditNumberCounter: 0,
|
||||
customValue1: '',
|
||||
customValue2: '',
|
||||
contacts: BuiltList<ContactEntity>(),
|
||||
|
||||
updatedAt: 0,
|
||||
archivedAt: 0,
|
||||
isDeleted: false,
|
||||
id: --ClientEntity.counter,
|
||||
name: '',
|
||||
displayName: '',
|
||||
balance: 0.0,
|
||||
paidToDate: 0.0,
|
||||
address1: '',
|
||||
address2: '',
|
||||
city: '',
|
||||
state: '',
|
||||
postalCode: '',
|
||||
countryId: 0,
|
||||
workPhone: '',
|
||||
privateNotes: '',
|
||||
publicNotes: '',
|
||||
website: '',
|
||||
industryId: 0,
|
||||
sizeId: 0,
|
||||
paymentTerms: 0,
|
||||
vatNumber: '',
|
||||
idNumber: '',
|
||||
languageId: 0,
|
||||
currencyId: 0,
|
||||
invoiceNumberCounter: 0,
|
||||
quoteNumberCounter: 0,
|
||||
taskRate: 0.0,
|
||||
shippingAddress1: '',
|
||||
shippingAddress2: '',
|
||||
shippingCity: '',
|
||||
shippingState: '',
|
||||
shippingPostalCode: '',
|
||||
shippingCountryId: 0,
|
||||
showTasksInPortal: false,
|
||||
sendReminders: false,
|
||||
creditNumberCounter: 0,
|
||||
customValue1: '',
|
||||
customValue2: '',
|
||||
contacts: BuiltList<ContactEntity>(),
|
||||
updatedAt: 0,
|
||||
archivedAt: 0,
|
||||
isDeleted: false,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -200,12 +203,13 @@ abstract class ClientEntity extends Object with BaseEntity implements Built<Clie
|
|||
return displayName;
|
||||
}
|
||||
|
||||
bool get hasEmailAddress => contacts.where((contact) => contact.email?.isNotEmpty).length > 0;
|
||||
bool get hasEmailAddress =>
|
||||
contacts.where((contact) => contact.email?.isNotEmpty).length > 0;
|
||||
|
||||
int compareTo(ClientEntity client, String sortField, bool sortAscending) {
|
||||
int response = 0;
|
||||
ClientEntity clientA = sortAscending ? this : client;
|
||||
ClientEntity clientB = sortAscending ? client: this;
|
||||
ClientEntity clientB = sortAscending ? client : this;
|
||||
|
||||
switch (sortField) {
|
||||
case ClientFields.balance:
|
||||
|
|
@ -213,7 +217,9 @@ abstract class ClientEntity extends Object with BaseEntity implements Built<Clie
|
|||
}
|
||||
|
||||
if (response == 0) {
|
||||
return clientA.displayName.toLowerCase().compareTo(clientB.displayName.toLowerCase());
|
||||
return clientA.displayName
|
||||
.toLowerCase()
|
||||
.compareTo(clientB.displayName.toLowerCase());
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
|
|
@ -242,34 +248,9 @@ abstract class ClientEntity extends Object with BaseEntity implements Built<Clie
|
|||
return false;
|
||||
}
|
||||
|
||||
String matchesSearchField(String search) {
|
||||
if (search == null || search.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
search = search.toLowerCase();
|
||||
if (displayName.toLowerCase().contains(search)) {
|
||||
return null;
|
||||
}
|
||||
if (vatNumber.toLowerCase().contains(search)) {
|
||||
return ClientFields.vatNumber;
|
||||
}
|
||||
if (idNumber.toLowerCase().contains(search)) {
|
||||
return ClientFields.idNumber;
|
||||
}
|
||||
if (workPhone.toLowerCase().contains(search)) {
|
||||
return ClientFields.workPhone;
|
||||
}
|
||||
var contact = contacts.where((contact) => contact.matchesSearch(search)).first;
|
||||
if (contact != null) {
|
||||
return contact.matchesSearchField(search);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String matchesSearchValue(String search) {
|
||||
if (search == null || search.isEmpty) {
|
||||
return null;
|
||||
return '';
|
||||
}
|
||||
|
||||
search = search.toLowerCase();
|
||||
|
|
@ -282,19 +263,20 @@ abstract class ClientEntity extends Object with BaseEntity implements Built<Clie
|
|||
if (workPhone.toLowerCase().contains(search)) {
|
||||
return workPhone;
|
||||
}
|
||||
var contact = contacts.where((contact) => contact.matchesSearch(search)).first;
|
||||
final contact = contacts.firstWhere(
|
||||
(contact) => contact.matchesSearch(search),
|
||||
orElse: () => null);
|
||||
if (contact != null) {
|
||||
return contact.matchesSearchValue(search);
|
||||
}
|
||||
|
||||
return null;
|
||||
return '';
|
||||
}
|
||||
|
||||
ClientEntity._();
|
||||
static Serializer<ClientEntity> get serializer => _$clientEntitySerializer;
|
||||
}
|
||||
|
||||
|
||||
class ContactFields {
|
||||
static const String firstName = 'firstName';
|
||||
static const String lastName = 'lastName';
|
||||
|
|
@ -302,24 +284,24 @@ class ContactFields {
|
|||
static const String phone = 'phone';
|
||||
}
|
||||
|
||||
abstract class ContactEntity extends Object with BaseEntity implements Built<ContactEntity, ContactEntityBuilder> {
|
||||
|
||||
abstract class ContactEntity extends Object
|
||||
with BaseEntity
|
||||
implements Built<ContactEntity, ContactEntityBuilder> {
|
||||
static int counter = 0;
|
||||
factory ContactEntity() {
|
||||
return _$ContactEntity._(
|
||||
id: --ContactEntity.counter,
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
contactKey: '',
|
||||
isPrimary: false,
|
||||
customValue1: '',
|
||||
customValue2: '',
|
||||
|
||||
updatedAt: 0,
|
||||
archivedAt: 0,
|
||||
isDeleted: false,
|
||||
id: --ContactEntity.counter,
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
contactKey: '',
|
||||
isPrimary: false,
|
||||
customValue1: '',
|
||||
customValue2: '',
|
||||
updatedAt: 0,
|
||||
archivedAt: 0,
|
||||
isDeleted: false,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -345,7 +327,7 @@ abstract class ContactEntity extends Object with BaseEntity implements Built<Con
|
|||
@BuiltValueField(wireName: 'custom_value2')
|
||||
String get customValue2;
|
||||
|
||||
String fullName () {
|
||||
String fullName() {
|
||||
return (firstName + ' ' + lastName).trim();
|
||||
}
|
||||
|
||||
|
|
@ -369,22 +351,6 @@ abstract class ContactEntity extends Object with BaseEntity implements Built<Con
|
|||
return false;
|
||||
}
|
||||
|
||||
String matchesSearchField(String search) {
|
||||
if (search == null || search.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
search = search.toLowerCase();
|
||||
if (fullName().toLowerCase().contains(search)) {
|
||||
return ClientFields.contact;
|
||||
} else if (email.toLowerCase().contains(search)) {
|
||||
return ContactFields.email;
|
||||
} else if (phone.toLowerCase().contains(search)) {
|
||||
return ContactFields.phone;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String matchesSearchValue(String search) {
|
||||
if (search == null || search.isEmpty) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -89,10 +89,6 @@ abstract class BaseEntity {
|
|||
return true;
|
||||
}
|
||||
|
||||
String matchesSearchField(String search) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String matchesSearchValue(String search) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,22 +8,26 @@ import 'package:invoiceninja/utils/formatting.dart';
|
|||
|
||||
part 'product_model.g.dart';
|
||||
|
||||
abstract class ProductListResponse implements Built<ProductListResponse, ProductListResponseBuilder> {
|
||||
|
||||
abstract class ProductListResponse
|
||||
implements Built<ProductListResponse, ProductListResponseBuilder> {
|
||||
BuiltList<ProductEntity> get data;
|
||||
|
||||
ProductListResponse._();
|
||||
factory ProductListResponse([updates(ProductListResponseBuilder b)]) = _$ProductListResponse;
|
||||
static Serializer<ProductListResponse> get serializer => _$productListResponseSerializer;
|
||||
factory ProductListResponse([updates(ProductListResponseBuilder b)]) =
|
||||
_$ProductListResponse;
|
||||
static Serializer<ProductListResponse> get serializer =>
|
||||
_$productListResponseSerializer;
|
||||
}
|
||||
|
||||
abstract class ProductItemResponse implements Built<ProductItemResponse, ProductItemResponseBuilder> {
|
||||
|
||||
abstract class ProductItemResponse
|
||||
implements Built<ProductItemResponse, ProductItemResponseBuilder> {
|
||||
ProductEntity get data;
|
||||
|
||||
ProductItemResponse._();
|
||||
factory ProductItemResponse([updates(ProductItemResponseBuilder b)]) = _$ProductItemResponse;
|
||||
static Serializer<ProductItemResponse> get serializer => _$productItemResponseSerializer;
|
||||
factory ProductItemResponse([updates(ProductItemResponseBuilder b)]) =
|
||||
_$ProductItemResponse;
|
||||
static Serializer<ProductItemResponse> get serializer =>
|
||||
_$productItemResponseSerializer;
|
||||
}
|
||||
|
||||
class ProductFields {
|
||||
|
|
@ -33,10 +37,13 @@ class ProductFields {
|
|||
static const String updatedAt = 'updatedAt';
|
||||
static const String archivedAt = 'archivedAt';
|
||||
static const String isDeleted = 'isDeleted';
|
||||
static const String customValue1 = 'customValue1';
|
||||
static const String customValue2 = 'customValue2';
|
||||
}
|
||||
|
||||
abstract class ProductEntity extends Object with BaseEntity, ConvertToInvoiceItem implements Built<ProductEntity, ProductEntityBuilder> {
|
||||
|
||||
abstract class ProductEntity extends Object
|
||||
with BaseEntity, ConvertToInvoiceItem
|
||||
implements Built<ProductEntity, ProductEntityBuilder> {
|
||||
@override
|
||||
EntityType get entityType {
|
||||
return EntityType.product;
|
||||
|
|
@ -45,44 +52,44 @@ abstract class ProductEntity extends Object with BaseEntity, ConvertToInvoiceIte
|
|||
static int counter = 0;
|
||||
factory ProductEntity() {
|
||||
return _$ProductEntity._(
|
||||
id: --ProductEntity.counter,
|
||||
productKey: '',
|
||||
notes: '',
|
||||
cost: 0.0,
|
||||
taxName1: '',
|
||||
taxRate1: 0.0,
|
||||
taxName2: '',
|
||||
taxRate2: 0.0,
|
||||
customValue1: '',
|
||||
customValue2: '',
|
||||
updatedAt: 0,
|
||||
archivedAt: 0,
|
||||
isDeleted: false,
|
||||
id: --ProductEntity.counter,
|
||||
productKey: '',
|
||||
notes: '',
|
||||
cost: 0.0,
|
||||
taxName1: '',
|
||||
taxRate1: 0.0,
|
||||
taxName2: '',
|
||||
taxRate2: 0.0,
|
||||
customValue1: '',
|
||||
customValue2: '',
|
||||
updatedAt: 0,
|
||||
archivedAt: 0,
|
||||
isDeleted: false,
|
||||
);
|
||||
}
|
||||
|
||||
@BuiltValueField(wireName: 'product_key')
|
||||
String get productKey;
|
||||
|
||||
|
||||
String get notes;
|
||||
|
||||
|
||||
double get cost;
|
||||
|
||||
|
||||
@BuiltValueField(wireName: 'tax_name1')
|
||||
String get taxName1;
|
||||
|
||||
|
||||
@BuiltValueField(wireName: 'tax_rate1')
|
||||
double get taxRate1;
|
||||
|
||||
|
||||
@BuiltValueField(wireName: 'tax_name2')
|
||||
String get taxName2;
|
||||
|
||||
|
||||
@BuiltValueField(wireName: 'tax_rate2')
|
||||
double get taxRate2;
|
||||
|
||||
|
||||
@BuiltValueField(wireName: 'custom_value1')
|
||||
String get customValue1;
|
||||
|
||||
|
||||
@BuiltValueField(wireName: 'custom_value2')
|
||||
String get customValue2;
|
||||
|
||||
|
|
@ -103,14 +110,14 @@ abstract class ProductEntity extends Object with BaseEntity, ConvertToInvoiceIte
|
|||
..taxName1 = taxName1
|
||||
..taxRate1 = taxRate1
|
||||
..taxName2 = taxName2
|
||||
..taxRate2 = taxRate2
|
||||
);
|
||||
..taxRate2 = taxRate2);
|
||||
}
|
||||
|
||||
int compareTo(ProductEntity product, [String sortField, bool sortAscending = true]) {
|
||||
int compareTo(ProductEntity product,
|
||||
[String sortField, bool sortAscending = true]) {
|
||||
int response = 0;
|
||||
ProductEntity productA = sortAscending ? this : product;
|
||||
ProductEntity productB = sortAscending ? product: this;
|
||||
ProductEntity productB = sortAscending ? product : this;
|
||||
|
||||
switch (sortField) {
|
||||
case ProductFields.cost:
|
||||
|
|
@ -118,7 +125,9 @@ abstract class ProductEntity extends Object with BaseEntity, ConvertToInvoiceIte
|
|||
}
|
||||
|
||||
if (response == 0) {
|
||||
return productA.productKey.toLowerCase().compareTo(productB.productKey.toLowerCase());
|
||||
return productA.productKey
|
||||
.toLowerCase()
|
||||
.compareTo(productB.productKey.toLowerCase());
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
|
|
@ -130,29 +139,22 @@ abstract class ProductEntity extends Object with BaseEntity, ConvertToInvoiceIte
|
|||
}
|
||||
|
||||
search = search.toLowerCase();
|
||||
|
||||
if (productKey.toLowerCase().contains(search)) {
|
||||
return true;
|
||||
}
|
||||
if (notes.toLowerCase().contains(search)) {
|
||||
} else if (notes.toLowerCase().contains(search)) {
|
||||
return true;
|
||||
} else if (customValue1.isNotEmpty &&
|
||||
customValue1.toLowerCase().contains(search)) {
|
||||
return true;
|
||||
} else if (customValue2.isNotEmpty &&
|
||||
customValue2.toLowerCase().contains(search)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String matchesSearchField(String search) {
|
||||
if (search == null || search.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
search = search.toLowerCase();
|
||||
|
||||
if (notes.toLowerCase().contains(search)) {
|
||||
return ProductFields.notes;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
String matchesSearchValue(String search) {
|
||||
if (search == null || search.isEmpty) {
|
||||
return null;
|
||||
|
|
@ -161,6 +163,12 @@ abstract class ProductEntity extends Object with BaseEntity, ConvertToInvoiceIte
|
|||
search = search.toLowerCase();
|
||||
if (notes.toLowerCase().contains(search)) {
|
||||
return notes;
|
||||
} else if (customValue1.isNotEmpty &&
|
||||
customValue1.toLowerCase().contains(search)) {
|
||||
return customValue1;
|
||||
} else if (customValue2.isNotEmpty &&
|
||||
customValue2.toLowerCase().contains(search)) {
|
||||
return customValue2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class AppDrawer extends StatelessWidget {
|
|||
DrawerTile(
|
||||
icon: FontAwesomeIcons.filePdfO,
|
||||
title: AppLocalization.of(context).invoices,
|
||||
onTap: () => store.dispatch(ViewProductList(context)),
|
||||
onTap: () => store.dispatch(ViewInvoiceList(context)),
|
||||
onCreateTap: () {
|
||||
navigator.pop();
|
||||
store.dispatch(
|
||||
|
|
|
|||
|
|
@ -88,13 +88,7 @@ class _EntityDropdownState extends State<EntityDropdown> {
|
|||
final entity = widget.entityMap[entityId];
|
||||
final filter =
|
||||
store.state.getUIState(widget.entityType).dropdownFilter;
|
||||
String subtitle;
|
||||
final matchField = entity.matchesSearchField(filter);
|
||||
if (matchField != null) {
|
||||
final field = localization.lookup(matchField);
|
||||
final value = entity.matchesSearchValue(filter);
|
||||
subtitle = '$field: $value';
|
||||
}
|
||||
final String subtitle = entity.matchesSearchValue(filter);
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Text(entity.listDisplayName),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ class ClientItem extends StatelessWidget {
|
|||
final GestureTapCallback onTap;
|
||||
//final ValueChanged<bool> onCheckboxChanged;
|
||||
final ClientEntity client;
|
||||
final String filter;
|
||||
|
||||
static final clientItemKey = (int id) => Key('__client_item_${id}__');
|
||||
|
||||
|
|
@ -23,6 +24,7 @@ class ClientItem extends StatelessWidget {
|
|||
@required this.onTap,
|
||||
//@required this.onCheckboxChanged,
|
||||
@required this.client,
|
||||
@required this.filter,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -47,7 +49,18 @@ class ClientItem extends StatelessWidget {
|
|||
style: Theme.of(context).textTheme.title)
|
||||
],
|
||||
),
|
||||
subtitle: EntityStateLabel(client),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
filter != null && filter.isNotEmpty
|
||||
? client.matchesSearchValue(filter) : '',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
EntityStateLabel(client),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class ClientList extends StatelessWidget {
|
|||
var client = viewModel.clientMap[clientId];
|
||||
return Column(children: <Widget>[
|
||||
ClientItem(
|
||||
filter: viewModel.filter,
|
||||
state: viewModel.state,
|
||||
client: client,
|
||||
onDismissed: (DismissDirection direction) =>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class ClientListVM {
|
|||
final AppState state;
|
||||
final List<int> clientList;
|
||||
final BuiltMap<int, ClientEntity> clientMap;
|
||||
final String filter;
|
||||
final bool isLoading;
|
||||
final bool isLoaded;
|
||||
final Function(BuildContext, ClientEntity) onClientTap;
|
||||
|
|
@ -47,6 +48,7 @@ class ClientListVM {
|
|||
@required this.clientMap,
|
||||
@required this.isLoading,
|
||||
@required this.isLoaded,
|
||||
@required this.filter,
|
||||
@required this.onClientTap,
|
||||
@required this.onDismissed,
|
||||
@required this.onRefreshed,
|
||||
|
|
@ -70,6 +72,7 @@ class ClientListVM {
|
|||
clientMap: store.state.clientState.map,
|
||||
isLoading: store.state.isLoading,
|
||||
isLoaded: store.state.clientState.isLoaded,
|
||||
filter: store.state.clientListState.search,
|
||||
onClientTap: (context, client) {
|
||||
store.dispatch(ViewClient(clientId: client.id, context: context));
|
||||
},
|
||||
|
|
|
|||
|
|
@ -145,11 +145,7 @@ class _InvoiceItemSelectorState extends State<InvoiceItemSelector> {
|
|||
itemBuilder: (BuildContext context, int index) {
|
||||
int entityId = matches[index];
|
||||
var entity = state.map[entityId];
|
||||
var subtitle = null;
|
||||
var matchField = entity.matchesSearchField(_filter);
|
||||
if (matchField != null) {
|
||||
subtitle = entity.matchesSearchValue(_filter);
|
||||
}
|
||||
final String subtitle = entity.matchesSearchValue(_filter);
|
||||
return ListTile(
|
||||
dense: true,
|
||||
leading: Checkbox(
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ class InvoiceItem extends StatelessWidget {
|
|||
final InvoiceEntity invoice;
|
||||
final ClientEntity client;
|
||||
final AppState state;
|
||||
final String filter;
|
||||
|
||||
InvoiceItem({
|
||||
@required this.onDismissed,
|
||||
|
|
@ -22,6 +23,7 @@ class InvoiceItem extends StatelessWidget {
|
|||
@required this.invoice,
|
||||
@required this.client,
|
||||
@required this.state,
|
||||
@required this.filter,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -62,16 +64,13 @@ class InvoiceItem extends StatelessWidget {
|
|||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(invoice.invoiceNumber),
|
||||
/*
|
||||
invoice.notes.isNotEmpty
|
||||
? Text(
|
||||
invoice.notes,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
: Container(),
|
||||
*/
|
||||
Text(
|
||||
filter != null && filter.isNotEmpty
|
||||
? invoice.matchesSearchValue(filter) ?? ''
|
||||
: invoice.privateNotes ?? '',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
EntityStateLabel(invoice),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class InvoiceList extends StatelessWidget {
|
|||
var invoice = viewModel.invoiceMap[invoiceId];
|
||||
return Column(children: <Widget>[
|
||||
InvoiceItem(
|
||||
filter: viewModel.filter,
|
||||
invoice: invoice,
|
||||
client: viewModel.clientMap[invoice.clientId],
|
||||
onDismissed: (DismissDirection direction) =>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class InvoiceListVM {
|
|||
final List<int> invoiceList;
|
||||
final BuiltMap<int, InvoiceEntity> invoiceMap;
|
||||
final BuiltMap<int, ClientEntity> clientMap;
|
||||
final String filter;
|
||||
final bool isLoading;
|
||||
final bool isLoaded;
|
||||
final Function(BuildContext, InvoiceEntity) onInvoiceTap;
|
||||
|
|
@ -49,6 +50,7 @@ class InvoiceListVM {
|
|||
@required this.clientMap,
|
||||
@required this.isLoading,
|
||||
@required this.isLoaded,
|
||||
@required this.filter,
|
||||
@required this.onInvoiceTap,
|
||||
@required this.onDismissed,
|
||||
@required this.onRefreshed,
|
||||
|
|
@ -80,6 +82,7 @@ class InvoiceListVM {
|
|||
isLoading: state.isLoading,
|
||||
isLoaded: state.invoiceState.isLoaded &&
|
||||
state.clientState.isLoaded,
|
||||
filter: state.invoiceListState.search,
|
||||
onInvoiceTap: (context, invoice) {
|
||||
store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context));
|
||||
},
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ class ProductItem extends StatelessWidget {
|
|||
final GestureTapCallback onTap;
|
||||
//final ValueChanged<bool> onCheckboxChanged;
|
||||
final ProductEntity product;
|
||||
|
||||
final String filter;
|
||||
|
||||
static final productItemKey = (int id) => Key('__product_item_${id}__');
|
||||
|
||||
ProductItem({
|
||||
|
|
@ -22,6 +23,7 @@ class ProductItem extends StatelessWidget {
|
|||
@required this.onTap,
|
||||
//@required this.onCheckboxChanged,
|
||||
@required this.product,
|
||||
@required this.filter,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -61,13 +63,13 @@ class ProductItem extends StatelessWidget {
|
|||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
product.notes.isNotEmpty
|
||||
? Text(
|
||||
product.notes,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
: Container(),
|
||||
Text(
|
||||
filter != null && filter.isNotEmpty
|
||||
? product.matchesSearchValue(filter) ?? ''
|
||||
: product.notes ?? '',
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
EntityStateLabel(product),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class ProductList extends StatelessWidget {
|
|||
var product = viewModel.productMap[productId];
|
||||
return Column(children: <Widget>[
|
||||
ProductItem(
|
||||
filter: viewModel.filter,
|
||||
state: viewModel.state,
|
||||
product: product,
|
||||
onDismissed: (DismissDirection direction) =>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class ProductListVM {
|
|||
final AppState state;
|
||||
final List<int> productList;
|
||||
final BuiltMap<int, ProductEntity> productMap;
|
||||
final String filter;
|
||||
final bool isLoading;
|
||||
final bool isLoaded;
|
||||
final Function(BuildContext, ProductEntity) onProductTap;
|
||||
|
|
@ -44,6 +45,7 @@ class ProductListVM {
|
|||
@required this.state,
|
||||
@required this.productList,
|
||||
@required this.productMap,
|
||||
@required this.filter,
|
||||
@required this.isLoading,
|
||||
@required this.isLoaded,
|
||||
@required this.onProductTap,
|
||||
|
|
@ -69,6 +71,7 @@ class ProductListVM {
|
|||
productMap: store.state.productState.map,
|
||||
isLoading: store.state.isLoading,
|
||||
isLoaded: store.state.productState.isLoaded,
|
||||
filter: store.state.productUIState.listUIState.search,
|
||||
onProductTap: (context, product) {
|
||||
store.dispatch(EditProduct(product: product, context: context));
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue