diff --git a/lib/data/repositories/client_repository.dart b/lib/data/repositories/client_repository.dart index 065ef349b..5fcb94f24 100644 --- a/lib/data/repositories/client_repository.dart +++ b/lib/data/repositories/client_repository.dart @@ -1,12 +1,13 @@ import 'dart:async'; import 'dart:convert'; import 'dart:core'; -import 'package:invoiceninja_flutter/constants.dart'; -import 'package:invoiceninja_flutter/data/models/serializers.dart'; + import 'package:built_collection/built_collection.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/models/serializers.dart'; import 'package:invoiceninja_flutter/data/web_client.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; class ClientRepository { const ClientRepository({ @@ -47,8 +48,34 @@ class ClientRepository { return clientResponse.data; } - Future saveData(Credentials credentials, ClientEntity client, - [EntityAction action]) async { + Future> bulkAction( + Credentials credentials, List ids, EntityAction action) async { + dynamic response; + + switch (action) { + case EntityAction.restore: + case EntityAction.archive: + case EntityAction.delete: + var url = credentials.url + '/clients/bulk?include=activities'; + if (action != null) { + url += '&action=' + action.toString(); + } + response = + await webClient.put(url, credentials.token, json.encode([ids])); + break; + default: + // Might have other actions in the future + break; + } + + final ClientListResponse clientResponse = + serializers.deserializeWith(ClientListResponse.serializer, response); + + return clientResponse.data.toList(); + } + + Future saveData( + Credentials credentials, ClientEntity client) async { final data = serializers.serializeWith(ClientEntity.serializer, client); dynamic response; diff --git a/lib/redux/client/client_actions.dart b/lib/redux/client/client_actions.dart index 360d6c79a..913d4e0dd 100644 --- a/lib/redux/client/client_actions.dart +++ b/lib/redux/client/client_actions.dart @@ -175,60 +175,60 @@ class SaveClientFailure implements StopSaving { } class ArchiveClientRequest implements StartSaving { - ArchiveClientRequest(this.completer, this.clientId); + ArchiveClientRequest(this.completer, this.clientIds); final Completer completer; - final String clientId; + final List clientIds; } class ArchiveClientSuccess implements StopSaving, PersistData { - ArchiveClientSuccess(this.client); + ArchiveClientSuccess(this.clients); - final ClientEntity client; + final List clients; } class ArchiveClientFailure implements StopSaving { - ArchiveClientFailure(this.client); + ArchiveClientFailure(this.clients); - final ClientEntity client; + final List clients; } class DeleteClientRequest implements StartSaving { - DeleteClientRequest(this.completer, this.clientId); + DeleteClientRequest(this.completer, this.clientIds); final Completer completer; - final String clientId; + final List clientIds; } class DeleteClientSuccess implements StopSaving, PersistData { - DeleteClientSuccess(this.client); + DeleteClientSuccess(this.clients); - final ClientEntity client; + final List clients; } class DeleteClientFailure implements StopSaving { - DeleteClientFailure(this.client); + DeleteClientFailure(this.clients); - final ClientEntity client; + final List clients; } class RestoreClientRequest implements StartSaving { - RestoreClientRequest(this.completer, this.clientId); + RestoreClientRequest(this.completer, this.clientIds); final Completer completer; - final String clientId; + final List clientIds; } class RestoreClientSuccess implements StopSaving, PersistData { - RestoreClientSuccess(this.client); + RestoreClientSuccess(this.clients); - final ClientEntity client; + final List clients; } class RestoreClientFailure implements StopSaving { - RestoreClientFailure(this.client); + RestoreClientFailure(this.clients); - final ClientEntity client; + final List clients; } class FilterClients { @@ -269,71 +269,64 @@ class FilterClientsByCustom2 implements PersistUI { } void handleClientAction( - BuildContext context, ClientEntity client, EntityAction action) { + BuildContext context, List clients, EntityAction action) { + assert( + [EntityAction.restore, EntityAction.archive, EntityAction.delete] + .contains(action) || + clients.length == 1, + 'Cannot perform this action on more than one client'); final store = StoreProvider.of(context); final state = store.state; final CompanyEntity company = state.selectedCompany; final localization = AppLocalization.of(context); - final multiselect = state.clientListState.isInMultiselect(); - final isMultiselectLast = - client == state.clientListState.selectedEntities.last; + final clientIds = clients.map((client) => client.id).toList(); switch (action) { case EntityAction.edit: - store.dispatch(EditClient(context: context, client: client)); + store.dispatch(EditClient(context: context, client: clients[0])); break; case EntityAction.newInvoice: store.dispatch(EditInvoice( invoice: InvoiceEntity(company: company) - .rebuild((b) => b.clientId = client.id), + .rebuild((b) => b.clientId = clients[0].id), context: context)); break; case EntityAction.newExpense: store.dispatch(EditExpense( expense: ExpenseEntity( - company: company, client: client, uiState: state.uiState), + company: company, client: clients[0], uiState: state.uiState), context: context)); break; case EntityAction.enterPayment: store.dispatch(EditPayment( payment: PaymentEntity(company: company) - .rebuild((b) => b.clientId = client.id), + .rebuild((b) => b.clientId = clients[0].id), context: context)); break; case EntityAction.restore: - if (multiselect && !isMultiselectLast) { - store.dispatch(RestoreClientRequest(null, client.id)); - } else { - store.dispatch(RestoreClientRequest( - snackBarCompleter(context, localization.restoredClient), - client.id)); - } + store.dispatch(RestoreClientRequest( + snackBarCompleter(context, localization.restoredClient), clientIds)); break; case EntityAction.archive: - if (multiselect && !isMultiselectLast) { - store.dispatch(ArchiveClientRequest(null, client.id)); - } else { - store.dispatch(ArchiveClientRequest( - snackBarCompleter(context, localization.archivedClient), - client.id)); - } + store.dispatch(ArchiveClientRequest( + snackBarCompleter(context, localization.archivedClient), clientIds)); break; case EntityAction.delete: - if (multiselect && !isMultiselectLast) { - store.dispatch(DeleteClientRequest(null, client.id)); - } else { - store.dispatch(DeleteClientRequest( - snackBarCompleter(context, localization.deletedClient), client.id)); - } + store.dispatch(DeleteClientRequest( + snackBarCompleter(context, localization.deletedClient), clientIds)); break; case EntityAction.toggleMultiselect: if (!store.state.clientListState.isInMultiselect()) { store.dispatch(StartMultiselect(context: context)); } - if (!store.state.clientListState.isSelected(client)) { - store.dispatch(AddToMultiselect(context: context, entity: client)); - } else { - store.dispatch(RemoveFromMultiselect(context: context, entity: client)); + + for (final client in clients) { + if (!store.state.clientListState.isSelected(client)) { + store.dispatch(AddToMultiselect(context: context, entity: client)); + } else { + store.dispatch( + RemoveFromMultiselect(context: context, entity: client)); + } } break; } diff --git a/lib/redux/client/client_middleware.dart b/lib/redux/client/client_middleware.dart index 2699b398d..a6aaf5183 100644 --- a/lib/redux/client/client_middleware.dart +++ b/lib/redux/client/client_middleware.dart @@ -1,16 +1,16 @@ -import 'package:redux/redux.dart'; import 'package:flutter/material.dart'; import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/repositories/client_repository.dart'; import 'package:invoiceninja_flutter/redux/app/app_middleware.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; import 'package:invoiceninja_flutter/redux/product/product_actions.dart'; import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; import 'package:invoiceninja_flutter/ui/client/client_screen.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart'; import 'package:invoiceninja_flutter/ui/client/view/client_view_vm.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; -import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/data/repositories/client_repository.dart'; +import 'package:redux/redux.dart'; List> createStoreClientsMiddleware([ ClientRepository repository = const ClientRepository(), @@ -105,17 +105,20 @@ Middleware _viewClientList() { Middleware _archiveClient(ClientRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as ArchiveClientRequest; - final origClient = store.state.clientState.map[action.clientId]; repository - .saveData(store.state.credentials, origClient, EntityAction.archive) - .then((ClientEntity client) { - store.dispatch(ArchiveClientSuccess(client)); + .bulkAction( + store.state.credentials, action.clientIds, EntityAction.archive) + .then((List clients) { + store.dispatch(ArchiveClientSuccess(clients)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); - store.dispatch(ArchiveClientFailure(origClient)); + final clients = action.clientIds + .map((id) => store.state.clientState.map[id]) + .toList(); + store.dispatch(ArchiveClientFailure(clients)); if (action.completer != null) { action.completer.completeError(error); } @@ -128,17 +131,20 @@ Middleware _archiveClient(ClientRepository repository) { Middleware _deleteClient(ClientRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as DeleteClientRequest; - final origClient = store.state.clientState.map[action.clientId]; repository - .saveData(store.state.credentials, origClient, EntityAction.delete) - .then((ClientEntity client) { - store.dispatch(DeleteClientSuccess(client)); + .bulkAction( + store.state.credentials, action.clientIds, EntityAction.delete) + .then((List clients) { + store.dispatch(DeleteClientSuccess(clients)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); - store.dispatch(DeleteClientFailure(origClient)); + final clients = action.clientIds + .map((id) => store.state.clientState.map[id]) + .toList(); + store.dispatch(DeleteClientFailure(clients)); if (action.completer != null) { action.completer.completeError(error); } @@ -151,17 +157,20 @@ Middleware _deleteClient(ClientRepository repository) { Middleware _restoreClient(ClientRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { final action = dynamicAction as RestoreClientRequest; - final origClient = store.state.clientState.map[action.clientId]; repository - .saveData(store.state.credentials, origClient, EntityAction.restore) - .then((ClientEntity client) { - store.dispatch(RestoreClientSuccess(client)); + .bulkAction( + store.state.credentials, action.clientIds, EntityAction.restore) + .then((List clients) { + store.dispatch(RestoreClientSuccess(clients)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); - store.dispatch(RestoreClientFailure(origClient)); + final clients = action.clientIds + .map((id) => store.state.clientState.map[id]) + .toList(); + store.dispatch(RestoreClientFailure(clients)); if (action.completer != null) { action.completer.completeError(error); } diff --git a/lib/redux/client/client_reducer.dart b/lib/redux/client/client_reducer.dart index 251655383..242419947 100644 --- a/lib/redux/client/client_reducer.dart +++ b/lib/redux/client/client_reducer.dart @@ -58,14 +58,14 @@ final editingReducer = combineReducers([ TypedReducer((client, action) { return action.client; }), - TypedReducer((client, action) { - return action.client; + TypedReducer((clients, action) { + return action.clients[0]; }), - TypedReducer((client, action) { - return action.client; + TypedReducer((clients, action) { + return action.clients[0]; }), - TypedReducer((client, action) { - return action.client; + TypedReducer((clients, action) { + return action.clients[0]; }), TypedReducer((client, action) { return action.client; @@ -197,57 +197,103 @@ final clientsReducer = combineReducers([ ClientState _archiveClientRequest( ClientState clientState, ArchiveClientRequest action) { - final client = clientState.map[action.clientId] - .rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch); + final clients = action.clientIds.map((id) => clientState.map[id]).toList(); - return clientState.rebuild((b) => b..map[action.clientId] = client); + for (int i = 0; i < clients.length; i++) { + clients[i] = clients[i] + .rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch); + } + return clientState.rebuild((b) { + for (final client in clients) { + b.map[client.id] = client; + } + }); } ClientState _archiveClientSuccess( ClientState clientState, ArchiveClientSuccess action) { - return clientState.rebuild((b) => b..map[action.client.id] = action.client); + return clientState.rebuild((b) { + for (final client in action.clients) { + b.map[client.id] = client; + } + }); } ClientState _archiveClientFailure( ClientState clientState, ArchiveClientFailure action) { - return clientState.rebuild((b) => b..map[action.client.id] = action.client); + return clientState.rebuild((b) { + for (final client in action.clients) { + b.map[client.id] = client; + } + }); } ClientState _deleteClientRequest( ClientState clientState, DeleteClientRequest action) { - final client = clientState.map[action.clientId].rebuild((b) => b - ..archivedAt = DateTime.now().millisecondsSinceEpoch - ..isDeleted = true); + final clients = action.clientIds.map((id) => clientState.map[id]).toList(); - return clientState.rebuild((b) => b..map[action.clientId] = client); + for (int i = 0; i < clients.length; i++) { + clients[i] = clients[i].rebuild((b) => b + ..archivedAt = DateTime.now().millisecondsSinceEpoch + ..isDeleted = true); + } + return clientState.rebuild((b) { + for (final client in clients) { + b.map[client.id] = client; + } + }); } ClientState _deleteClientSuccess( ClientState clientState, DeleteClientSuccess action) { - return clientState.rebuild((b) => b..map[action.client.id] = action.client); + return clientState.rebuild((b) { + for (final client in action.clients) { + b.map[client.id] = client; + } + }); } ClientState _deleteClientFailure( ClientState clientState, DeleteClientFailure action) { - return clientState.rebuild((b) => b..map[action.client.id] = action.client); + return clientState.rebuild((b) { + for (final client in action.clients) { + b.map[client.id] = client; + } + }); } ClientState _restoreClientRequest( ClientState clientState, RestoreClientRequest action) { - final client = clientState.map[action.clientId].rebuild((b) => b - ..archivedAt = null - ..isDeleted = false); - return clientState.rebuild((b) => b..map[action.clientId] = client); + final clients = action.clientIds.map((id) => clientState.map[id]).toList(); + + for (int i = 0; i < clients.length; i++) { + clients[i] = clients[i].rebuild((b) => b + ..archivedAt = null + ..isDeleted = false); + } + return clientState.rebuild((b) { + for (final client in clients) { + b.map[client.id] = client; + } + }); } ClientState _restoreClientSuccess( ClientState clientState, RestoreClientSuccess action) { - return clientState.rebuild((b) => b..map[action.client.id] = action.client); + return clientState.rebuild((b) { + for (final client in action.clients) { + b.map[client.id] = client; + } + }); } ClientState _restoreClientFailure( ClientState clientState, RestoreClientFailure action) { - return clientState.rebuild((b) => b..map[action.client.id] = action.client); + return clientState.rebuild((b) { + for (final client in action.clients) { + b.map[client.id] = client; + } + }); } ClientState _addClient(ClientState clientState, AddClientSuccess action) { diff --git a/lib/redux/invoice/invoice_actions.dart b/lib/redux/invoice/invoice_actions.dart index 97ec6a9e8..0bfd3a18e 100644 --- a/lib/redux/invoice/invoice_actions.dart +++ b/lib/redux/invoice/invoice_actions.dart @@ -1,17 +1,18 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; + import 'package:built_collection/built_collection.dart'; -import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; -import 'package:flutter_redux/flutter_redux.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/ui/app/responsive_padding.dart'; -import 'package:invoiceninja_flutter/ui/invoice/invoice_email_vm.dart'; -import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:flutter/material.dart'; +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_actions.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart'; import 'package:invoiceninja_flutter/redux/quote/quote_actions.dart'; +import 'package:invoiceninja_flutter/ui/app/responsive_padding.dart'; +import 'package:invoiceninja_flutter/ui/invoice/invoice_email_vm.dart'; +import 'package:invoiceninja_flutter/utils/completers.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/pdf.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -322,8 +323,8 @@ class FilterInvoicesByCustom2 implements PersistUI { final String value; } -void handleInvoiceAction( - BuildContext context, InvoiceEntity invoice, EntityAction action) async { +void handleInvoiceAction(BuildContext context, List invoices, + EntityAction action) async { final store = StoreProvider.of(context); final state = store.state; final CompanyEntity company = state.selectedCompany; @@ -331,27 +332,27 @@ void handleInvoiceAction( switch (action) { case EntityAction.edit: - store.dispatch(EditInvoice(context: context, invoice: invoice)); + store.dispatch(EditInvoice(context: context, invoice: invoices[0])); break; case EntityAction.pdf: - viewPdf(invoice, context); + viewPdf(invoices[0], context); break; case EntityAction.clientPortal: - if (await canLaunch(invoice.invitationSilentLink)) { - await launch(invoice.invitationSilentLink, + if (await canLaunch(invoices[0].invitationSilentLink)) { + await launch(invoices[0].invitationSilentLink, forceSafariVC: false, forceWebView: false); } break; case EntityAction.markSent: store.dispatch(MarkSentInvoiceRequest( snackBarCompleter(context, localization.markedInvoiceAsSent), - invoice.id)); + invoices[0].id)); break; case EntityAction.sendEmail: if (isMobile(context)) { store.dispatch(ShowEmailInvoice( completer: snackBarCompleter(context, localization.emailedInvoice), - invoice: invoice, + invoice: invoices[0], context: context)); } else { showDialog( @@ -363,28 +364,30 @@ void handleInvoiceAction( break; case EntityAction.cloneToInvoice: store.dispatch( - EditInvoice(context: context, invoice: invoice.cloneToInvoice)); + EditInvoice(context: context, invoice: invoices[0].cloneToInvoice)); break; case EntityAction.cloneToQuote: - store.dispatch(EditQuote(context: context, quote: invoice.cloneToQuote)); + store.dispatch( + EditQuote(context: context, quote: invoices[0].cloneToQuote)); break; case EntityAction.enterPayment: store.dispatch(EditPayment( - context: context, payment: invoice.createPayment(company))); + context: context, payment: invoices[0].createPayment(company))); break; case EntityAction.restore: store.dispatch(RestoreInvoiceRequest( snackBarCompleter(context, localization.restoredInvoice), - invoice.id)); + invoices[0].id)); break; case EntityAction.archive: store.dispatch(ArchiveInvoiceRequest( snackBarCompleter(context, localization.archivedInvoice), - invoice.id)); + invoices[0].id)); break; case EntityAction.delete: store.dispatch(DeleteInvoiceRequest( - snackBarCompleter(context, localization.deletedInvoice), invoice.id)); + snackBarCompleter(context, localization.deletedInvoice), + invoices[0].id)); break; } } diff --git a/lib/redux/payment/payment_actions.dart b/lib/redux/payment/payment_actions.dart index c78aa8bca..c0f9ac76f 100644 --- a/lib/redux/payment/payment_actions.dart +++ b/lib/redux/payment/payment_actions.dart @@ -1,9 +1,10 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; + import 'package:built_collection/built_collection.dart'; +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_actions.dart'; -import 'package:flutter_redux/flutter_redux.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; @@ -251,31 +252,33 @@ class FilterPaymentsByEntity implements PersistUI { } void handlePaymentAction( - BuildContext context, PaymentEntity payment, EntityAction action) { + BuildContext context, List payments, EntityAction action) { final store = StoreProvider.of(context); final localization = AppLocalization.of(context); switch (action) { case EntityAction.edit: - store.dispatch(EditPayment(context: context, payment: payment)); + store.dispatch(EditPayment(context: context, payment: payments[0])); break; case EntityAction.sendEmail: store.dispatch(EmailPaymentRequest( - snackBarCompleter(context, localization.emailedPayment), payment)); + snackBarCompleter(context, localization.emailedPayment), + payments[0])); break; case EntityAction.restore: store.dispatch(RestorePaymentRequest( snackBarCompleter(context, localization.restoredPayment), - payment.id)); + payments[0].id)); break; case EntityAction.archive: store.dispatch(ArchivePaymentRequest( snackBarCompleter(context, localization.archivedPayment), - payment.id)); + payments[0].id)); break; case EntityAction.delete: store.dispatch(DeletePaymentRequest( - snackBarCompleter(context, localization.deletedPayment), payment.id)); + snackBarCompleter(context, localization.deletedPayment), + payments[0].id)); break; } } diff --git a/lib/redux/product/product_actions.dart b/lib/redux/product/product_actions.dart index 973f01c94..0b7a1c756 100644 --- a/lib/redux/product/product_actions.dart +++ b/lib/redux/product/product_actions.dart @@ -1,12 +1,13 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; + import 'package:built_collection/built_collection.dart'; -import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +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_actions.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/product/product_selectors.dart'; import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; +import 'package:invoiceninja_flutter/redux/product/product_selectors.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; @@ -195,7 +196,7 @@ class FilterProductDropdown { } void handleProductAction( - BuildContext context, ProductEntity product, EntityAction action) { + BuildContext context, List products, EntityAction action) { final store = StoreProvider.of(context); final state = store.state; final localization = AppLocalization.of(context); @@ -203,31 +204,32 @@ void handleProductAction( switch (action) { case EntityAction.newInvoice: final item = - convertProductToInvoiceItem(context: context, product: product); + convertProductToInvoiceItem(context: context, product: products[0]); store.dispatch(EditInvoice( context: context, invoice: InvoiceEntity(company: state.selectedCompany) .rebuild((b) => b..invoiceItems.add(item)))); break; case EntityAction.edit: - store.dispatch(EditProduct(context: context, product: product)); + store.dispatch(EditProduct(context: context, product: products[0])); break; case EntityAction.clone: - store.dispatch(EditProduct(context: context, product: product.clone)); + store.dispatch(EditProduct(context: context, product: products[0].clone)); break; case EntityAction.restore: store.dispatch(RestoreProductRequest( snackBarCompleter(context, localization.restoredProduct), - product.id)); + products[0].id)); break; case EntityAction.archive: store.dispatch(ArchiveProductRequest( snackBarCompleter(context, localization.archivedProduct), - product.id)); + products[0].id)); break; case EntityAction.delete: store.dispatch(DeleteProductRequest( - snackBarCompleter(context, localization.deletedProduct), product.id)); + snackBarCompleter(context, localization.deletedProduct), + products[0].id)); break; } } diff --git a/lib/redux/project/project_actions.dart b/lib/redux/project/project_actions.dart index 01bf11c80..4642c6ab7 100644 --- a/lib/redux/project/project_actions.dart +++ b/lib/redux/project/project_actions.dart @@ -242,53 +242,53 @@ class FilterProjectsByEntity implements PersistUI { } void handleProjectAction( - BuildContext context, ProjectEntity project, EntityAction action) { + BuildContext context, List projects, EntityAction action) { final store = StoreProvider.of(context); final state = store.state; final CompanyEntity company = state.selectedCompany; switch (action) { case EntityAction.edit: - store.dispatch(EditProject(context: context, project: project)); + store.dispatch(EditProject(context: context, project: projects[0])); break; case EntityAction.newTask: store.dispatch(EditTask( task: TaskEntity(isRunning: state.uiState.autoStartTasks) .rebuild((b) => b - ..projectId = project.id - ..clientId = project.clientId), + ..projectId = projects[0].id + ..clientId = projects[0].clientId), context: context)); break; case EntityAction.newInvoice: final items = - convertProjectToInvoiceItem(project: project, context: context); + convertProjectToInvoiceItem(project: projects[0], context: context); store.dispatch(EditInvoice( invoice: InvoiceEntity(company: company).rebuild((b) => b ..hasTasks = true - ..clientId = project.clientId + ..clientId = projects[0].clientId ..invoiceItems.addAll(items)), context: context)); break; case EntityAction.clone: - store.dispatch(EditProject(context: context, project: project.clone)); + store.dispatch(EditProject(context: context, project: projects[0].clone)); break; case EntityAction.restore: store.dispatch(RestoreProjectRequest( snackBarCompleter( context, AppLocalization.of(context).restoredProject), - project.id)); + projects[0].id)); break; case EntityAction.archive: store.dispatch(ArchiveProjectRequest( snackBarCompleter( context, AppLocalization.of(context).archivedProject), - project.id)); + projects[0].id)); break; case EntityAction.delete: store.dispatch(DeleteProjectRequest( snackBarCompleter( context, AppLocalization.of(context).deletedProject), - project.id)); + projects[0].id)); break; } } diff --git a/lib/redux/quote/quote_actions.dart b/lib/redux/quote/quote_actions.dart index e6dbea860..a70162083 100644 --- a/lib/redux/quote/quote_actions.dart +++ b/lib/redux/quote/quote_actions.dart @@ -1,16 +1,17 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; + import 'package:built_collection/built_collection.dart'; -import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; +import 'package:flutter/material.dart'; +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_actions.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; +import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/pdf.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; -import 'package:flutter/material.dart'; class ViewQuoteList implements PersistUI { ViewQuoteList({this.context, this.force = false}); @@ -338,31 +339,31 @@ class ConvertQuoteFailure implements StopSaving { final dynamic error; } -Future handleQuoteAction( - BuildContext context, InvoiceEntity quote, EntityAction action) async { +Future handleQuoteAction(BuildContext context, List quotes, + EntityAction action) async { final store = StoreProvider.of(context); final localization = AppLocalization.of(context); switch (action) { case EntityAction.edit: - store.dispatch(EditQuote(context: context, quote: quote)); + store.dispatch(EditQuote(context: context, quote: quotes[0])); break; case EntityAction.pdf: - viewPdf(quote, context); + viewPdf(quotes[0], context); break; case EntityAction.clientPortal: - if (await canLaunch(quote.invitationSilentLink)) { - await launch(quote.invitationSilentLink, + if (await canLaunch(quotes[0].invitationSilentLink)) { + await launch(quotes[0].invitationSilentLink, forceSafariVC: false, forceWebView: false); } break; case EntityAction.viewInvoice: store.dispatch( - ViewInvoice(context: context, invoiceId: quote.quoteInvoiceId)); + ViewInvoice(context: context, invoiceId: quotes[0].quoteInvoiceId)); break; case EntityAction.convert: final Completer completer = Completer(); - store.dispatch(ConvertQuote(completer, quote.id)); + store.dispatch(ConvertQuote(completer, quotes[0].id)); completer.future.then((InvoiceEntity invoice) { store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context)); }); @@ -370,32 +371,35 @@ Future handleQuoteAction( case EntityAction.markSent: store.dispatch(MarkSentQuoteRequest( snackBarCompleter(context, localization.markedQuoteAsSent), - quote.id)); + quotes[0].id)); break; case EntityAction.sendEmail: store.dispatch(ShowEmailQuote( completer: snackBarCompleter(context, localization.emailedQuote), - quote: quote, + quote: quotes[0], context: context)); break; case EntityAction.cloneToInvoice: store.dispatch( - EditInvoice(context: context, invoice: quote.cloneToInvoice)); + EditInvoice(context: context, invoice: quotes[0].cloneToInvoice)); break; case EntityAction.cloneToQuote: - store.dispatch(EditQuote(context: context, quote: quote.cloneToQuote)); + store + .dispatch(EditQuote(context: context, quote: quotes[0].cloneToQuote)); break; case EntityAction.restore: store.dispatch(RestoreQuoteRequest( - snackBarCompleter(context, localization.restoredQuote), quote.id)); + snackBarCompleter(context, localization.restoredQuote), + quotes[0].id)); break; case EntityAction.archive: store.dispatch(ArchiveQuoteRequest( - snackBarCompleter(context, localization.archivedQuote), quote.id)); + snackBarCompleter(context, localization.archivedQuote), + quotes[0].id)); break; case EntityAction.delete: store.dispatch(DeleteQuoteRequest( - snackBarCompleter(context, localization.deletedQuote), quote.id)); + snackBarCompleter(context, localization.deletedQuote), quotes[0].id)); break; } } diff --git a/lib/redux/task/task_actions.dart b/lib/redux/task/task_actions.dart index 2c2a391f2..fdf63af30 100644 --- a/lib/redux/task/task_actions.dart +++ b/lib/redux/task/task_actions.dart @@ -1,17 +1,18 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; + import 'package:built_collection/built_collection.dart'; +import 'package:flutter/material.dart'; +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_actions.dart'; -import 'package:flutter_redux/flutter_redux.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; +import 'package:invoiceninja_flutter/redux/task/task_selectors.dart'; import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart'; import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; -import 'package:flutter/material.dart'; -import 'package:invoiceninja_flutter/redux/task/task_selectors.dart'; +import 'package:invoiceninja_flutter/utils/completers.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; class ViewTaskList implements PersistUI { ViewTaskList({@required this.context, this.force = false}); @@ -276,7 +277,7 @@ class FilterTasksByEntity implements PersistUI { } void handleTaskAction( - BuildContext context, TaskEntity task, EntityAction action) { + BuildContext context, List tasks, EntityAction action) { final store = StoreProvider.of(context); final state = store.state; final CompanyEntity company = state.selectedCompany; @@ -284,15 +285,15 @@ void handleTaskAction( switch (action) { case EntityAction.edit: - store.dispatch(EditTask(context: context, task: task)); + store.dispatch(EditTask(context: context, task: tasks[0])); break; case EntityAction.start: case EntityAction.stop: case EntityAction.resume: final Completer completer = new Completer(); final localization = AppLocalization.of(context); - store - .dispatch(SaveTaskRequest(completer: completer, task: task.toggle())); + store.dispatch( + SaveTaskRequest(completer: completer, task: tasks[0].toggle())); completer.future.then((savedTask) { Scaffold.of(context).showSnackBar(SnackBar( content: SnackBarRow( @@ -312,31 +313,32 @@ void handleTaskAction( break; case EntityAction.newInvoice: - final item = convertTaskToInvoiceItem(task: task, context: context); + final item = convertTaskToInvoiceItem(task: tasks[0], context: context); store.dispatch(EditInvoice( invoice: InvoiceEntity(company: company).rebuild((b) => b ..hasTasks = true - ..clientId = task.clientId + ..clientId = tasks[0].clientId ..invoiceItems.add(item)), context: context)); break; case EntityAction.viewInvoice: - store.dispatch(ViewInvoice(invoiceId: task.invoiceId, context: context)); + store.dispatch( + ViewInvoice(invoiceId: tasks[0].invoiceId, context: context)); break; case EntityAction.clone: - store.dispatch(EditTask(context: context, task: task.clone)); + store.dispatch(EditTask(context: context, task: tasks[0].clone)); break; case EntityAction.restore: store.dispatch(RestoreTaskRequest( - snackBarCompleter(context, localization.restoredTask), task.id)); + snackBarCompleter(context, localization.restoredTask), tasks[0].id)); break; case EntityAction.archive: store.dispatch(ArchiveTaskRequest( - snackBarCompleter(context, localization.archivedTask), task.id)); + snackBarCompleter(context, localization.archivedTask), tasks[0].id)); break; case EntityAction.delete: store.dispatch(DeleteTaskRequest( - snackBarCompleter(context, localization.deletedTask), task.id)); + snackBarCompleter(context, localization.deletedTask), tasks[0].id)); break; } } diff --git a/lib/redux/vendor/vendor_actions.dart b/lib/redux/vendor/vendor_actions.dart index 17d216924..69670eb66 100644 --- a/lib/redux/vendor/vendor_actions.dart +++ b/lib/redux/vendor/vendor_actions.dart @@ -1,13 +1,14 @@ import 'dart:async'; -import 'package:flutter/widgets.dart'; + import 'package:built_collection/built_collection.dart'; +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_actions.dart'; -import 'package:flutter_redux/flutter_redux.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart'; -import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; +import 'package:invoiceninja_flutter/utils/localization.dart'; class ViewVendorList implements PersistUI { ViewVendorList({@required this.context, this.force = false}); @@ -266,7 +267,7 @@ class FilterVendorsByEntity implements PersistUI { } void handleVendorAction( - BuildContext context, VendorEntity vendor, EntityAction action) { + BuildContext context, List vendors, EntityAction action) { final store = StoreProvider.of(context); final state = store.state; final CompanyEntity company = state.selectedCompany; @@ -274,24 +275,27 @@ void handleVendorAction( switch (action) { case EntityAction.edit: - store.dispatch(EditVendor(context: context, vendor: vendor)); + store.dispatch(EditVendor(context: context, vendor: vendors[0])); break; case EntityAction.newExpense: store.dispatch(EditExpense( - expense: ExpenseEntity(company: company, vendor: vendor), + expense: ExpenseEntity(company: company, vendor: vendors[0]), context: context)); break; case EntityAction.restore: store.dispatch(RestoreVendorRequest( - snackBarCompleter(context, localization.restoredVendor), vendor.id)); + snackBarCompleter(context, localization.restoredVendor), + vendors[0].id)); break; case EntityAction.archive: store.dispatch(ArchiveVendorRequest( - snackBarCompleter(context, localization.archivedVendor), vendor.id)); + snackBarCompleter(context, localization.archivedVendor), + vendors[0].id)); break; case EntityAction.delete: store.dispatch(DeleteVendorRequest( - snackBarCompleter(context, localization.deletedVendor), vendor.id)); + snackBarCompleter(context, localization.deletedVendor), + vendors[0].id)); break; } } diff --git a/lib/ui/app/entities/entity_actions_dialog.dart b/lib/ui/app/entities/entity_actions_dialog.dart index dd482a5f7..c080f4a76 100644 --- a/lib/ui/app/entities/entity_actions_dialog.dart +++ b/lib/ui/app/entities/entity_actions_dialog.dart @@ -8,7 +8,8 @@ Future showEntityActionsDialog({ @required BuildContext context, @required List entities, @required UserCompanyEntity userCompany, - @required Function(BuildContext, BaseEntity, EntityAction) onEntityAction, + @required + Function(BuildContext, List, EntityAction) onEntityAction, ClientEntity client, }) async { if (entities == null) { @@ -49,7 +50,7 @@ class EntityActionListTile extends StatelessWidget { final List entities; final EntityAction entityAction; final BuildContext mainContext; - final Function(BuildContext, BaseEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) onEntityAction; @override Widget build(BuildContext context) { @@ -60,10 +61,7 @@ class EntityActionListTile extends StatelessWidget { title: Text(localization.lookup(entityAction.toString())), onTap: () { Navigator.of(context).pop(); - for (int i = 0; i < entities.length; i++) { - final BaseEntity entity = entities[i]; - onEntityAction(context, entity, entityAction); - } + onEntityAction(context, entities, entityAction); }, ); } diff --git a/lib/ui/client/client_list.dart b/lib/ui/client/client_list.dart index 9daa5c97c..970c58352 100644 --- a/lib/ui/client/client_list.dart +++ b/lib/ui/client/client_list.dart @@ -82,7 +82,7 @@ class ClientList extends StatelessWidget { store.state.uiState.longPressSelectionIsDefault ?? true; if (longPressIsSelection) { viewModel.onEntityAction( - context, client, EntityAction.toggleMultiselect); + context, [client], EntityAction.toggleMultiselect); } else { showDialog(); } diff --git a/lib/ui/client/client_list_vm.dart b/lib/ui/client/client_list_vm.dart index b8444e8be..0d2cc94db 100644 --- a/lib/ui/client/client_list_vm.dart +++ b/lib/ui/client/client_list_vm.dart @@ -5,11 +5,11 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:invoiceninja_flutter/redux/group/group_actions.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:invoiceninja_flutter/redux/group/group_actions.dart'; import 'package:invoiceninja_flutter/ui/client/client_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; @@ -55,7 +55,7 @@ class ClientListVM { final bool isLoaded; final Function(BuildContext, ClientEntity) onClientTap; final Function(BuildContext) onRefreshed; - final Function(BuildContext, ClientEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) onEntityAction; final Function onClearEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed; @@ -84,9 +84,9 @@ class ClientListVM { store.dispatch(ViewClient(clientId: client.id, context: context)); }, onRefreshed: (context) => _handleRefresh(context), - onEntityAction: - (BuildContext context, BaseEntity client, EntityAction action) => - handleClientAction(context, client, action), + onEntityAction: (BuildContext context, List client, + EntityAction action) => + handleClientAction(context, client, action), onClearEntityFilterPressed: () => store.dispatch(FilterClientsByEntity()), onViewEntityFilterPressed: (BuildContext context) => store.dispatch( ViewGroup( diff --git a/lib/ui/client/client_screen_vm.dart b/lib/ui/client/client_screen_vm.dart index 693901ad9..2e02d2b43 100644 --- a/lib/ui/client/client_screen_vm.dart +++ b/lib/ui/client/client_screen_vm.dart @@ -35,7 +35,7 @@ class ClientScreenVM { final bool isInMultiselect; final UserCompanyEntity userCompany; - final Function(BuildContext, ClientEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) onEntityAction; static ClientScreenVM fromStore(Store store) { final state = store.state; @@ -43,9 +43,9 @@ class ClientScreenVM { return ClientScreenVM( userCompany: state.userCompany, isInMultiselect: state.clientListState.isInMultiselect(), - onEntityAction: - (BuildContext context, BaseEntity client, EntityAction action) => - handleClientAction(context, client, action), + onEntityAction: (BuildContext context, List clients, + EntityAction action) => + handleClientAction(context, clients, action), ); } } diff --git a/lib/ui/client/view/client_view_vm.dart b/lib/ui/client/view/client_view_vm.dart index 44fb094c0..f3cc64b01 100644 --- a/lib/ui/client/view/client_view_vm.dart +++ b/lib/ui/client/view/client_view_vm.dart @@ -1,23 +1,24 @@ import 'dart:async'; + import 'package:flutter/foundation.dart'; 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/client/client_actions.dart'; +import 'package:invoiceninja_flutter/redux/expense/expense_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/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/ui/ui_actions.dart'; -import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart'; +import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; import 'package:invoiceninja_flutter/ui/client/client_screen.dart'; +import 'package:invoiceninja_flutter/ui/client/view/client_view.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:redux/redux.dart'; -import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/client/view/client_view.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; class ClientViewScreen extends StatelessWidget { const ClientViewScreen({Key key}) : super(key: key); @@ -176,7 +177,7 @@ class ClientViewVM { } }, onEntityAction: (BuildContext context, EntityAction action) => - handleClientAction(context, client, action), + handleClientAction(context, [client], action), ); } diff --git a/lib/ui/document/document_list.dart b/lib/ui/document/document_list.dart index b4aa60b69..970f79896 100644 --- a/lib/ui/document/document_list.dart +++ b/lib/ui/document/document_list.dart @@ -63,7 +63,7 @@ class DocumentList extends StatelessWidget { showDialog(); } else { viewModel.onEntityAction( - context, document, action); + context, [document], action); } }, onLongPress: () => showDialog(), diff --git a/lib/ui/document/document_list_vm.dart b/lib/ui/document/document_list_vm.dart index 04c645091..8bd29ea52 100644 --- a/lib/ui/document/document_list_vm.dart +++ b/lib/ui/document/document_list_vm.dart @@ -1,19 +1,20 @@ import 'dart:async'; -import 'package:redux/redux.dart'; -import 'package:flutter/material.dart'; + +import 'package:built_collection/built_collection.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:built_collection/built_collection.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/document/document_actions.dart'; +import 'package:invoiceninja_flutter/redux/document/document_selectors.dart'; import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/ui/document/document_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/document/document_selectors.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/document/document_list.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/document/document_actions.dart'; +import 'package:redux/redux.dart'; class DocumentListBuilder extends StatelessWidget { const DocumentListBuilder({Key key}) : super(key: key); @@ -78,9 +79,9 @@ class DocumentListVM { onDocumentTap: (context, document) { store.dispatch(ViewDocument(documentId: document.id, context: context)); }, - onEntityAction: - (BuildContext context, BaseEntity document, EntityAction action) => - handleDocumentAction(context, document, action), + onEntityAction: (BuildContext context, List documents, + EntityAction action) => + handleDocumentAction(context, documents[0], action), onRefreshed: (context) => _handleRefresh(context), ); } @@ -94,7 +95,8 @@ class DocumentListVM { final bool isLoaded; final Function(BuildContext, DocumentEntity) onDocumentTap; final Function(BuildContext) onRefreshed; - final Function(BuildContext, DocumentEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) + onEntityAction; final Function onClearEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed; } diff --git a/lib/ui/expense/expense_list.dart b/lib/ui/expense/expense_list.dart index ad84df164..ab9667e51 100644 --- a/lib/ui/expense/expense_list.dart +++ b/lib/ui/expense/expense_list.dart @@ -84,7 +84,7 @@ class ExpenseList extends StatelessWidget { showDialog(); } else { viewModel.onEntityAction( - context, expense, action); + context, [expense], action); } }, onLongPress: () => showDialog(), diff --git a/lib/ui/expense/expense_list_vm.dart b/lib/ui/expense/expense_list_vm.dart index 8fd47e626..b8df67535 100644 --- a/lib/ui/expense/expense_list_vm.dart +++ b/lib/ui/expense/expense_list_vm.dart @@ -1,20 +1,21 @@ import 'dart:async'; -import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart'; -import 'package:redux/redux.dart'; -import 'package:flutter/material.dart'; + +import 'package:built_collection/built_collection.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:built_collection/built_collection.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/expense/expense_actions.dart'; +import 'package:invoiceninja_flutter/redux/expense/expense_selectors.dart'; import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart'; +import 'package:invoiceninja_flutter/ui/expense/expense_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/expense/expense_selectors.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/expense/expense_list.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart'; +import 'package:redux/redux.dart'; class ExpenseListBuilder extends StatelessWidget { const ExpenseListBuilder({Key key}) : super(key: key); @@ -95,9 +96,9 @@ class ExpenseListVM { onExpenseTap: (context, expense) { store.dispatch(ViewExpense(expenseId: expense.id, context: context)); }, - onEntityAction: - (BuildContext context, BaseEntity expense, EntityAction action) => - handleExpenseAction(context, expense, action), + onEntityAction: (BuildContext context, List expenses, + EntityAction action) => + handleExpenseAction(context, expenses[0], action), onRefreshed: (context) => _handleRefresh(context), ); } @@ -112,7 +113,8 @@ class ExpenseListVM { final bool isLoaded; final Function(BuildContext, ExpenseEntity) onExpenseTap; final Function(BuildContext) onRefreshed; - final Function(BuildContext, ExpenseEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) + onEntityAction; final Function onClearEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed; } diff --git a/lib/ui/expense/view/expense_view_vm.dart b/lib/ui/expense/view/expense_view_vm.dart index 95f872114..c7e1b0b99 100644 --- a/lib/ui/expense/view/expense_view_vm.dart +++ b/lib/ui/expense/view/expense_view_vm.dart @@ -106,9 +106,9 @@ class ExpenseViewVM { userCompany: userCompany, context: context, entities: [vendor], - onEntityAction: (BuildContext context, BaseEntity vendor, - EntityAction action) => - handleVendorAction(context, vendor, action)); + onEntityAction: (BuildContext context, + List vendors, EntityAction action) => + handleVendorAction(context, vendors, action)); } else { store.dispatch( ViewVendor(vendorId: vendor.id, context: context)); @@ -120,9 +120,9 @@ class ExpenseViewVM { userCompany: userCompany, context: context, entities: [client], - onEntityAction: (BuildContext context, BaseEntity client, - EntityAction action) => - handleClientAction(context, client, action)); + onEntityAction: (BuildContext context, + List clients, EntityAction action) => + handleClientAction(context, clients, action)); } else { store.dispatch( ViewClient(clientId: client.id, context: context)); @@ -135,9 +135,9 @@ class ExpenseViewVM { context: context, entities: [invoice], client: client, - onEntityAction: (BuildContext context, BaseEntity invoice, - EntityAction action) => - handleInvoiceAction(context, invoice, action)); + onEntityAction: (BuildContext context, + List invoices, EntityAction action) => + handleInvoiceAction(context, invoices, action)); } else { store.dispatch( ViewInvoice(invoiceId: invoice.id, context: context)); diff --git a/lib/ui/invoice/invoice_list.dart b/lib/ui/invoice/invoice_list.dart index c2c4db5cf..a02137d2b 100644 --- a/lib/ui/invoice/invoice_list.dart +++ b/lib/ui/invoice/invoice_list.dart @@ -101,7 +101,7 @@ class InvoiceList extends StatelessWidget { showDialog(); } else { viewModel.onEntityAction( - context, invoice, action); + context, [invoice], action); } }, onLongPress: () => showDialog(), diff --git a/lib/ui/invoice/invoice_list_vm.dart b/lib/ui/invoice/invoice_list_vm.dart index c4c93f9ab..04ed8b1a2 100644 --- a/lib/ui/invoice/invoice_list_vm.dart +++ b/lib/ui/invoice/invoice_list_vm.dart @@ -1,19 +1,20 @@ import 'dart:async'; + import 'package:built_collection/built_collection.dart'; -import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; -import 'package:invoiceninja_flutter/redux/invoice/invoice_selectors.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; 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/invoice/invoice_actions.dart'; +import 'package:invoiceninja_flutter/redux/invoice/invoice_selectors.dart'; import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/ui/invoice/invoice_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:redux/redux.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/invoice/invoice_list.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; class InvoiceListBuilder extends StatelessWidget { const InvoiceListBuilder({Key key}) : super(key: key); @@ -64,7 +65,8 @@ class EntityListVM { final Function(BuildContext) onRefreshed; final Function onClearEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed; - final Function(BuildContext, InvoiceEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) + onEntityAction; } class InvoiceListVM extends EntityListVM { @@ -82,7 +84,7 @@ class InvoiceListVM extends EntityListVM { Function(BuildContext) onRefreshed, Function onClearEntityFilterPressed, Function(BuildContext) onViewEntityFilterPressed, - Function(BuildContext, InvoiceEntity, EntityAction) onEntityAction, + Function(BuildContext, List, EntityAction) onEntityAction, }) : super( state: state, user: user, @@ -137,9 +139,9 @@ class InvoiceListVM extends EntityListVM { ViewClient( clientId: state.invoiceListState.filterEntityId, context: context)), - onEntityAction: - (BuildContext context, BaseEntity invoice, EntityAction action) => - handleInvoiceAction(context, invoice, action), + onEntityAction: (BuildContext context, List invoices, + EntityAction action) => + handleInvoiceAction(context, invoices, action), ); } } diff --git a/lib/ui/invoice/view/invoice_view_vm.dart b/lib/ui/invoice/view/invoice_view_vm.dart index 25f943a5e..f6832fbb0 100644 --- a/lib/ui/invoice/view/invoice_view_vm.dart +++ b/lib/ui/invoice/view/invoice_view_vm.dart @@ -1,23 +1,24 @@ import 'dart:async'; -import 'package:invoiceninja_flutter/redux/document/document_actions.dart'; -import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart'; -import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart'; -import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart'; -import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart'; -import 'package:redux/redux.dart'; + import 'package:flutter/foundation.dart'; 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/client/client_actions.dart'; +import 'package:invoiceninja_flutter/redux/document/document_actions.dart'; +import 'package:invoiceninja_flutter/redux/expense/expense_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/ui/ui_actions.dart'; +import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart'; +import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart'; +import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; import 'package:invoiceninja_flutter/ui/invoice/invoice_screen.dart'; +import 'package:invoiceninja_flutter/ui/invoice/view/invoice_view.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/invoice/view/invoice_view.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; +import 'package:redux/redux.dart'; class InvoiceViewScreen extends StatelessWidget { const InvoiceViewScreen({Key key}) : super(key: key); @@ -159,9 +160,9 @@ class InvoiceViewVM extends EntityViewVM { userCompany: state.userCompany, context: context, entities: [client], - onEntityAction: (BuildContext context, BaseEntity client, + onEntityAction: (BuildContext context, List clients, EntityAction action) => - handleClientAction(context, client, action)); + handleClientAction(context, clients, action)); } else { store.dispatch(ViewClient(clientId: client.id, context: context)); } @@ -174,9 +175,9 @@ class InvoiceViewVM extends EntityViewVM { context: context, client: client, entities: [payment], - onEntityAction: (BuildContext context, BaseEntity payment, + onEntityAction: (BuildContext context, List payments, EntityAction action) => - handlePaymentAction(context, payment, action)); + handlePaymentAction(context, payments, action)); } else { store.dispatch(ViewPayment(paymentId: payment.id, context: context)); } @@ -187,7 +188,7 @@ class InvoiceViewVM extends EntityViewVM { store.dispatch(ViewPaymentList(context: context)); }, onEntityAction: (BuildContext context, EntityAction action) => - handleInvoiceAction(context, invoice, action), + handleInvoiceAction(context, [invoice], action), onUploadDocument: (BuildContext context, String path) { final Completer completer = Completer(); final document = DocumentEntity().rebuild((b) => b diff --git a/lib/ui/payment/payment_list.dart b/lib/ui/payment/payment_list.dart index a88799820..66cbc0792 100644 --- a/lib/ui/payment/payment_list.dart +++ b/lib/ui/payment/payment_list.dart @@ -112,7 +112,7 @@ class PaymentList extends StatelessWidget { showDialog(); } else { viewModel.onEntityAction( - context, payment, action); + context, [payment], action); } }, onLongPress: () => showDialog(), diff --git a/lib/ui/payment/payment_list_vm.dart b/lib/ui/payment/payment_list_vm.dart index 0a9fdd0c8..8d643d9b0 100644 --- a/lib/ui/payment/payment_list_vm.dart +++ b/lib/ui/payment/payment_list_vm.dart @@ -1,20 +1,21 @@ import 'dart:async'; -import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; -import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; -import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; -import 'package:redux/redux.dart'; -import 'package:flutter/material.dart'; + +import 'package:built_collection/built_collection.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:built_collection/built_collection.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/invoice/invoice_actions.dart'; +import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart'; +import 'package:invoiceninja_flutter/redux/payment/payment_selectors.dart'; +import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/ui/payment/payment_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/payment/payment_selectors.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/payment/payment_list.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart'; +import 'package:redux/redux.dart'; class PaymentListBuilder extends StatelessWidget { const PaymentListBuilder({Key key}) : super(key: key); @@ -79,9 +80,9 @@ class PaymentListVM { onPaymentTap: (context, payment) { store.dispatch(ViewPayment(paymentId: payment.id, context: context)); }, - onEntityAction: - (BuildContext context, BaseEntity payment, EntityAction action) => - handlePaymentAction(context, payment, action), + onEntityAction: (BuildContext context, List payments, + EntityAction action) => + handlePaymentAction(context, payments, action), onClearEntityFilterPressed: () => store.dispatch(FilterPaymentsByEntity()), onViewClientFilterPressed: (BuildContext context) { @@ -114,5 +115,6 @@ class PaymentListVM { final Function(BuildContext) onRefreshed; final Function onClearEntityFilterPressed; final Function(BuildContext) onViewClientFilterPressed; - final Function(BuildContext, PaymentEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) + onEntityAction; } diff --git a/lib/ui/payment/view/payment_view_vm.dart b/lib/ui/payment/view/payment_view_vm.dart index 41ce1ce5e..427ee62bf 100644 --- a/lib/ui/payment/view/payment_view_vm.dart +++ b/lib/ui/payment/view/payment_view_vm.dart @@ -70,9 +70,9 @@ class PaymentViewVM { userCompany: state.userCompany, context: context, entities: [client], - onEntityAction: (BuildContext context, BaseEntity client, + onEntityAction: (BuildContext context, List clients, EntityAction action) => - handleClientAction(context, client, action)); + handleClientAction(context, clients, action)); } else { store.dispatch(ViewClient(clientId: client.id, context: context)); } @@ -84,7 +84,7 @@ class PaymentViewVM { context: context, entities: [invoice], client: client, - onEntityAction: (BuildContext context, BaseEntity invoice, + onEntityAction: (BuildContext context, List invoice, EntityAction action) => handleInvoiceAction(context, invoice, action)); } else { @@ -92,7 +92,7 @@ class PaymentViewVM { } }, onEntityAction: (BuildContext context, EntityAction action) => - handlePaymentAction(context, payment, action), + handlePaymentAction(context, [payment], action), ); } diff --git a/lib/ui/product/edit/product_edit_vm.dart b/lib/ui/product/edit/product_edit_vm.dart index a5088902c..eee6f6148 100644 --- a/lib/ui/product/edit/product_edit_vm.dart +++ b/lib/ui/product/edit/product_edit_vm.dart @@ -1,17 +1,18 @@ import 'dart:async'; + import 'package:flutter/foundation.dart'; 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/redux/ui/ui_actions.dart'; import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart'; +import 'package:invoiceninja_flutter/ui/product/edit/product_edit.dart'; import 'package:invoiceninja_flutter/ui/product/product_screen.dart'; import 'package:invoiceninja_flutter/ui/product/view/product_view_vm.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:redux/redux.dart'; -import 'package:invoiceninja_flutter/redux/product/product_actions.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/product/edit/product_edit.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; class ProductEditScreen extends StatelessWidget { const ProductEditScreen({Key key}) : super(key: key); @@ -102,10 +103,10 @@ class ProductEditVM { if (action == EntityAction.clone) { Navigator.pop(context); WidgetsBinding.instance.addPostFrameCallback((duration) { - handleProductAction(context, product, action); + handleProductAction(context, [product], action); }); } else { - handleProductAction(context, product, action); + handleProductAction(context, [product], action); } }, ); diff --git a/lib/ui/product/product_list.dart b/lib/ui/product/product_list.dart index ad7d6b933..494623a46 100644 --- a/lib/ui/product/product_list.dart +++ b/lib/ui/product/product_list.dart @@ -52,7 +52,7 @@ class ProductList extends StatelessWidget { if (action == EntityAction.more) { showDialog(); } else { - viewModel.onEntityAction(context, product, action); + viewModel.onEntityAction(context, [product], action); } }, onTap: () => viewModel.onProductTap(context, product), diff --git a/lib/ui/product/product_list_vm.dart b/lib/ui/product/product_list_vm.dart index dd605bb53..ed11207ff 100644 --- a/lib/ui/product/product_list_vm.dart +++ b/lib/ui/product/product_list_vm.dart @@ -1,17 +1,18 @@ import 'dart:async'; + import 'package:built_collection/built_collection.dart'; -import 'package:invoiceninja_flutter/redux/product/product_selectors.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; 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:invoiceninja_flutter/ui/product/product_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:redux/redux.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/product/product_list.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/product/product_actions.dart'; class ProductListBuilder extends StatelessWidget { const ProductListBuilder({Key key}) : super(key: key); @@ -66,9 +67,9 @@ class ProductListVM { onProductTap: (context, product) { store.dispatch(ViewProduct(productId: product.id, context: context)); }, - onEntityAction: - (BuildContext context, BaseEntity product, EntityAction action) => - handleProductAction(context, product, action), + onEntityAction: (BuildContext context, List products, + EntityAction action) => + handleProductAction(context, products, action), onRefreshed: (context) => _handleRefresh(context), ); } @@ -81,5 +82,6 @@ class ProductListVM { final bool isLoaded; final Function(BuildContext, ProductEntity) onProductTap; final Function(BuildContext) onRefreshed; - final Function(BuildContext, ProductEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) + onEntityAction; } diff --git a/lib/ui/product/view/product_view_vm.dart b/lib/ui/product/view/product_view_vm.dart index c9c4fc251..08f51d07e 100644 --- a/lib/ui/product/view/product_view_vm.dart +++ b/lib/ui/product/view/product_view_vm.dart @@ -1,16 +1,17 @@ import 'dart:async'; + import 'package:flutter/foundation.dart'; 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/redux/ui/ui_actions.dart'; +import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; import 'package:invoiceninja_flutter/ui/product/product_screen.dart'; import 'package:invoiceninja_flutter/ui/product/view/product_view.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:redux/redux.dart'; -import 'package:invoiceninja_flutter/redux/product/product_actions.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; class ProductViewScreen extends StatelessWidget { const ProductViewScreen({Key key}) : super(key: key); @@ -93,7 +94,7 @@ class ProductViewVM { } }, onEntityAction: (BuildContext context, EntityAction action) => - handleProductAction(context, product, action), + handleProductAction(context, [product], action), ); } diff --git a/lib/ui/project/project_list.dart b/lib/ui/project/project_list.dart index 21d97fe82..90874b0fe 100644 --- a/lib/ui/project/project_list.dart +++ b/lib/ui/project/project_list.dart @@ -95,7 +95,7 @@ class ProjectList extends StatelessWidget { showDialog(); } else { viewModel.onEntityAction( - context, project, action); + context, [project], action); } }, onLongPress: () => showDialog(), diff --git a/lib/ui/project/project_list_vm.dart b/lib/ui/project/project_list_vm.dart index 7daad040b..91f7bebd7 100644 --- a/lib/ui/project/project_list_vm.dart +++ b/lib/ui/project/project_list_vm.dart @@ -1,19 +1,20 @@ import 'dart:async'; -import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; -import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; -import 'package:redux/redux.dart'; -import 'package:flutter/material.dart'; + +import 'package:built_collection/built_collection.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:built_collection/built_collection.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/project/project_actions.dart'; +import 'package:invoiceninja_flutter/redux/project/project_selectors.dart'; +import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/ui/project/project_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/project/project_selectors.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/project/project_list.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/project/project_actions.dart'; +import 'package:redux/redux.dart'; class ProjectListBuilder extends StatelessWidget { const ProjectListBuilder({Key key}) : super(key: key); @@ -83,9 +84,9 @@ class ProjectListVM { onProjectTap: (context, project) { store.dispatch(ViewProject(projectId: project.id, context: context)); }, - onEntityAction: - (BuildContext context, BaseEntity project, EntityAction action) => - handleProjectAction(context, project, action), + onEntityAction: (BuildContext context, List projects, + EntityAction action) => + handleProjectAction(context, projects, action), onRefreshed: (context) => _handleRefresh(context), ); } @@ -100,7 +101,8 @@ class ProjectListVM { final bool isLoaded; final Function(BuildContext, ProjectEntity) onProjectTap; final Function(BuildContext) onRefreshed; - final Function(BuildContext, ProjectEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) + onEntityAction; final Function onClearEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed; } diff --git a/lib/ui/project/view/project_view_vm.dart b/lib/ui/project/view/project_view_vm.dart index 64fe26240..ca1103a10 100644 --- a/lib/ui/project/view/project_view_vm.dart +++ b/lib/ui/project/view/project_view_vm.dart @@ -84,9 +84,9 @@ class ProjectViewVM { userCompany: state.userCompany, context: context, entities: [client], - onEntityAction: (BuildContext context, BaseEntity client, + onEntityAction: (BuildContext context, List clients, EntityAction action) => - handleClientAction(context, client, action)); + handleClientAction(context, clients, action)); } else { store.dispatch(ViewClient(clientId: client.id, context: context)); } @@ -119,7 +119,7 @@ class ProjectViewVM { } }, onEntityAction: (BuildContext context, EntityAction action) => - handleProjectAction(context, project, action), + handleProjectAction(context, [project], action), ); } diff --git a/lib/ui/quote/quote_list_vm.dart b/lib/ui/quote/quote_list_vm.dart index 9f7cd5fba..a9564f0b4 100644 --- a/lib/ui/quote/quote_list_vm.dart +++ b/lib/ui/quote/quote_list_vm.dart @@ -49,7 +49,7 @@ class QuoteListVM extends EntityListVM { Function(BuildContext) onRefreshed, Function onClearEntityFilterPressed, Function(BuildContext) onViewEntityFilterPressed, - Function(BuildContext, InvoiceEntity, EntityAction) onEntityAction, + Function(BuildContext, List, EntityAction) onEntityAction, }) : super( state: state, user: user, @@ -100,8 +100,8 @@ class QuoteListVM extends EntityListVM { ViewClient( clientId: state.quoteListState.filterEntityId, context: context)), onEntityAction: - (BuildContext context, BaseEntity quote, EntityAction action) => - handleQuoteAction(context, quote, action), + (BuildContext context, List quotes, EntityAction action) => + handleQuoteAction(context, quotes, action), ); } } diff --git a/lib/ui/quote/view/quote_view_vm.dart b/lib/ui/quote/view/quote_view_vm.dart index 8716d83c2..c6d25bcff 100644 --- a/lib/ui/quote/view/quote_view_vm.dart +++ b/lib/ui/quote/view/quote_view_vm.dart @@ -125,15 +125,15 @@ class QuoteViewVM extends EntityViewVM { userCompany: state.userCompany, context: context, entities: [client], - onEntityAction: (BuildContext context, BaseEntity client, + onEntityAction: (BuildContext context, List clients, EntityAction action) => - handleClientAction(context, client, action)); + handleClientAction(context, clients, action)); } else { store.dispatch(ViewClient(clientId: client.id, context: context)); } }, onEntityAction: (BuildContext context, EntityAction action) => - handleQuoteAction(context, quote, action), + handleQuoteAction(context, [quote], action), onUploadDocument: (BuildContext context, String path) { final Completer completer = Completer(); final document = DocumentEntity().rebuild((b) => b diff --git a/lib/ui/task/task_list.dart b/lib/ui/task/task_list.dart index 461864ca5..84ec3ac81 100644 --- a/lib/ui/task/task_list.dart +++ b/lib/ui/task/task_list.dart @@ -110,7 +110,7 @@ class TaskList extends StatelessWidget { showDialog(); } else { viewModel.onEntityAction( - context, task, action); + context, [task], action); } }, onLongPress: () => showDialog(), diff --git a/lib/ui/task/task_list_vm.dart b/lib/ui/task/task_list_vm.dart index 450d995fa..0018de2bc 100644 --- a/lib/ui/task/task_list_vm.dart +++ b/lib/ui/task/task_list_vm.dart @@ -1,20 +1,21 @@ import 'dart:async'; -import 'package:invoiceninja_flutter/redux/project/project_actions.dart'; -import 'package:redux/redux.dart'; -import 'package:flutter/material.dart'; + +import 'package:built_collection/built_collection.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:built_collection/built_collection.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/project/project_actions.dart'; +import 'package:invoiceninja_flutter/redux/task/task_actions.dart'; +import 'package:invoiceninja_flutter/redux/task/task_selectors.dart'; import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/ui/task/task_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/task/task_selectors.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/task/task_list.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/task/task_actions.dart'; +import 'package:redux/redux.dart'; class TaskListBuilder extends StatelessWidget { const TaskListBuilder({Key key}) : super(key: key); @@ -97,8 +98,8 @@ class TaskListVM { store.dispatch(ViewTask(taskId: task.id, context: context)); }, onEntityAction: - (BuildContext context, BaseEntity task, EntityAction action) => - handleTaskAction(context, task, action), + (BuildContext context, List tasks, EntityAction action) => + handleTaskAction(context, tasks, action), onRefreshed: (context) => _handleRefresh(context), ); } @@ -114,7 +115,7 @@ class TaskListVM { final bool isLoaded; final Function(BuildContext, TaskEntity) onTaskTap; final Function(BuildContext) onRefreshed; - final Function(BuildContext, TaskEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) onEntityAction; final Function onClearEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed; } diff --git a/lib/ui/task/view/task_view_vm.dart b/lib/ui/task/view/task_view_vm.dart index bb3ed5eee..d07a4bc48 100644 --- a/lib/ui/task/view/task_view_vm.dart +++ b/lib/ui/task/view/task_view_vm.dart @@ -113,9 +113,9 @@ class TaskViewVM { userCompany: state.userCompany, context: context, entities: [client], - onEntityAction: (BuildContext context, BaseEntity client, + onEntityAction: (BuildContext context, List clients, EntityAction action) => - handleClientAction(context, client, action)); + handleClientAction(context, clients, action)); } else { store.dispatch(ViewClient(clientId: client.id, context: context)); } @@ -127,9 +127,9 @@ class TaskViewVM { context: context, entities: [project], client: client, - onEntityAction: (BuildContext context, BaseEntity project, + onEntityAction: (BuildContext context, List projects, EntityAction action) => - handleProjectAction(context, project, action)); + handleProjectAction(context, projects, action)); } else { store.dispatch(ViewProject(projectId: project.id, context: context)); } @@ -141,9 +141,9 @@ class TaskViewVM { context: context, entities: [invoice], client: client, - onEntityAction: (BuildContext context, BaseEntity invoice, + onEntityAction: (BuildContext context, List invoices, EntityAction action) => - handleInvoiceAction(context, invoice, action)); + handleInvoiceAction(context, invoices, action)); } else { store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context)); } @@ -170,7 +170,7 @@ class TaskViewVM { } }, onEntityAction: (BuildContext context, EntityAction action) => - handleTaskAction(context, task, action), + handleTaskAction(context, [task], action), ); } diff --git a/lib/ui/vendor/vendor_list.dart b/lib/ui/vendor/vendor_list.dart index 60ba70fa4..f120f93e2 100644 --- a/lib/ui/vendor/vendor_list.dart +++ b/lib/ui/vendor/vendor_list.dart @@ -54,7 +54,7 @@ class VendorList extends StatelessWidget { showDialog(); } else { viewModel.onEntityAction( - context, vendor, action); + context, [vendor], action); } }, onLongPress: () => showDialog(), diff --git a/lib/ui/vendor/vendor_list_vm.dart b/lib/ui/vendor/vendor_list_vm.dart index c36a3ec3c..09bbd3cc2 100644 --- a/lib/ui/vendor/vendor_list_vm.dart +++ b/lib/ui/vendor/vendor_list_vm.dart @@ -1,19 +1,20 @@ import 'dart:async'; -import 'package:redux/redux.dart'; -import 'package:flutter/material.dart'; + +import 'package:built_collection/built_collection.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_redux/flutter_redux.dart'; -import 'package:built_collection/built_collection.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/ui/list_ui_state.dart'; +import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart'; +import 'package:invoiceninja_flutter/redux/vendor/vendor_selectors.dart'; +import 'package:invoiceninja_flutter/ui/vendor/vendor_list.dart'; import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; -import 'package:invoiceninja_flutter/redux/vendor/vendor_selectors.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/vendor/vendor_list.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; -import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart'; +import 'package:redux/redux.dart'; class VendorListBuilder extends StatelessWidget { const VendorListBuilder({Key key}) : super(key: key); @@ -77,9 +78,9 @@ class VendorListVM { onVendorTap: (context, vendor) { store.dispatch(ViewVendor(vendorId: vendor.id, context: context)); }, - onEntityAction: - (BuildContext context, BaseEntity vendor, EntityAction action) => - handleVendorAction(context, vendor, action), + onEntityAction: (BuildContext context, List vendors, + EntityAction action) => + handleVendorAction(context, vendors, action), onRefreshed: (context) => _handleRefresh(context), ); } @@ -93,7 +94,7 @@ class VendorListVM { final bool isLoaded; final Function(BuildContext, VendorEntity) onVendorTap; final Function(BuildContext) onRefreshed; - final Function(BuildContext, VendorEntity, EntityAction) onEntityAction; + final Function(BuildContext, List, EntityAction) onEntityAction; final Function onClearEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed; } diff --git a/lib/ui/vendor/view/vendor_view_vm.dart b/lib/ui/vendor/view/vendor_view_vm.dart index fb3e3288c..4b78ee4cd 100644 --- a/lib/ui/vendor/view/vendor_view_vm.dart +++ b/lib/ui/vendor/view/vendor_view_vm.dart @@ -1,19 +1,20 @@ import 'dart:async'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_redux/flutter_redux.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; +import 'package:invoiceninja_flutter/data/models/vendor_model.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart'; import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; +import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart'; import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; -import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/ui/vendor/vendor_screen.dart'; +import 'package:invoiceninja_flutter/ui/vendor/view/vendor_view.dart'; +import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:redux/redux.dart'; -import 'package:flutter_redux/flutter_redux.dart'; -import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart'; -import 'package:invoiceninja_flutter/data/models/vendor_model.dart'; -import 'package:invoiceninja_flutter/data/models/models.dart'; -import 'package:invoiceninja_flutter/ui/vendor/view/vendor_view.dart'; -import 'package:invoiceninja_flutter/redux/app/app_state.dart'; class VendorViewScreen extends StatelessWidget { const VendorViewScreen({Key key}) : super(key: key); @@ -108,7 +109,7 @@ class VendorViewVM { expense: ExpenseEntity(company: company, vendor: vendor), context: context)), onEntityAction: (BuildContext context, EntityAction action) => - handleVendorAction(context, vendor, action), + handleVendorAction(context, [vendor], action), ); }