This commit is contained in:
Hillel Coren 2019-11-15 14:30:05 +02:00
parent 9fb1faf85f
commit 908ef8c080
72 changed files with 229 additions and 413 deletions

View File

@ -104,6 +104,7 @@ abstract class ClientEntity extends Object
ClientEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false);
@nullable

View File

@ -71,6 +71,7 @@ abstract class CreditEntity extends Object
CreditEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false);
@override

View File

@ -92,6 +92,7 @@ abstract class DocumentEntity extends Object
DocumentEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false);
@override

View File

@ -114,6 +114,7 @@ abstract class ExpenseEntity extends Object
ExpenseEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false
..invoiceId = null
..expenseDate = convertDateTimeToSqlDate()

View File

@ -124,6 +124,7 @@ abstract class InvoiceEntity extends Object
InvoiceEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false
..statusId = kInvoiceStatusDraft
..quoteInvoiceId = null

View File

@ -74,6 +74,7 @@ abstract class ProductEntity extends Object
ProductEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false);
@override

View File

@ -73,6 +73,7 @@ abstract class ProjectEntity extends Object
ProjectEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false);
@override

View File

@ -120,6 +120,7 @@ abstract class QuoteEntity extends Object
QuoteEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false
..quoteInvoiceId = null
..invoiceNumber = ''

View File

@ -152,6 +152,7 @@ abstract class TaskEntity extends Object
TaskEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false
..invoiceId = null
..isRunning = false

View File

@ -98,6 +98,7 @@ abstract class VendorEntity extends Object
VendorEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId
..isChanged = true
..isDeleted = false);
@override

View File

@ -187,6 +187,11 @@ Reducer<BuiltList<HistoryRecord>> historyReducer = combineReducers([
BuiltList<HistoryRecord> _addToHistory(
BuiltList<HistoryRecord> list, HistoryRecord record) {
// don't track new records
if (record.id.startsWith('-')) {
return list;
}
final old =
list.firstWhere((item) => item.matchesRecord(record), orElse: () => null);
if (old != null) {

View File

@ -1,18 +1,26 @@
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/company_model.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart';
import 'package:invoiceninja_flutter/redux/group/group_actions.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart';
import 'package:invoiceninja_flutter/redux/product/product_actions.dart';
import 'package:invoiceninja_flutter/redux/project/project_actions.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_actions.dart';
import 'package:invoiceninja_flutter/redux/task/task_actions.dart';
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_actions.dart';
import 'package:invoiceninja_flutter/redux/user/user_actions.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
import 'package:invoiceninja_flutter/utils/icons.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
Future<void> showEntityActionsDialog(
{@required
BuildContext context,
@required
List<BaseEntity> entities,
@required
UserCompanyEntity userCompany,
@required
Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction,
{@required BuildContext context,
@required List<BaseEntity> entities,
ClientEntity client,
bool multiselect = false}) async {
if (entities == null) {
@ -22,10 +30,12 @@ Future<void> showEntityActionsDialog(
showDialog<String>(
context: context,
builder: (BuildContext dialogContext) {
final state = StoreProvider.of<AppState>(context).state;
final actions = <Widget>[];
actions.addAll(entities[0]
.getActions(
userCompany: userCompany,
userCompany: state.userCompany,
includeEdit: true,
client: client,
multiselect: multiselect)
@ -35,9 +45,8 @@ Future<void> showEntityActionsDialog(
} else {
return EntityActionListTile(
entities: entities,
entityAction: entityAction,
action: entityAction,
mainContext: mainContext,
onEntityAction: onEntityAction,
);
}
}).toList());
@ -48,13 +57,10 @@ Future<void> showEntityActionsDialog(
class EntityActionListTile extends StatelessWidget {
const EntityActionListTile(
{this.entities,
this.entityAction,
this.onEntityAction,
this.mainContext});
{this.entities, this.action, this.onEntityAction, this.mainContext});
final List<BaseEntity> entities;
final EntityAction entityAction;
final EntityAction action;
final BuildContext mainContext;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
@ -63,11 +69,52 @@ class EntityActionListTile extends StatelessWidget {
final localization = AppLocalization.of(context);
return ListTile(
leading: Icon(getEntityActionIcon(entityAction)),
title: Text(localization.lookup(entityAction.toString())),
leading: Icon(getEntityActionIcon(action)),
title: Text(localization.lookup(action.toString())),
onTap: () {
Navigator.of(context).pop();
onEntityAction(context, entities, entityAction);
final first = entities.first;
switch (first.entityType) {
case EntityType.client:
handleClientAction(context, entities, action);
break;
case EntityType.product:
handleProductAction(context, entities, action);
break;
case EntityType.invoice:
handleInvoiceAction(context, entities, action);
break;
case EntityType.payment:
handlePaymentAction(context, entities, action);
break;
case EntityType.quote:
handleQuoteAction(context, entities, action);
break;
case EntityType.task:
handleTaskAction(context, entities, action);
break;
case EntityType.project:
handleProjectAction(context, entities, action);
break;
case EntityType.vendor:
handleVendorAction(context, entities, action);
break;
case EntityType.expense:
handleExpenseAction(context, entities, action);
break;
case EntityType.companyGateway:
handleCompanyGatewayAction(context, entities, action);
break;
case EntityType.group:
handleGroupAction(context, entities, action);
break;
case EntityType.taxRate:
handleTaxRateAction(context, entities, action);
break;
case EntityType.user:
handleUserAction(context, entities, action);
break;
}
},
);
}

View File

@ -1,7 +1,9 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_state.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:timeago/timeago.dart' as timeago;
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
@ -29,9 +31,10 @@ class HistoryDrawer extends StatelessWidget {
break;
}
final entity = state.getEntityMap(history.entityType)[history.id];
final entity =
state.getEntityMap(history.entityType)[history.id] as BaseEntity;
if (entity == null) {
if (entity == null || entity.isDeleted) {
continue;
}
@ -46,10 +49,10 @@ class HistoryDrawer extends StatelessWidget {
context: context,
entityId: history.id,
entityType: history.entityType),
onLongPress: () => editEntityById(
onLongPress: () => showEntityActionsDialog(
context: context,
entityId: history.id,
entityType: history.entityType),
entities: [entity],
),
));
}

View File

@ -53,13 +53,11 @@ class ClientList extends StatelessWidget {
final isInMultiselect =
state.clientListState.isInMultiselect();
final userCompany = viewModel.state.userCompany;
void showDialog() => showEntityActionsDialog(
entities: [client],
context: context,
userCompany: userCompany,
onEntityAction: viewModel.onEntityAction);
);
return ClientListItem(
user: viewModel.state.user,

View File

@ -45,8 +45,7 @@ class ClientScreen extends StatelessWidget {
.where((client) => value != listUIState.isSelected(client.id))
.toList();
viewModel.onEntityAction(
context, clients, EntityAction.toggleMultiselect);
handleClientAction(context, clients, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.clients,
@ -92,9 +91,7 @@ class ClientScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: clients,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearClientMultiselect(context: context));
},

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/client/client_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class ClientScreenVM {
@required this.isInMultiselect,
@required this.clientList,
@required this.userCompany,
@required this.onEntityAction,
@required this.clientMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> clientList;
final Function(BuildContext, List<ClientEntity>, EntityAction) onEntityAction;
final BuiltMap<String, ClientEntity> clientMap;
static ClientScreenVM fromStore(Store<AppState> store) {
@ -52,9 +49,6 @@ class ClientScreenVM {
state.clientState.list, state.groupState.map, state.clientListState),
userCompany: state.userCompany,
isInMultiselect: state.clientListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) =>
handleClientAction(context, clients, action),
);
}
}

View File

@ -4,6 +4,7 @@ import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
@ -24,14 +25,12 @@ class CompanyGatewayList extends StatelessWidget {
final store = StoreProvider.of<AppState>(context);
final listUIState = store.state.uiState.companyGatewayUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
final userCompany = viewModel.userCompany;
void showDialog(CompanyGatewayEntity companyGateway) =>
showEntityActionsDialog(
userCompany: userCompany,
entities: [companyGateway],
context: context,
onEntityAction: viewModel.onEntityAction);
);
return Column(
children: <Widget>[
@ -71,13 +70,14 @@ class CompanyGatewayList extends StatelessWidget {
context, companyGateway),
onRemovePressed:
viewModel.state.settingsUIState.isFiltered
? () => viewModel.onRemovePressed(companyGatewayId)
? () => viewModel
.onRemovePressed(companyGatewayId)
: null,
onEntityAction: (EntityAction action) {
if (action == EntityAction.more) {
showDialog(companyGateway);
} else {
viewModel.onEntityAction(
handleCompanyGatewayAction(
context, [companyGateway], action);
}
},

View File

@ -45,7 +45,6 @@ class CompanyGatewayListVM {
@required this.onCompanyGatewayTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
@required this.onSortChanged,
@ -92,9 +91,6 @@ class CompanyGatewayListVM {
store.dispatch(ViewCompanyGateway(
companyGatewayId: companyGateway.id, context: context));
},
onEntityAction: (BuildContext context, List<BaseEntity> companyGateway,
EntityAction action) =>
handleCompanyGatewayAction(context, companyGateway, action),
onRefreshed: (context) => _handleRefresh(context),
onRemovePressed: (gatewayId) {
gatewayIds.remove(gatewayId);
@ -124,7 +120,6 @@ class CompanyGatewayListVM {
final bool isLoaded;
final Function(BuildContext, CompanyGatewayEntity) onCompanyGatewayTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
final Function(int, int) onSortChanged;

View File

@ -28,7 +28,6 @@ class CompanyGatewayScreen extends StatelessWidget {
Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final userCompany = state.userCompany;
final localization = AppLocalization.of(context);
final listUIState = state.uiState.companyGatewayUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
@ -47,7 +46,7 @@ class CompanyGatewayScreen extends StatelessWidget {
value != listUIState.isSelected(companyGateway.id))
.toList();
viewModel.onEntityAction(
handleCompanyGatewayAction(
context, companyGateways, EntityAction.toggleMultiselect);
},
isSettings: true,
@ -66,9 +65,7 @@ class CompanyGatewayScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: companyGateways,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(
@ -100,7 +97,6 @@ class CompanyGatewayScreen extends StatelessWidget {
backgroundColor: Theme.of(context).primaryColorDark,
onPressed: () {
if (state.settingsUIState.isFiltered) {
} else {
store.dispatch(EditCompanyGateway(
companyGateway: CompanyGatewayEntity(), context: context));

View File

@ -8,7 +8,6 @@ import 'package:invoiceninja_flutter/data/models/group_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_selectors.dart';
import 'package:invoiceninja_flutter/redux/group/group_actions.dart';
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
@ -39,7 +38,6 @@ class CompanyGatewayScreenVM {
@required this.isInMultiselect,
@required this.companyGatewayList,
@required this.userCompany,
@required this.onEntityAction,
@required this.companyGatewayMap,
@required this.onSavePressed,
@required this.onCancelPressed,
@ -48,7 +46,6 @@ class CompanyGatewayScreenVM {
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> companyGatewayList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, CompanyGatewayEntity> companyGatewayMap;
final Function(BuildContext) onSavePressed;
final Function(BuildContext) onCancelPressed;
@ -67,9 +64,6 @@ class CompanyGatewayScreenVM {
),
userCompany: state.userCompany,
isInMultiselect: state.companyGatewayListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> companyGateways,
EntityAction action) =>
handleCompanyGatewayAction(context, companyGateways, action),
onCancelPressed: (context) => store.dispatch(ResetSettings()),
onSavePressed: (context) {
final settingsUIState = state.uiState.settingsUIState;

View File

@ -54,8 +54,7 @@ class DocumentList extends StatelessWidget {
void showDialog() => showEntityActionsDialog(
entities: [document],
context: context,
userCompany: userCompany,
onEntityAction: viewModel.onEntityAction);
);
return DocumentListItem(
userCompany: userCompany,

View File

@ -45,7 +45,7 @@ class DocumentScreen extends StatelessWidget {
.where((document) => value != listUIState.isSelected(document.id))
.toList();
viewModel.onEntityAction(
handleDocumentAction(
context, documents, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
@ -93,9 +93,7 @@ class DocumentScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: documents,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearDocumentMultiselect(context: context));
},

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/document/document_actions.dart';
import 'package:invoiceninja_flutter/redux/document/document_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class DocumentScreenVM {
@required this.isInMultiselect,
@required this.documentList,
@required this.userCompany,
@required this.onEntityAction,
@required this.documentMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> documentList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, DocumentEntity> documentMap;
static DocumentScreenVM fromStore(Store<AppState> store) {
@ -52,9 +49,6 @@ class DocumentScreenVM {
state.documentState.list, state.documentListState),
userCompany: state.userCompany,
isInMultiselect: state.documentListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> documents,
EntityAction action) =>
handleDocumentAction(context, documents, action),
);
}
}

View File

@ -4,6 +4,7 @@ import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/document/document_selectors.dart';
import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
@ -64,9 +65,8 @@ class ExpenseList extends StatelessWidget {
void showDialog() => showEntityActionsDialog(
entities: [expense],
context: context,
userCompany: state.userCompany,
client: client,
onEntityAction: viewModel.onEntityAction);
);
return ExpenseListItem(
userCompany: viewModel.state.userCompany,
@ -80,8 +80,7 @@ class ExpenseList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
context, [expense], action);
handleExpenseAction(context, [expense], action);
}
},
onLongPress: () async {
@ -89,7 +88,7 @@ class ExpenseList extends StatelessWidget {
.longPressSelectionIsDefault ??
true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(context, [expense],
handleExpenseAction(context, [expense],
EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -43,7 +43,6 @@ class ExpenseListVM {
@required this.onExpenseTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
});
@ -84,9 +83,6 @@ class ExpenseListVM {
onExpenseTap: (context, expense) {
store.dispatch(ViewExpense(expenseId: expense.id, context: context));
},
onEntityAction: (BuildContext context, List<BaseEntity> expenses,
EntityAction action) =>
handleExpenseAction(context, expenses, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
@ -101,8 +97,6 @@ class ExpenseListVM {
final bool isLoaded;
final Function(BuildContext, ExpenseEntity) onExpenseTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<ExpenseEntity>, EntityAction)
onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
}

View File

@ -46,8 +46,7 @@ class ExpenseScreen extends StatelessWidget {
.where((expense) => value != listUIState.isSelected(expense.id))
.toList();
viewModel.onEntityAction(
context, expenses, EntityAction.toggleMultiselect);
handleExpenseAction(context, expenses, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.expenses,
@ -94,9 +93,7 @@ class ExpenseScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: expenses,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearExpenseMultiselect(context: context));
},

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart';
import 'package:invoiceninja_flutter/redux/expense/expense_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class ExpenseScreenVM {
@required this.isInMultiselect,
@required this.expenseList,
@required this.userCompany,
@required this.onEntityAction,
@required this.expenseMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> expenseList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, ExpenseEntity> expenseMap;
static ExpenseScreenVM fromStore(Store<AppState> store) {
@ -56,9 +53,6 @@ class ExpenseScreenVM {
state.expenseListState),
userCompany: state.userCompany,
isInMultiselect: state.expenseListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> expenses,
EntityAction action) =>
handleExpenseAction(context, expenses, action),
);
}
}

View File

@ -59,7 +59,6 @@ class ExpenseViewVM {
factory ExpenseViewVM.fromStore(Store<AppState> store) {
final state = store.state;
final userCompany = state.userCompany;
final expense = state.expenseState.map[state.expenseUIState.selectedId] ??
ExpenseEntity(id: state.expenseUIState.selectedId);
final vendor = state.vendorState.map[expense.vendorId];
@ -103,12 +102,9 @@ class ExpenseViewVM {
case EntityType.vendor:
if (longPress) {
showEntityActionsDialog(
userCompany: userCompany,
context: context,
entities: [vendor],
onEntityAction: (BuildContext context,
List<BaseEntity> vendors, EntityAction action) =>
handleVendorAction(context, vendors, action));
);
} else {
store.dispatch(
ViewVendor(vendorId: vendor.id, context: context));
@ -116,13 +112,7 @@ class ExpenseViewVM {
break;
case EntityType.client:
if (longPress) {
showEntityActionsDialog(
userCompany: userCompany,
context: context,
entities: [client],
onEntityAction: (BuildContext context,
List<BaseEntity> clients, EntityAction action) =>
handleClientAction(context, clients, action));
showEntityActionsDialog(context: context, entities: [client]);
} else {
store.dispatch(
ViewClient(clientId: client.id, context: context));
@ -131,13 +121,7 @@ class ExpenseViewVM {
case EntityType.invoice:
if (longPress) {
showEntityActionsDialog(
userCompany: userCompany,
context: context,
entities: [invoice],
client: client,
onEntityAction: (BuildContext context,
List<BaseEntity> invoices, EntityAction action) =>
handleInvoiceAction(context, invoices, action));
context: context, entities: [invoice], client: client);
} else {
store.dispatch(
ViewInvoice(invoiceId: invoice.id, context: context));

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/group/group_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
@ -48,13 +49,11 @@ class GroupList extends StatelessWidget {
itemBuilder: (BuildContext context, index) {
final groupId = viewModel.groupList[index];
final group = viewModel.groupMap[groupId];
final userCompany = viewModel.userCompany;
void showDialog() => showEntityActionsDialog(
userCompany: userCompany,
entities: [group],
context: context,
onEntityAction: viewModel.onEntityAction);
);
return GroupListItem(
user: viewModel.userCompany.user,
@ -65,8 +64,7 @@ class GroupList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
context, [group], action);
handleGroupAction(context, [group], action);
}
},
onLongPress: () async {
@ -74,7 +72,7 @@ class GroupList extends StatelessWidget {
.longPressSelectionIsDefault ??
true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(context, [group],
handleGroupAction(context, [group],
EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -44,7 +44,6 @@ class GroupListVM {
@required this.onGroupTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
});
@ -79,9 +78,6 @@ class GroupListVM {
onGroupTap: (context, group) {
store.dispatch(ViewGroup(groupId: group.id, context: context));
},
onEntityAction: (BuildContext context, List<BaseEntity> groups,
EntityAction action) =>
handleGroupAction(context, groups, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
@ -95,7 +91,6 @@ class GroupListVM {
final bool isLoaded;
final Function(BuildContext, GroupEntity) onGroupTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
}

View File

@ -30,7 +30,6 @@ class GroupSettingsScreen extends StatelessWidget {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final company = state.selectedCompany;
final userCompany = state.userCompany;
final localization = AppLocalization.of(context);
final listUIState = state.uiState.groupUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
@ -47,8 +46,7 @@ class GroupSettingsScreen extends StatelessWidget {
.where((group) => value != listUIState.isSelected(group.id))
.toList();
viewModel.onEntityAction(
context, groups, EntityAction.toggleMultiselect);
handleGroupAction(context, groups, EntityAction.toggleMultiselect);
},
isSettings: true,
appBarTitle: ListFilter(
@ -96,9 +94,7 @@ class GroupSettingsScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: groups,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearGroupMultiselect(context: context));
},

View File

@ -6,7 +6,6 @@ import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/group_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/group/group_actions.dart';
import 'package:invoiceninja_flutter/redux/group/group_selectors.dart';
import 'package:redux/redux.dart';
@ -34,14 +33,12 @@ class GroupScreenVM {
@required this.isInMultiselect,
@required this.groupList,
@required this.userCompany,
@required this.onEntityAction,
@required this.groupMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> groupList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, GroupEntity> groupMap;
static GroupScreenVM fromStore(Store<AppState> store) {
@ -53,9 +50,6 @@ class GroupScreenVM {
state.groupState.map, state.groupState.list, state.groupListState),
userCompany: state.userCompany,
isInMultiselect: state.groupListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> groups,
EntityAction action) =>
handleGroupAction(context, groups, action),
);
}
}

View File

@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/document/document_selectors.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
@ -58,9 +59,8 @@ class InvoiceList extends StatelessWidget {
void showDialog() => showEntityActionsDialog(
entities: [invoice],
context: context,
userCompany: state.userCompany,
client: client,
onEntityAction: viewModel.onEntityAction);
);
return InvoiceListItem(
user: viewModel.user,
@ -75,7 +75,7 @@ class InvoiceList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
handleInvoiceAction(
context, [invoice], action);
}
},
@ -84,7 +84,7 @@ class InvoiceList extends StatelessWidget {
state.uiState.longPressSelectionIsDefault ??
true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(context, [invoice],
handleInvoiceAction(context, [invoice],
EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -48,7 +48,6 @@ class EntityListVM {
@required this.onRefreshed,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
@required this.onEntityAction,
});
final AppState state;
@ -64,8 +63,6 @@ class EntityListVM {
final Function(BuildContext) onRefreshed;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
final Function(BuildContext, List<InvoiceEntity>, EntityAction)
onEntityAction;
}
class InvoiceListVM extends EntityListVM {
@ -98,7 +95,6 @@ class InvoiceListVM extends EntityListVM {
onRefreshed: onRefreshed,
onClearEntityFilterPressed: onClearEntityFilterPressed,
onViewEntityFilterPressed: onViewEntityFilterPressed,
onEntityAction: onEntityAction,
);
static InvoiceListVM fromStore(Store<AppState> store) {

View File

@ -46,8 +46,7 @@ class InvoiceScreen extends StatelessWidget {
.where((invoice) => value != listUIState.isSelected(invoice.id))
.toList();
viewModel.onEntityAction(
context, invoices, EntityAction.toggleMultiselect);
handleInvoiceAction(context, invoices, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.invoices,
@ -94,9 +93,7 @@ class InvoiceScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: invoices,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearInvoiceMultiselect(context: context));
},

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class InvoiceScreenVM {
@required this.isInMultiselect,
@required this.invoiceList,
@required this.userCompany,
@required this.onEntityAction,
@required this.invoiceMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> invoiceList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, InvoiceEntity> invoiceMap;
static InvoiceScreenVM fromStore(Store<AppState> store) {
@ -55,9 +52,6 @@ class InvoiceScreenVM {
state.invoiceListState),
userCompany: state.userCompany,
isInMultiselect: state.invoiceListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> invoices,
EntityAction action) =>
handleInvoiceAction(context, invoices, action),
);
}
}

View File

@ -157,12 +157,9 @@ class InvoiceViewVM extends EntityViewVM {
onClientPressed: (BuildContext context, [bool longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
entities: [client],
onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) =>
handleClientAction(context, clients, action));
);
} else {
store.dispatch(ViewClient(clientId: client.id, context: context));
}
@ -171,13 +168,10 @@ class InvoiceViewVM extends EntityViewVM {
[bool longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
client: client,
entities: [payment],
onEntityAction: (BuildContext context, List<BaseEntity> payments,
EntityAction action) =>
handlePaymentAction(context, payments, action));
);
} else {
store.dispatch(ViewPayment(paymentId: payment.id, context: context));
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_selectors.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
@ -57,9 +58,8 @@ class PaymentList extends StatelessWidget {
void showDialog() => showEntityActionsDialog(
entities: [payment],
context: context,
userCompany: state.userCompany,
client: client,
onEntityAction: viewModel.onEntityAction);
);
return PaymentListItem(
user: viewModel.user,
@ -71,7 +71,7 @@ class PaymentList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
handlePaymentAction(
context, [payment], action);
}
},
@ -80,7 +80,7 @@ class PaymentList extends StatelessWidget {
state.uiState.longPressSelectionIsDefault ??
true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(context, [payment],
handlePaymentAction(context, [payment],
EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -43,7 +43,6 @@ class PaymentListVM {
@required this.isLoaded,
@required this.onPaymentTap,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
@required this.listState,
@ -79,9 +78,6 @@ class PaymentListVM {
onPaymentTap: (context, payment) {
store.dispatch(ViewPayment(paymentId: payment.id, context: context));
},
onEntityAction: (BuildContext context, List<BaseEntity> payments,
EntityAction action) =>
handlePaymentAction(context, payments, action),
onClearEntityFilterPressed: () =>
store.dispatch(FilterPaymentsByEntity()),
onViewEntityFilterPressed: (BuildContext context) => viewEntityById(
@ -104,6 +100,4 @@ class PaymentListVM {
final Function(BuildContext) onRefreshed;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
final Function(BuildContext, List<PaymentEntity>, EntityAction)
onEntityAction;
}

View File

@ -42,8 +42,7 @@ class PaymentScreen extends StatelessWidget {
.where((payment) => value != listUIState.isSelected(payment.id))
.toList();
viewModel.onEntityAction(
context, payments, EntityAction.toggleMultiselect);
handlePaymentAction(context, payments, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.payments,
@ -90,9 +89,7 @@ class PaymentScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: payments,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearPaymentMultiselect(context: context));
},

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class PaymentScreenVM {
@required this.isInMultiselect,
@required this.paymentList,
@required this.userCompany,
@required this.onEntityAction,
@required this.paymentMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> paymentList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, PaymentEntity> paymentMap;
static PaymentScreenVM fromStore(Store<AppState> store) {
@ -56,9 +53,6 @@ class PaymentScreenVM {
state.paymentListState),
userCompany: state.userCompany,
isInMultiselect: state.paymentListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> payments,
EntityAction action) =>
handlePaymentAction(context, payments, action),
);
}
}

View File

@ -66,13 +66,7 @@ class PaymentViewVM {
},
onClientPressed: (context, [bool longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
entities: [client],
onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) =>
handleClientAction(context, clients, action));
showEntityActionsDialog(context: context, entities: [client]);
} else {
store.dispatch(ViewClient(clientId: client.id, context: context));
}
@ -80,13 +74,10 @@ class PaymentViewVM {
onInvoicePressed: (context, [bool longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
entities: [invoice],
client: client,
onEntityAction: (BuildContext context, List<BaseEntity> invoice,
EntityAction action) =>
handleInvoiceAction(context, invoice, action));
);
} else {
store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context));
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/product/product_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
@ -47,8 +48,7 @@ class ProductList extends StatelessWidget {
void showDialog() => showEntityActionsDialog(
entities: [product],
context: context,
userCompany: viewModel.state.userCompany,
onEntityAction: viewModel.onEntityAction);
);
return ProductListItem(
userCompany: viewModel.state.userCompany,
@ -58,7 +58,7 @@ class ProductList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(context, [product], action);
handleProductAction(context, [product], action);
}
},
onTap: () => viewModel.onProductTap(context, product),
@ -66,7 +66,7 @@ class ProductList extends StatelessWidget {
final longPressIsSelection =
store.state.uiState.longPressSelectionIsDefault ?? true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(
handleProductAction(
context, [product], EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -40,7 +40,6 @@ class ProductListVM {
@required this.isLoaded,
@required this.onProductTap,
@required this.onRefreshed,
@required this.onEntityAction,
});
static ProductListVM fromStore(Store<AppState> store) {
@ -67,9 +66,6 @@ class ProductListVM {
onProductTap: (context, product) {
store.dispatch(ViewProduct(productId: product.id, context: context));
},
onEntityAction: (BuildContext context, List<BaseEntity> products,
EntityAction action) =>
handleProductAction(context, products, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
@ -82,5 +78,4 @@ class ProductListVM {
final bool isLoaded;
final Function(BuildContext, ProductEntity) onProductTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
}

View File

@ -44,8 +44,7 @@ class ProductScreen extends StatelessWidget {
.where((product) => value != listUIState.isSelected(product.id))
.toList();
viewModel.onEntityAction(
context, products, EntityAction.toggleMultiselect);
handleProductAction(context, products, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.products,
@ -92,9 +91,7 @@ class ProductScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: products,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearProductMultiselect(context: context));
},

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/product/product_actions.dart';
import 'package:invoiceninja_flutter/redux/product/product_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class ProductScreenVM {
@required this.isInMultiselect,
@required this.productList,
@required this.userCompany,
@required this.onEntityAction,
@required this.productMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> productList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, ProductEntity> productMap;
static ProductScreenVM fromStore(Store<AppState> store) {
@ -52,9 +49,6 @@ class ProductScreenVM {
state.productState.list, state.productListState),
userCompany: state.userCompany,
isInMultiselect: state.productListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> products,
EntityAction action) =>
handleProductAction(context, products, action),
);
}
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/project/project_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
@ -56,9 +57,8 @@ class ProjectList extends StatelessWidget {
void showDialog() => showEntityActionsDialog(
entities: [project],
context: context,
userCompany: viewModel.state.userCompany,
client: client,
onEntityAction: viewModel.onEntityAction);
);
return ProjectListItem(
userCompany: viewModel.state.userCompany,
@ -72,7 +72,7 @@ class ProjectList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
handleProjectAction(
context, [project], action);
}
},
@ -81,7 +81,7 @@ class ProjectList extends StatelessWidget {
.longPressSelectionIsDefault ??
true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(context, [project],
handleProjectAction(context, [project],
EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -44,7 +44,6 @@ class ProjectListVM {
@required this.isLoaded,
@required this.onProjectTap,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
});
@ -84,9 +83,6 @@ class ProjectListVM {
onProjectTap: (context, project) {
store.dispatch(ViewProject(projectId: project.id, context: context));
},
onEntityAction: (BuildContext context, List<BaseEntity> projects,
EntityAction action) =>
handleProjectAction(context, projects, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
@ -101,8 +97,6 @@ class ProjectListVM {
final bool isLoaded;
final Function(BuildContext, ProjectEntity) onProjectTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<ProjectEntity>, EntityAction)
onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
}

View File

@ -44,8 +44,7 @@ class ProjectScreen extends StatelessWidget {
.where((project) => value != listUIState.isSelected(project.id))
.toList();
viewModel.onEntityAction(
context, projects, EntityAction.toggleMultiselect);
handleProjectAction(context, projects, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.projects,
@ -92,9 +91,7 @@ class ProjectScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: projects,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearProjectMultiselect(context: context));
},

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/project/project_actions.dart';
import 'package:invoiceninja_flutter/redux/project/project_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class ProjectScreenVM {
@required this.isInMultiselect,
@required this.projectList,
@required this.userCompany,
@required this.onEntityAction,
@required this.projectMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> projectList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, ProjectEntity> projectMap;
static ProjectScreenVM fromStore(Store<AppState> store) {
@ -55,9 +52,6 @@ class ProjectScreenVM {
state.clientState.map),
userCompany: state.userCompany,
isInMultiselect: state.projectListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> projects,
EntityAction action) =>
handleProjectAction(context, projects, action),
);
}
}

View File

@ -81,12 +81,8 @@ class ProjectViewVM {
onClientPressed: (BuildContext context, [bool longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
entities: [client],
onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) =>
handleClientAction(context, clients, action));
entities: [client],);
} else {
store.dispatch(ViewClient(clientId: client.id, context: context));
}

View File

@ -64,7 +64,6 @@ class QuoteListVM extends EntityListVM {
onRefreshed: onRefreshed,
onClearEntityFilterPressed: onClearEntityFilterPressed,
onViewEntityFilterPressed: onViewEntityFilterPressed,
onEntityAction: onEntityAction,
);
static QuoteListVM fromStore(Store<AppState> store) {

View File

@ -46,8 +46,7 @@ class QuoteScreen extends StatelessWidget {
.where((quote) => value != listUIState.isSelected(quote.id))
.toList();
viewModel.onEntityAction(
context, quotes, EntityAction.toggleMultiselect);
handleQuoteAction(context, quotes, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.quotes,
@ -93,11 +92,7 @@ class QuoteScreen extends StatelessWidget {
.toList();
await showEntityActionsDialog(
entities: quotes,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
entities: quotes, context: context, multiselect: true);
store.dispatch(ClearQuoteMultiselect(context: context));
},
),

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_actions.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class QuoteScreenVM {
@required this.isInMultiselect,
@required this.quoteList,
@required this.userCompany,
@required this.onEntityAction,
@required this.quoteMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> quoteList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, InvoiceEntity> quoteMap;
static QuoteScreenVM fromStore(Store<AppState> store) {
@ -52,9 +49,6 @@ class QuoteScreenVM {
state.quoteState.list, state.clientState.map, state.quoteListState),
userCompany: state.userCompany,
isInMultiselect: state.quoteListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> quotes,
EntityAction action) =>
handleQuoteAction(context, quotes, action),
);
}
}

View File

@ -122,12 +122,9 @@ class QuoteViewVM extends EntityViewVM {
onClientPressed: (BuildContext context, [bool longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
entities: [client],
onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) =>
handleClientAction(context, clients, action));
);
} else {
store.dispatch(ViewClient(clientId: client.id, context: context));
}

View File

@ -1,6 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/task/task_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
@ -54,9 +55,8 @@ class TaskList extends StatelessWidget {
void showDialog() => showEntityActionsDialog(
entities: [task],
context: context,
userCompany: state.userCompany,
client: client,
onEntityAction: viewModel.onEntityAction);
);
return TaskListItem(
userCompany: state.userCompany,
@ -71,8 +71,7 @@ class TaskList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
context, [task], action);
handleTaskAction(context, [task], action);
}
},
onLongPress: () async {
@ -80,7 +79,7 @@ class TaskList extends StatelessWidget {
state.uiState.longPressSelectionIsDefault ??
true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(context, [task],
handleTaskAction(context, [task],
EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -45,7 +45,6 @@ class TaskListVM {
@required this.onTaskTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
});
@ -86,9 +85,6 @@ class TaskListVM {
onTaskTap: (context, task) {
store.dispatch(ViewTask(taskId: task.id, context: context));
},
onEntityAction:
(BuildContext context, List<BaseEntity> tasks, EntityAction action) =>
handleTaskAction(context, tasks, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
@ -104,7 +100,6 @@ class TaskListVM {
final bool isLoaded;
final Function(BuildContext, TaskEntity) onTaskTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<TaskEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
}

View File

@ -45,8 +45,7 @@ class TaskScreen extends StatelessWidget {
.where((task) => value != listUIState.isSelected(task.id))
.toList();
viewModel.onEntityAction(
context, tasks, EntityAction.toggleMultiselect);
handleTaskAction(context, tasks, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.tasks,
@ -92,9 +91,7 @@ class TaskScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: tasks,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearTaskMultiselect(context: context));
},

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/task/task_actions.dart';
import 'package:invoiceninja_flutter/redux/task/task_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class TaskScreenVM {
@required this.isInMultiselect,
@required this.taskList,
@required this.userCompany,
@required this.onEntityAction,
@required this.taskMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> taskList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, TaskEntity> taskMap;
static TaskScreenVM fromStore(Store<AppState> store) {
@ -56,9 +53,6 @@ class TaskScreenVM {
state.taskListState),
userCompany: state.userCompany,
isInMultiselect: state.taskListState.isInMultiselect(),
onEntityAction:
(BuildContext context, List<BaseEntity> tasks, EntityAction action) =>
handleTaskAction(context, tasks, action),
);
}
}

View File

@ -110,12 +110,9 @@ class TaskViewVM {
onClientPressed: (BuildContext context, [bool longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
entities: [client],
onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) =>
handleClientAction(context, clients, action));
);
} else {
store.dispatch(ViewClient(clientId: client.id, context: context));
}
@ -123,13 +120,10 @@ class TaskViewVM {
onProjectPressed: (context, [longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
entities: [project],
client: client,
onEntityAction: (BuildContext context, List<BaseEntity> projects,
EntityAction action) =>
handleProjectAction(context, projects, action));
);
} else {
store.dispatch(ViewProject(projectId: project.id, context: context));
}
@ -137,13 +131,10 @@ class TaskViewVM {
onInvoicePressed: (context, [longPress = false]) {
if (longPress) {
showEntityActionsDialog(
userCompany: state.userCompany,
context: context,
entities: [invoice],
client: client,
onEntityAction: (BuildContext context, List<BaseEntity> invoices,
EntityAction action) =>
handleInvoiceAction(context, invoices, action));
);
} else {
store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context));
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
@ -41,13 +42,11 @@ class TaxRateList extends StatelessWidget {
itemBuilder: (BuildContext context, index) {
final taxRateId = viewModel.taxRateList[index];
final taxRate = viewModel.taxRateMap[taxRateId];
final userCompany = viewModel.userCompany;
void showDialog() => showEntityActionsDialog(
userCompany: userCompany,
entities: [taxRate],
context: context,
onEntityAction: viewModel.onEntityAction);
);
return TaxRateListItem(
user: viewModel.userCompany.user,
@ -59,7 +58,7 @@ class TaxRateList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
handleTaxRateAction(
context, [taxRate], action);
}
},
@ -68,7 +67,7 @@ class TaxRateList extends StatelessWidget {
.longPressSelectionIsDefault ??
true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(context, [taxRate],
handleTaxRateAction(context, [taxRate],
EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -43,7 +43,6 @@ class TaxRateListVM {
@required this.onTaxRateTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
});
@ -79,9 +78,6 @@ class TaxRateListVM {
onTaxRateTap: (context, taxRate) {
store.dispatch(ViewTaxRate(taxRateId: taxRate.id, context: context));
},
onEntityAction: (BuildContext context, List<BaseEntity> taxRates,
EntityAction action) =>
handleTaxRateAction(context, taxRates, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
@ -95,8 +91,6 @@ class TaxRateListVM {
final bool isLoaded;
final Function(BuildContext, TaxRateEntity) onTaxRateTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<TaxRateEntity>, EntityAction)
onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
}

View File

@ -28,7 +28,6 @@ class TaxRateSettingsScreen extends StatelessWidget {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final localization = AppLocalization.of(context);
final userCompany = state.userCompany;
final listUIState = state.uiState.taxRateUIState.listUIState;
final isInMultiselect = listUIState.isInMultiselect();
@ -45,8 +44,7 @@ class TaxRateSettingsScreen extends StatelessWidget {
.where((taxRate) => value != listUIState.isSelected(taxRate.id))
.toList();
viewModel.onEntityAction(
context, taxRates, EntityAction.toggleMultiselect);
handleTaxRateAction(context, taxRates, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.taxRates,
@ -91,9 +89,7 @@ class TaxRateSettingsScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: taxRates,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearTaxRateMultiselect(context: context));
},

View File

@ -7,7 +7,6 @@ import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_actions.dart';
import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_selectors.dart';
import 'package:invoiceninja_flutter/ui/tax_rate/tax_rate_screen.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
@ -35,7 +34,6 @@ class TaxRateScreenVM {
@required this.isInMultiselect,
@required this.taxRateList,
@required this.userCompany,
@required this.onEntityAction,
@required this.onBackPressed,
@required this.taxRateMap,
});
@ -43,7 +41,6 @@ class TaxRateScreenVM {
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> taxRateList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final Function(BuildContext) onBackPressed;
final BuiltMap<String, TaxRateEntity> taxRateMap;
@ -56,9 +53,6 @@ class TaxRateScreenVM {
state.taxRateState.list, state.taxRateListState),
userCompany: state.userCompany,
isInMultiselect: state.taxRateListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> taxRates,
EntityAction action) =>
handleTaxRateAction(context, taxRates, action),
onBackPressed: (context) {
if (isMobile(context)) {
Navigator.pop(context);

View File

@ -1,6 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/user/user_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
@ -46,13 +47,11 @@ class UserList extends StatelessWidget {
itemBuilder: (BuildContext context, index) {
final userId = viewModel.userList[index];
final user = viewModel.userMap[userId];
final userCompany = viewModel.userCompany;
void showDialog() => showEntityActionsDialog(
userCompany: userCompany,
entities: [user],
context: context,
onEntityAction: viewModel.onEntityAction);
);
return UserListItem(
user: user,
@ -62,8 +61,7 @@ class UserList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
context, [user], action);
handleUserAction(context, [user], action);
}
},
onLongPress: () => showDialog(),

View File

@ -43,7 +43,6 @@ class UserListVM {
@required this.onUserTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
});
@ -78,9 +77,6 @@ class UserListVM {
onUserTap: (context, user) {
store.dispatch(ViewUser(userId: user.id, context: context));
},
onEntityAction:
(BuildContext context, List<BaseEntity> users, EntityAction action) =>
handleUserAction(context, users, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
@ -94,7 +90,6 @@ class UserListVM {
final bool isLoaded;
final Function(BuildContext, UserEntity) onUserTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
}

View File

@ -95,9 +95,7 @@ class UserScreen extends StatelessWidget {
await showEntityActionsDialog(
entities: users,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
store.dispatch(ClearUserMultiselect(context: context));
},

View File

@ -6,7 +6,6 @@ import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/user_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/user/user_actions.dart';
import 'package:invoiceninja_flutter/redux/user/user_selectors.dart';
import 'package:redux/redux.dart';
import 'user_screen.dart';
@ -33,14 +32,12 @@ class UserScreenVM {
@required this.isInMultiselect,
@required this.userList,
@required this.userCompany,
@required this.onEntityAction,
@required this.userMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> userList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, UserEntity> userMap;
static UserScreenVM fromStore(Store<AppState> store) {
@ -52,9 +49,6 @@ class UserScreenVM {
state.userState.map, state.userState.list, state.userListState),
userCompany: state.userCompany,
isInMultiselect: state.userListState.isInMultiselect(),
onEntityAction:
(BuildContext context, List<BaseEntity> users, EntityAction action) =>
handleUserAction(context, users, action),
);
}
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
@ -39,15 +40,13 @@ class VendorList extends StatelessWidget {
separatorBuilder: (context, index) => ListDivider(),
itemCount: viewModel.vendorList.length,
itemBuilder: (BuildContext context, index) {
final userCompany = viewModel.state.userCompany;
final vendorId = viewModel.vendorList[index];
final vendor = viewModel.vendorMap[vendorId];
void showDialog() => showEntityActionsDialog(
entities: [vendor],
context: context,
userCompany: userCompany,
onEntityAction: viewModel.onEntityAction);
);
return VendorListItem(
userCompany: viewModel.state.userCompany,
@ -59,8 +58,7 @@ class VendorList extends StatelessWidget {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
context, [vendor], action);
handleVendorAction(context, [vendor], action);
}
},
onLongPress: () async {
@ -68,7 +66,7 @@ class VendorList extends StatelessWidget {
.longPressSelectionIsDefault ??
true;
if (longPressIsSelection && !isInMultiselect) {
viewModel.onEntityAction(context, [vendor],
handleVendorAction(context, [vendor],
EntityAction.toggleMultiselect);
} else {
showDialog();

View File

@ -42,7 +42,6 @@ class VendorListVM {
@required this.onVendorTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
});
@ -77,9 +76,6 @@ class VendorListVM {
onVendorTap: (context, vendor) {
store.dispatch(ViewVendor(vendorId: vendor.id, context: context));
},
onEntityAction: (BuildContext context, List<BaseEntity> vendors,
EntityAction action) =>
handleVendorAction(context, vendors, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
@ -93,7 +89,6 @@ class VendorListVM {
final bool isLoaded;
final Function(BuildContext, VendorEntity) onVendorTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, List<VendorEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
}

View File

@ -44,8 +44,7 @@ class VendorScreen extends StatelessWidget {
.where((vendor) => value != listUIState.isSelected(vendor.id))
.toList();
viewModel.onEntityAction(
context, vendors, EntityAction.toggleMultiselect);
handleVendorAction(context, vendors, EntityAction.toggleMultiselect);
},
appBarTitle: ListFilter(
title: localization.vendors,
@ -91,11 +90,7 @@ class VendorScreen extends StatelessWidget {
.toList();
await showEntityActionsDialog(
entities: vendors,
userCompany: userCompany,
context: context,
onEntityAction: viewModel.onEntityAction,
multiselect: true);
entities: vendors, context: context, multiselect: true);
store.dispatch(ClearVendorMultiselect(context: context));
},
),

View File

@ -5,7 +5,6 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_selectors.dart';
import 'package:redux/redux.dart';
@ -33,14 +32,12 @@ class VendorScreenVM {
@required this.isInMultiselect,
@required this.vendorList,
@required this.userCompany,
@required this.onEntityAction,
@required this.vendorMap,
});
final bool isInMultiselect;
final UserCompanyEntity userCompany;
final List<String> vendorList;
final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
final BuiltMap<String, VendorEntity> vendorMap;
static VendorScreenVM fromStore(Store<AppState> store) {
@ -52,9 +49,6 @@ class VendorScreenVM {
state.vendorState.map, state.vendorState.list, state.vendorListState),
userCompany: state.userCompany,
isInMultiselect: state.vendorListState.isInMultiselect(),
onEntityAction: (BuildContext context, List<BaseEntity> vendors,
EntityAction action) =>
handleVendorAction(context, vendors, action),
);
}
}