Handle quick changes in line items

This commit is contained in:
Hillel Coren 2021-05-27 20:24:51 +03:00
parent bf569242c6
commit 3d34cfa06a
2 changed files with 341 additions and 269 deletions

View File

@ -264,8 +264,12 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
), ),
), ),
*/ */
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: TypeAheadFormField<String>( child: TypeAheadFormField<String>(
key: ValueKey('__line_item_${index}_name__'), key: ValueKey('__line_item_${index}_name__'),
initialValue: lineItems[index].productKey, initialValue: lineItems[index].productKey,
@ -308,8 +312,8 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
final product = productState.map[productId]; final product = productState.map[productId];
final client = final client =
state.clientState.get(invoice.clientId); state.clientState.get(invoice.clientId);
final currency = state final currency = state.staticState
.staticState.currencyMap[client.currencyId]; .currencyMap[client.currencyId];
double cost = product.price; double cost = product.price;
if (company.convertProductExchangeRate && if (company.convertProductExchangeRate &&
@ -326,9 +330,11 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
..cost = item.isTask && item.cost != 0 ..cost = item.isTask && item.cost != 0
? item.cost ? item.cost
: cost : cost
..quantity = item.isTask || item.quantity != 0 ..quantity =
item.isTask || item.quantity != 0
? item.quantity ? item.quantity
: viewModel.state.company.defaultQuantity : viewModel.state.company
.defaultQuantity
? 1 ? 1
: product.quantity : product.quantity
..customValue1 = product.customValue1 ..customValue1 = product.customValue1
@ -341,7 +347,8 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
..taxName2 = product.taxName2 ..taxName2 = product.taxName2
..taxRate3 = product.taxRate3 ..taxRate3 = product.taxRate3
..taxName3 = product.taxName3); ..taxName3 = product.taxName3);
_onChanged(updatedItem, index, debounce: false); _onChanged(updatedItem, index,
debounce: false);
_updateTable(); _updateTable();
}, },
); );
@ -370,7 +377,8 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
} }
final updatedItem = item.rebuild((b) => b final updatedItem = item.rebuild((b) => b
..productKey = product.productKey ..productKey = product.productKey
..notes = item.isTask ? item.notes : product.notes ..notes =
item.isTask ? item.notes : product.notes
..cost = item.isTask && item.cost != 0 ..cost = item.isTask && item.cost != 0
? item.cost ? item.cost
: cost : cost
@ -403,7 +411,11 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
animationStart: 1, animationStart: 1,
debounceDuration: Duration(seconds: 0), debounceDuration: Duration(seconds: 0),
)), )),
Padding( ),
Focus(
onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding: const EdgeInsets.only(right: kTableColumnGap), padding: const EdgeInsets.only(right: kTableColumnGap),
child: GrowableFormField( child: GrowableFormField(
key: ValueKey('__line_item_${index}_description__'), key: ValueKey('__line_item_${index}_description__'),
@ -414,9 +426,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,
), ),
), ),
),
if (company.hasCustomField(customField1)) if (company.hasCustomField(customField1))
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: CustomField( child: CustomField(
field: customField1, field: customField1,
value: lineItems[index].customValue1, value: lineItems[index].customValue1,
@ -428,9 +445,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
onSavePressed: widget.entityViewModel.onSavePressed, onSavePressed: widget.entityViewModel.onSavePressed,
), ),
), ),
),
if (company.hasCustomField(customField2)) if (company.hasCustomField(customField2))
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: CustomField( child: CustomField(
field: customField2, field: customField2,
value: lineItems[index].customValue2, value: lineItems[index].customValue2,
@ -442,9 +464,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
onSavePressed: widget.entityViewModel.onSavePressed, onSavePressed: widget.entityViewModel.onSavePressed,
), ),
), ),
),
if (company.hasCustomField(CustomFieldType.product3)) if (company.hasCustomField(CustomFieldType.product3))
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: CustomField( child: CustomField(
field: CustomFieldType.product3, field: CustomFieldType.product3,
value: lineItems[index].customValue3, value: lineItems[index].customValue3,
@ -456,9 +483,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
onSavePressed: widget.entityViewModel.onSavePressed, onSavePressed: widget.entityViewModel.onSavePressed,
), ),
), ),
),
if (company.hasCustomField(customField4)) if (company.hasCustomField(customField4))
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: CustomField( child: CustomField(
field: customField4, field: customField4,
value: lineItems[index].customValue4, value: lineItems[index].customValue4,
@ -470,9 +502,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
onSavePressed: widget.entityViewModel.onSavePressed, onSavePressed: widget.entityViewModel.onSavePressed,
), ),
), ),
),
if (hasTax1) if (hasTax1)
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: TaxRateDropdown( child: TaxRateDropdown(
onSelected: (taxRate) => _onChanged( onSelected: (taxRate) => _onChanged(
lineItems[index].rebuild((b) => b lineItems[index].rebuild((b) => b
@ -484,9 +521,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
initialTaxRate: lineItems[index].taxRate1, initialTaxRate: lineItems[index].taxRate1,
), ),
), ),
),
if (hasTax2) if (hasTax2)
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: TaxRateDropdown( child: TaxRateDropdown(
onSelected: (taxRate) => _onChanged( onSelected: (taxRate) => _onChanged(
lineItems[index].rebuild((b) => b lineItems[index].rebuild((b) => b
@ -498,9 +540,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
initialTaxRate: lineItems[index].taxRate2, initialTaxRate: lineItems[index].taxRate2,
), ),
), ),
),
if (hasTax3) if (hasTax3)
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: TaxRateDropdown( child: TaxRateDropdown(
onSelected: (taxRate) => _onChanged( onSelected: (taxRate) => _onChanged(
lineItems[index].rebuild((b) => b lineItems[index].rebuild((b) => b
@ -512,7 +559,11 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
initialTaxRate: lineItems[index].taxRate3, initialTaxRate: lineItems[index].taxRate3,
), ),
), ),
Padding( ),
Focus(
onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding: const EdgeInsets.only(right: kTableColumnGap), padding: const EdgeInsets.only(right: kTableColumnGap),
child: DecoratedFormField( child: DecoratedFormField(
key: ValueKey('__line_item_${index}_cost__'), key: ValueKey('__line_item_${index}_cost__'),
@ -530,9 +581,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
onSavePressed: widget.entityViewModel.onSavePressed, onSavePressed: widget.entityViewModel.onSavePressed,
), ),
), ),
),
if (company.enableProductQuantity || widget.isTasks) if (company.enableProductQuantity || widget.isTasks)
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: DecoratedFormField( child: DecoratedFormField(
key: ValueKey('__line_item_${index}_quantity__'), key: ValueKey('__line_item_${index}_quantity__'),
textAlign: TextAlign.right, textAlign: TextAlign.right,
@ -549,9 +605,14 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
onSavePressed: widget.entityViewModel.onSavePressed, onSavePressed: widget.entityViewModel.onSavePressed,
), ),
), ),
),
if (company.enableProductDiscount) if (company.enableProductDiscount)
Padding( Focus(
padding: const EdgeInsets.only(right: kTableColumnGap), onFocusChange: (hasFocus) => Debouncer.complete(),
skipTraversal: true,
child: Padding(
padding:
const EdgeInsets.only(right: kTableColumnGap),
child: DecoratedFormField( child: DecoratedFormField(
key: ValueKey('__line_item_${index}_discount__'), key: ValueKey('__line_item_${index}_discount__'),
textAlign: TextAlign.right, textAlign: TextAlign.right,
@ -568,6 +629,7 @@ class _InvoiceEditItemsDesktopState extends State<InvoiceEditItemsDesktop> {
onSavePressed: widget.entityViewModel.onSavePressed, onSavePressed: widget.entityViewModel.onSavePressed,
), ),
), ),
),
Padding( Padding(
padding: const EdgeInsets.only(right: kTableColumnGap), padding: const EdgeInsets.only(right: kTableColumnGap),
child: TextFormField( child: TextFormField(

View File

@ -62,9 +62,14 @@ Completer<Null> errorCompleter(BuildContext context) {
// https://stackoverflow.com/a/55119208/497368 // https://stackoverflow.com/a/55119208/497368
class Debouncer { class Debouncer {
Debouncer({this.milliseconds = kMillisecondsToDebounceUpdate}); Debouncer({
this.milliseconds = kMillisecondsToDebounceUpdate,
this.sendFirstAction = false,
});
final int milliseconds; final int milliseconds;
final bool sendFirstAction;
static VoidCallback action; static VoidCallback action;
static Timer timer; static Timer timer;
@ -75,7 +80,11 @@ class Debouncer {
} }
if (timer == null) { if (timer == null) {
if (sendFirstAction) {
action(); action();
} else {
Debouncer.action = action;
}
} else { } else {
timer.cancel(); timer.cancel();
Debouncer.action = action; Debouncer.action = action;
@ -93,6 +102,7 @@ class Debouncer {
static void complete() { static void complete() {
if (action != null) { if (action != null) {
action(); action();
action = null;
} }
} }