From 5aaf30f1f9f2c7962cf8f80a1ccb2dd5d964d58c Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 2 Mar 2020 21:20:12 +0200 Subject: [PATCH] Starter... --- lib/ui/credit/credit_screen.dart | 220 +++++++++++++++++-------------- stubs/ui/stub/stub_screen | 220 +++++++++++++++++-------------- 2 files changed, 238 insertions(+), 202 deletions(-) diff --git a/lib/ui/credit/credit_screen.dart b/lib/ui/credit/credit_screen.dart index 9ab558dda..483e07516 100644 --- a/lib/ui/credit/credit_screen.dart +++ b/lib/ui/credit/credit_screen.dart @@ -2,17 +2,20 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:invoiceninja_flutter/data/models/credit_model.dart'; -import 'package:invoiceninja_flutter/ui/app/list_filter.dart'; -import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart'; -import 'package:invoiceninja_flutter/ui/credit/credit_screen_vm.dart'; -import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/credit/credit_list_vm.dart'; +import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart'; import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart'; +import 'package:invoiceninja_flutter/ui/app/forms/save_cancel_buttons.dart'; +import 'package:invoiceninja_flutter/ui/app/list_scaffold.dart'; import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart'; +import 'package:invoiceninja_flutter/ui/app/list_filter.dart'; +import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart'; +import 'package:invoiceninja_flutter/ui/credit/credit_list_vm.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; + +import 'credit_screen_vm.dart'; class CreditScreen extends StatelessWidget { const CreditScreen({ @@ -28,103 +31,118 @@ class CreditScreen extends StatelessWidget { Widget build(BuildContext context) { final store = StoreProvider.of(context); final state = store.state; - final company = state.selectedCompany; + final company = state.company; + final userCompany = state.userCompany; final localization = AppLocalization.of(context); final listUIState = state.uiState.creditUIState.listUIState; final isInMultiselect = listUIState.isInMultiselect(); - return AppScaffold( - isChecked: isInMultiselect && - listUIState.selectedIds.length == viewModel.creditList.length, - showCheckbox: isInMultiselect, - onCheckboxChanged: (value) { - final credits = viewModel.creditList - .map((creditId) => viewModel.creditMap[creditId]) - .where((credit) => value != listUIState.isSelected(credit)) - .toList(); - - viewModel.onEntityAction( - context, credits, EntityAction.toggleMultiselect); - }, - appBarTitle: ListFilter( - title: localization.credits - key: ValueKey(state.creditListState.filterClearedAt), - entityType: EntityType.credit, - onFilterChanged: (value) { - store.dispatch(FilterCredits(value)); - }, - ), - appBarActions: [ - if (!viewModel.isInMultiselect) - ListFilterButton( - entityType: EntityType.credit, - onFilterPressed: (String value) { - store.dispatch(FilterCredits(value)); - }, - ), - if (viewModel.isInMultiselect) - SaveCancelButtons( - saveLabel: localization.done, - onSavePressed: listUIState.selectedIds.isEmpty - ? null - : (context) async { - final credits = listUIState.selectedIds - .map( - (creditId) => viewModel.creditMap[creditId]) - .toList(); - - await showEntityActionsDialog( - entities: credits, context: context, multiselect: true, - completer: Completer() - ..future.then((_) => - store.dispatch(ClearCreditMultiselect())), - ); - }, - onCancelPressed: (context) => - store.dispatch(ClearCreditMultiselect()), - ), - ], - body: CreditListBuilder(), - bottomNavigationBar: AppBottomBar( - entityType: EntityType.credit, - onSelectedSortField: (value) => store.dispatch(SortCredits(value)), - customValues1: company.getCustomFieldValues(CustomFieldType.credit1, - excludeBlank: true), - customValues2: company.getCustomFieldValues(CustomFieldType.credit2, - excludeBlank: true), - onSelectedCustom1: (value) => - store.dispatch(FilterCreditsByCustom1(value)), - onSelectedCustom2: (value) => - store.dispatch(FilterCreditsByCustom2(value)), - sortFields: [ - CreditFields.updatedAt, - ], - onSelectedState: (EntityState state, value) { - store.dispatch(FilterCreditsByState(state)); - }, - onCheckboxPressed: () { - if (store.state.creditListState.isInMultiselect()) { - store.dispatch(ClearCreditMultiselect()); - } else { - store.dispatch(StartCreditMultiselect()); - } - }, - ), - floatingActionButton: user.canCreate(EntityType.credit) - ? FloatingActionButton( - heroTag: 'credit_fab', - backgroundColor: Theme.of(context).primaryColorDark, - onPressed: () { - store.dispatch( - EditCredit(credit: InvoiceEntity(), context: context)); - }, - child: Icon( - Icons.add, - color: Colors.white, - ), - tooltip: localization.newCredit, - ) - : null, - ); + return ListScaffold( + isChecked: isInMultiselect && + listUIState.selectedIds.length == viewModel.creditList.length, + showCheckbox: isInMultiselect, + onHamburgerLongPress: () => store.dispatch(StartCreditMultiselect()), + onCheckboxChanged: (value) { + final credits = viewModel.creditList + .map((creditId) => viewModel.creditMap[creditId]) + .where((credit) => value != listUIState.isSelected(credit.id)) + .toList(); + + handleCreditAction(context, credits, EntityAction.toggleMultiselect); + }, + appBarTitle: ListFilter( + title: localization.credits, + key: ValueKey(state.creditListState.filterClearedAt), + filter: state.creditListState.filter, + onFilterChanged: (value) { + store.dispatch(FilterCredits(value)); + }, + ), + appBarActions: [ + if (!viewModel.isInMultiselect) + ListFilterButton( + filter: state.creditListState.filter, + onFilterPressed: (String value) { + store.dispatch(FilterCredits(value)); + }, + ), + if (viewModel.isInMultiselect) + SaveCancelButtons( + saveLabel: localization.done, + onSavePressed: listUIState.selectedIds.isEmpty + ? null + : (context) async { + final credits = listUIState.selectedIds + .map( + (creditId) => viewModel.creditMap[creditId]) + .toList(); + + await showEntityActionsDialog( + entities: credits, + context: context, + multiselect: true, + completer: Completer() + ..future.then( + (_) => store.dispatch(ClearCreditMultiselect())), + ); + }, + onCancelPressed: (context) => + store.dispatch(ClearCreditMultiselect()), + ), + ], + body: CreditListBuilder(), + bottomNavigationBar: AppBottomBar( + entityType: EntityType.credit, + onSelectedSortField: (value) { + store.dispatch(SortCredits(value)); + }, + sortFields: [ + CreditFields.number, + CreditFields.amount, + CreditFields.updatedAt, + ], + onSelectedState: (EntityState state, value) { + store.dispatch(FilterCreditsByState(state)); + }, + onCheckboxPressed: () { + if (store.state.creditListState.isInMultiselect()) { + store.dispatch(ClearCreditMultiselect()); + } else { + store.dispatch(StartCreditMultiselect()); + } + }, + customValues1: company.getCustomFieldValues(CustomFieldType.invoice1, + excludeBlank: true), + customValues2: company.getCustomFieldValues(CustomFieldType.invoice2, + excludeBlank: true), + customValues3: company.getCustomFieldValues(CustomFieldType.invoice3, + excludeBlank: true), + customValues4: company.getCustomFieldValues(CustomFieldType.invoice4, + excludeBlank: true), + onSelectedCustom1: (value) => + store.dispatch(FilterCreditsByCustom1(value)), + onSelectedCustom2: (value) => + store.dispatch(FilterCreditsByCustom2(value)), + onSelectedCustom3: (value) => + store.dispatch(FilterCreditsByCustom3(value)), + onSelectedCustom4: (value) => + store.dispatch(FilterCreditsByCustom4(value)), + ), + floatingActionButton: userCompany.canCreate(EntityType.credit) + ? FloatingActionButton( + heroTag: 'credit_fab', + backgroundColor: Theme.of(context).primaryColorDark, + onPressed: () { + createEntityByType( + context: context, entityType: EntityType.credit); + }, + child: Icon( + Icons.add, + color: Colors.white, + ), + tooltip: localization.newCredit, + ) + : null, + ); } } diff --git a/stubs/ui/stub/stub_screen b/stubs/ui/stub/stub_screen index 32f32abf3..76bfdc8e9 100644 --- a/stubs/ui/stub/stub_screen +++ b/stubs/ui/stub/stub_screen @@ -2,17 +2,20 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:invoiceninja_flutter/data/models/stub_model.dart'; -import 'package:invoiceninja_flutter/ui/app/list_filter.dart'; -import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart'; -import 'package:invoiceninja_flutter/ui/stub/stub_screen_vm.dart'; -import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/stub/stub_list_vm.dart'; +import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/stub/stub_actions.dart'; import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart'; +import 'package:invoiceninja_flutter/ui/app/forms/save_cancel_buttons.dart'; +import 'package:invoiceninja_flutter/ui/app/list_scaffold.dart'; import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart'; +import 'package:invoiceninja_flutter/ui/app/list_filter.dart'; +import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart'; +import 'package:invoiceninja_flutter/ui/stub/stub_list_vm.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; + +import 'stub_screen_vm.dart'; class StubScreen extends StatelessWidget { const StubScreen({ @@ -28,103 +31,118 @@ class StubScreen extends StatelessWidget { Widget build(BuildContext context) { final store = StoreProvider.of(context); final state = store.state; - final company = state.selectedCompany; + final company = state.company; + final userCompany = state.userCompany; final localization = AppLocalization.of(context); final listUIState = state.uiState.stubUIState.listUIState; final isInMultiselect = listUIState.isInMultiselect(); - return AppScaffold( - isChecked: isInMultiselect && - listUIState.selectedIds.length == viewModel.stubList.length, - showCheckbox: isInMultiselect, - onCheckboxChanged: (value) { - final stubs = viewModel.stubList - .map((stubId) => viewModel.stubMap[stubId]) - .where((stub) => value != listUIState.isSelected(stub)) - .toList(); - - viewModel.onEntityAction( - context, stubs, EntityAction.toggleMultiselect); - }, - appBarTitle: ListFilter( - title: localization.stubs - key: ValueKey(state.stubListState.filterClearedAt), - entityType: EntityType.stub, - onFilterChanged: (value) { - store.dispatch(FilterStubs(value)); - }, - ), - appBarActions: [ - if (!viewModel.isInMultiselect) - ListFilterButton( - entityType: EntityType.stub, - onFilterPressed: (String value) { - store.dispatch(FilterStubs(value)); - }, - ), - if (viewModel.isInMultiselect) - SaveCancelButtons( - saveLabel: localization.done, - onSavePressed: listUIState.selectedIds.isEmpty - ? null - : (context) async { - final stubs = listUIState.selectedIds - .map( - (stubId) => viewModel.stubMap[stubId]) - .toList(); - - await showEntityActionsDialog( - entities: stubs, context: context, multiselect: true, - completer: Completer() - ..future.then((_) => - store.dispatch(ClearStubMultiselect())), - ); - }, - onCancelPressed: (context) => - store.dispatch(ClearStubMultiselect()), - ), - ], - body: StubListBuilder(), - bottomNavigationBar: AppBottomBar( - entityType: EntityType.stub, - onSelectedSortField: (value) => store.dispatch(SortStubs(value)), - customValues1: company.getCustomFieldValues(CustomFieldType.stub1, - excludeBlank: true), - customValues2: company.getCustomFieldValues(CustomFieldType.stub2, - excludeBlank: true), - onSelectedCustom1: (value) => - store.dispatch(FilterStubsByCustom1(value)), - onSelectedCustom2: (value) => - store.dispatch(FilterStubsByCustom2(value)), - sortFields: [ - StubFields.updatedAt, - ], - onSelectedState: (EntityState state, value) { - store.dispatch(FilterStubsByState(state)); - }, - onCheckboxPressed: () { - if (store.state.stubListState.isInMultiselect()) { - store.dispatch(ClearStubMultiselect()); - } else { - store.dispatch(StartStubMultiselect()); - } - }, - ), - floatingActionButton: user.canCreate(EntityType.stub) - ? FloatingActionButton( - heroTag: 'stub_fab', - backgroundColor: Theme.of(context).primaryColorDark, - onPressed: () { - store.dispatch( - EditStub(stub: StubEntity(), context: context)); - }, - child: Icon( - Icons.add, - color: Colors.white, - ), - tooltip: localization.newStub, - ) - : null, - ); + return ListScaffold( + isChecked: isInMultiselect && + listUIState.selectedIds.length == viewModel.stubList.length, + showCheckbox: isInMultiselect, + onHamburgerLongPress: () => store.dispatch(StartStubMultiselect()), + onCheckboxChanged: (value) { + final stubs = viewModel.stubList + .map((stubId) => viewModel.stubMap[stubId]) + .where((stub) => value != listUIState.isSelected(stub.id)) + .toList(); + + handleStubAction(context, stubs, EntityAction.toggleMultiselect); + }, + appBarTitle: ListFilter( + title: localization.stubs, + key: ValueKey(state.stubListState.filterClearedAt), + filter: state.stubListState.filter, + onFilterChanged: (value) { + store.dispatch(FilterStubs(value)); + }, + ), + appBarActions: [ + if (!viewModel.isInMultiselect) + ListFilterButton( + filter: state.stubListState.filter, + onFilterPressed: (String value) { + store.dispatch(FilterStubs(value)); + }, + ), + if (viewModel.isInMultiselect) + SaveCancelButtons( + saveLabel: localization.done, + onSavePressed: listUIState.selectedIds.isEmpty + ? null + : (context) async { + final stubs = listUIState.selectedIds + .map( + (stubId) => viewModel.stubMap[stubId]) + .toList(); + + await showEntityActionsDialog( + entities: stubs, + context: context, + multiselect: true, + completer: Completer() + ..future.then( + (_) => store.dispatch(ClearStubMultiselect())), + ); + }, + onCancelPressed: (context) => + store.dispatch(ClearStubMultiselect()), + ), + ], + body: StubListBuilder(), + bottomNavigationBar: AppBottomBar( + entityType: EntityType.stub, + onSelectedSortField: (value) { + store.dispatch(SortStubs(value)); + }, + sortFields: [ + StubFields.name, + StubFields.balance, + StubFields.updatedAt, + ], + onSelectedState: (EntityState state, value) { + store.dispatch(FilterStubsByState(state)); + }, + onCheckboxPressed: () { + if (store.state.stubListState.isInMultiselect()) { + store.dispatch(ClearStubMultiselect()); + } else { + store.dispatch(StartStubMultiselect()); + } + }, + customValues1: company.getCustomFieldValues(CustomFieldType.stub1, + excludeBlank: true), + customValues2: company.getCustomFieldValues(CustomFieldType.stub2, + excludeBlank: true), + customValues3: company.getCustomFieldValues(CustomFieldType.stub3, + excludeBlank: true), + customValues4: company.getCustomFieldValues(CustomFieldType.stub4, + excludeBlank: true), + onSelectedCustom1: (value) => + store.dispatch(FilterStubsByCustom1(value)), + onSelectedCustom2: (value) => + store.dispatch(FilterStubsByCustom2(value)), + onSelectedCustom3: (value) => + store.dispatch(FilterStubsByCustom3(value)), + onSelectedCustom4: (value) => + store.dispatch(FilterStubsByCustom4(value)), + ), + floatingActionButton: userCompany.canCreate(EntityType.stub) + ? FloatingActionButton( + heroTag: 'stub_fab', + backgroundColor: Theme.of(context).primaryColorDark, + onPressed: () { + createEntityByType( + context: context, entityType: EntityType.stub); + }, + child: Icon( + Icons.add, + color: Colors.white, + ), + tooltip: localization.newStub, + ) + : null, + ); } }