Refactorerd Actions to take Lists

This commit is contained in:
Gianfranco Gasbarri 2019-09-30 00:28:17 +01:00
parent c06ac2cd07
commit f8fa32b516
42 changed files with 500 additions and 390 deletions

View File

@ -1,12 +1,13 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:core'; 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: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/models.dart';
import 'package:invoiceninja_flutter/data/models/serializers.dart';
import 'package:invoiceninja_flutter/data/web_client.dart'; import 'package:invoiceninja_flutter/data/web_client.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class ClientRepository { class ClientRepository {
const ClientRepository({ const ClientRepository({
@ -47,8 +48,34 @@ class ClientRepository {
return clientResponse.data; return clientResponse.data;
} }
Future<ClientEntity> saveData(Credentials credentials, ClientEntity client, Future<List<ClientEntity>> bulkAction(
[EntityAction action]) async { Credentials credentials, List<String> 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<ClientEntity> saveData(
Credentials credentials, ClientEntity client) async {
final data = serializers.serializeWith(ClientEntity.serializer, client); final data = serializers.serializeWith(ClientEntity.serializer, client);
dynamic response; dynamic response;

View File

@ -175,60 +175,60 @@ class SaveClientFailure implements StopSaving {
} }
class ArchiveClientRequest implements StartSaving { class ArchiveClientRequest implements StartSaving {
ArchiveClientRequest(this.completer, this.clientId); ArchiveClientRequest(this.completer, this.clientIds);
final Completer completer; final Completer completer;
final String clientId; final List<String> clientIds;
} }
class ArchiveClientSuccess implements StopSaving, PersistData { class ArchiveClientSuccess implements StopSaving, PersistData {
ArchiveClientSuccess(this.client); ArchiveClientSuccess(this.clients);
final ClientEntity client; final List<ClientEntity> clients;
} }
class ArchiveClientFailure implements StopSaving { class ArchiveClientFailure implements StopSaving {
ArchiveClientFailure(this.client); ArchiveClientFailure(this.clients);
final ClientEntity client; final List<ClientEntity> clients;
} }
class DeleteClientRequest implements StartSaving { class DeleteClientRequest implements StartSaving {
DeleteClientRequest(this.completer, this.clientId); DeleteClientRequest(this.completer, this.clientIds);
final Completer completer; final Completer completer;
final String clientId; final List<String> clientIds;
} }
class DeleteClientSuccess implements StopSaving, PersistData { class DeleteClientSuccess implements StopSaving, PersistData {
DeleteClientSuccess(this.client); DeleteClientSuccess(this.clients);
final ClientEntity client; final List<ClientEntity> clients;
} }
class DeleteClientFailure implements StopSaving { class DeleteClientFailure implements StopSaving {
DeleteClientFailure(this.client); DeleteClientFailure(this.clients);
final ClientEntity client; final List<ClientEntity> clients;
} }
class RestoreClientRequest implements StartSaving { class RestoreClientRequest implements StartSaving {
RestoreClientRequest(this.completer, this.clientId); RestoreClientRequest(this.completer, this.clientIds);
final Completer completer; final Completer completer;
final String clientId; final List<String> clientIds;
} }
class RestoreClientSuccess implements StopSaving, PersistData { class RestoreClientSuccess implements StopSaving, PersistData {
RestoreClientSuccess(this.client); RestoreClientSuccess(this.clients);
final ClientEntity client; final List<ClientEntity> clients;
} }
class RestoreClientFailure implements StopSaving { class RestoreClientFailure implements StopSaving {
RestoreClientFailure(this.client); RestoreClientFailure(this.clients);
final ClientEntity client; final List<ClientEntity> clients;
} }
class FilterClients { class FilterClients {
@ -269,71 +269,64 @@ class FilterClientsByCustom2 implements PersistUI {
} }
void handleClientAction( void handleClientAction(
BuildContext context, ClientEntity client, EntityAction action) { BuildContext context, List<ClientEntity> 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<AppState>(context); final store = StoreProvider.of<AppState>(context);
final state = store.state; final state = store.state;
final CompanyEntity company = state.selectedCompany; final CompanyEntity company = state.selectedCompany;
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
final multiselect = state.clientListState.isInMultiselect(); final clientIds = clients.map((client) => client.id).toList();
final isMultiselectLast =
client == state.clientListState.selectedEntities.last;
switch (action) { switch (action) {
case EntityAction.edit: case EntityAction.edit:
store.dispatch(EditClient(context: context, client: client)); store.dispatch(EditClient(context: context, client: clients[0]));
break; break;
case EntityAction.newInvoice: case EntityAction.newInvoice:
store.dispatch(EditInvoice( store.dispatch(EditInvoice(
invoice: InvoiceEntity(company: company) invoice: InvoiceEntity(company: company)
.rebuild((b) => b.clientId = client.id), .rebuild((b) => b.clientId = clients[0].id),
context: context)); context: context));
break; break;
case EntityAction.newExpense: case EntityAction.newExpense:
store.dispatch(EditExpense( store.dispatch(EditExpense(
expense: ExpenseEntity( expense: ExpenseEntity(
company: company, client: client, uiState: state.uiState), company: company, client: clients[0], uiState: state.uiState),
context: context)); context: context));
break; break;
case EntityAction.enterPayment: case EntityAction.enterPayment:
store.dispatch(EditPayment( store.dispatch(EditPayment(
payment: PaymentEntity(company: company) payment: PaymentEntity(company: company)
.rebuild((b) => b.clientId = client.id), .rebuild((b) => b.clientId = clients[0].id),
context: context)); context: context));
break; break;
case EntityAction.restore: case EntityAction.restore:
if (multiselect && !isMultiselectLast) { store.dispatch(RestoreClientRequest(
store.dispatch(RestoreClientRequest(null, client.id)); snackBarCompleter(context, localization.restoredClient), clientIds));
} else {
store.dispatch(RestoreClientRequest(
snackBarCompleter(context, localization.restoredClient),
client.id));
}
break; break;
case EntityAction.archive: case EntityAction.archive:
if (multiselect && !isMultiselectLast) { store.dispatch(ArchiveClientRequest(
store.dispatch(ArchiveClientRequest(null, client.id)); snackBarCompleter(context, localization.archivedClient), clientIds));
} else {
store.dispatch(ArchiveClientRequest(
snackBarCompleter(context, localization.archivedClient),
client.id));
}
break; break;
case EntityAction.delete: case EntityAction.delete:
if (multiselect && !isMultiselectLast) { store.dispatch(DeleteClientRequest(
store.dispatch(DeleteClientRequest(null, client.id)); snackBarCompleter(context, localization.deletedClient), clientIds));
} else {
store.dispatch(DeleteClientRequest(
snackBarCompleter(context, localization.deletedClient), client.id));
}
break; break;
case EntityAction.toggleMultiselect: case EntityAction.toggleMultiselect:
if (!store.state.clientListState.isInMultiselect()) { if (!store.state.clientListState.isInMultiselect()) {
store.dispatch(StartMultiselect(context: context)); store.dispatch(StartMultiselect(context: context));
} }
if (!store.state.clientListState.isSelected(client)) {
store.dispatch(AddToMultiselect(context: context, entity: client)); for (final client in clients) {
} else { if (!store.state.clientListState.isSelected(client)) {
store.dispatch(RemoveFromMultiselect(context: context, entity: client)); store.dispatch(AddToMultiselect(context: context, entity: client));
} else {
store.dispatch(
RemoveFromMultiselect(context: context, entity: client));
}
} }
break; break;
} }

View File

@ -1,16 +1,16 @@
import 'package:redux/redux.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.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_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/product/product_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_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/client_screen.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.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/ui/client/view/client_view_vm.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/repositories/client_repository.dart';
List<Middleware<AppState>> createStoreClientsMiddleware([ List<Middleware<AppState>> createStoreClientsMiddleware([
ClientRepository repository = const ClientRepository(), ClientRepository repository = const ClientRepository(),
@ -105,17 +105,20 @@ Middleware<AppState> _viewClientList() {
Middleware<AppState> _archiveClient(ClientRepository repository) { Middleware<AppState> _archiveClient(ClientRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ArchiveClientRequest; final action = dynamicAction as ArchiveClientRequest;
final origClient = store.state.clientState.map[action.clientId];
repository repository
.saveData(store.state.credentials, origClient, EntityAction.archive) .bulkAction(
.then((ClientEntity client) { store.state.credentials, action.clientIds, EntityAction.archive)
store.dispatch(ArchiveClientSuccess(client)); .then((List<ClientEntity> clients) {
store.dispatch(ArchiveClientSuccess(clients));
if (action.completer != null) { if (action.completer != null) {
action.completer.complete(null); action.completer.complete(null);
} }
}).catchError((Object error) { }).catchError((Object error) {
print(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) { if (action.completer != null) {
action.completer.completeError(error); action.completer.completeError(error);
} }
@ -128,17 +131,20 @@ Middleware<AppState> _archiveClient(ClientRepository repository) {
Middleware<AppState> _deleteClient(ClientRepository repository) { Middleware<AppState> _deleteClient(ClientRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as DeleteClientRequest; final action = dynamicAction as DeleteClientRequest;
final origClient = store.state.clientState.map[action.clientId];
repository repository
.saveData(store.state.credentials, origClient, EntityAction.delete) .bulkAction(
.then((ClientEntity client) { store.state.credentials, action.clientIds, EntityAction.delete)
store.dispatch(DeleteClientSuccess(client)); .then((List<ClientEntity> clients) {
store.dispatch(DeleteClientSuccess(clients));
if (action.completer != null) { if (action.completer != null) {
action.completer.complete(null); action.completer.complete(null);
} }
}).catchError((Object error) { }).catchError((Object error) {
print(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) { if (action.completer != null) {
action.completer.completeError(error); action.completer.completeError(error);
} }
@ -151,17 +157,20 @@ Middleware<AppState> _deleteClient(ClientRepository repository) {
Middleware<AppState> _restoreClient(ClientRepository repository) { Middleware<AppState> _restoreClient(ClientRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as RestoreClientRequest; final action = dynamicAction as RestoreClientRequest;
final origClient = store.state.clientState.map[action.clientId];
repository repository
.saveData(store.state.credentials, origClient, EntityAction.restore) .bulkAction(
.then((ClientEntity client) { store.state.credentials, action.clientIds, EntityAction.restore)
store.dispatch(RestoreClientSuccess(client)); .then((List<ClientEntity> clients) {
store.dispatch(RestoreClientSuccess(clients));
if (action.completer != null) { if (action.completer != null) {
action.completer.complete(null); action.completer.complete(null);
} }
}).catchError((Object error) { }).catchError((Object error) {
print(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) { if (action.completer != null) {
action.completer.completeError(error); action.completer.completeError(error);
} }

View File

@ -58,14 +58,14 @@ final editingReducer = combineReducers<ClientEntity>([
TypedReducer<ClientEntity, AddClientSuccess>((client, action) { TypedReducer<ClientEntity, AddClientSuccess>((client, action) {
return action.client; return action.client;
}), }),
TypedReducer<ClientEntity, RestoreClientSuccess>((client, action) { TypedReducer<ClientEntity, RestoreClientSuccess>((clients, action) {
return action.client; return action.clients[0];
}), }),
TypedReducer<ClientEntity, ArchiveClientSuccess>((client, action) { TypedReducer<ClientEntity, ArchiveClientSuccess>((clients, action) {
return action.client; return action.clients[0];
}), }),
TypedReducer<ClientEntity, DeleteClientSuccess>((client, action) { TypedReducer<ClientEntity, DeleteClientSuccess>((clients, action) {
return action.client; return action.clients[0];
}), }),
TypedReducer<ClientEntity, EditClient>((client, action) { TypedReducer<ClientEntity, EditClient>((client, action) {
return action.client; return action.client;
@ -197,57 +197,103 @@ final clientsReducer = combineReducers<ClientState>([
ClientState _archiveClientRequest( ClientState _archiveClientRequest(
ClientState clientState, ArchiveClientRequest action) { ClientState clientState, ArchiveClientRequest action) {
final client = clientState.map[action.clientId] final clients = action.clientIds.map((id) => clientState.map[id]).toList();
.rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch);
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 _archiveClientSuccess(
ClientState clientState, ArchiveClientSuccess action) { 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 _archiveClientFailure(
ClientState clientState, ArchiveClientFailure action) { 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 _deleteClientRequest(
ClientState clientState, DeleteClientRequest action) { ClientState clientState, DeleteClientRequest action) {
final client = clientState.map[action.clientId].rebuild((b) => b final clients = action.clientIds.map((id) => clientState.map[id]).toList();
..archivedAt = DateTime.now().millisecondsSinceEpoch
..isDeleted = true);
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 _deleteClientSuccess(
ClientState clientState, DeleteClientSuccess action) { 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 _deleteClientFailure(
ClientState clientState, DeleteClientFailure action) { 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 _restoreClientRequest(
ClientState clientState, RestoreClientRequest action) { ClientState clientState, RestoreClientRequest action) {
final client = clientState.map[action.clientId].rebuild((b) => b final clients = action.clientIds.map((id) => clientState.map[id]).toList();
..archivedAt = null
..isDeleted = false); for (int i = 0; i < clients.length; i++) {
return clientState.rebuild((b) => b..map[action.clientId] = client); 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 _restoreClientSuccess(
ClientState clientState, RestoreClientSuccess action) { 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 _restoreClientFailure(
ClientState clientState, RestoreClientFailure action) { 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) { ClientState _addClient(ClientState clientState, AddClientSuccess action) {

View File

@ -1,17 +1,18 @@
import 'dart:async'; 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: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/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/payment/payment_actions.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_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/pdf.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -322,8 +323,8 @@ class FilterInvoicesByCustom2 implements PersistUI {
final String value; final String value;
} }
void handleInvoiceAction( void handleInvoiceAction(BuildContext context, List<InvoiceEntity> invoices,
BuildContext context, InvoiceEntity invoice, EntityAction action) async { EntityAction action) async {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final state = store.state; final state = store.state;
final CompanyEntity company = state.selectedCompany; final CompanyEntity company = state.selectedCompany;
@ -331,27 +332,27 @@ void handleInvoiceAction(
switch (action) { switch (action) {
case EntityAction.edit: case EntityAction.edit:
store.dispatch(EditInvoice(context: context, invoice: invoice)); store.dispatch(EditInvoice(context: context, invoice: invoices[0]));
break; break;
case EntityAction.pdf: case EntityAction.pdf:
viewPdf(invoice, context); viewPdf(invoices[0], context);
break; break;
case EntityAction.clientPortal: case EntityAction.clientPortal:
if (await canLaunch(invoice.invitationSilentLink)) { if (await canLaunch(invoices[0].invitationSilentLink)) {
await launch(invoice.invitationSilentLink, await launch(invoices[0].invitationSilentLink,
forceSafariVC: false, forceWebView: false); forceSafariVC: false, forceWebView: false);
} }
break; break;
case EntityAction.markSent: case EntityAction.markSent:
store.dispatch(MarkSentInvoiceRequest( store.dispatch(MarkSentInvoiceRequest(
snackBarCompleter(context, localization.markedInvoiceAsSent), snackBarCompleter(context, localization.markedInvoiceAsSent),
invoice.id)); invoices[0].id));
break; break;
case EntityAction.sendEmail: case EntityAction.sendEmail:
if (isMobile(context)) { if (isMobile(context)) {
store.dispatch(ShowEmailInvoice( store.dispatch(ShowEmailInvoice(
completer: snackBarCompleter(context, localization.emailedInvoice), completer: snackBarCompleter(context, localization.emailedInvoice),
invoice: invoice, invoice: invoices[0],
context: context)); context: context));
} else { } else {
showDialog<ResponsivePadding>( showDialog<ResponsivePadding>(
@ -363,28 +364,30 @@ void handleInvoiceAction(
break; break;
case EntityAction.cloneToInvoice: case EntityAction.cloneToInvoice:
store.dispatch( store.dispatch(
EditInvoice(context: context, invoice: invoice.cloneToInvoice)); EditInvoice(context: context, invoice: invoices[0].cloneToInvoice));
break; break;
case EntityAction.cloneToQuote: case EntityAction.cloneToQuote:
store.dispatch(EditQuote(context: context, quote: invoice.cloneToQuote)); store.dispatch(
EditQuote(context: context, quote: invoices[0].cloneToQuote));
break; break;
case EntityAction.enterPayment: case EntityAction.enterPayment:
store.dispatch(EditPayment( store.dispatch(EditPayment(
context: context, payment: invoice.createPayment(company))); context: context, payment: invoices[0].createPayment(company)));
break; break;
case EntityAction.restore: case EntityAction.restore:
store.dispatch(RestoreInvoiceRequest( store.dispatch(RestoreInvoiceRequest(
snackBarCompleter(context, localization.restoredInvoice), snackBarCompleter(context, localization.restoredInvoice),
invoice.id)); invoices[0].id));
break; break;
case EntityAction.archive: case EntityAction.archive:
store.dispatch(ArchiveInvoiceRequest( store.dispatch(ArchiveInvoiceRequest(
snackBarCompleter(context, localization.archivedInvoice), snackBarCompleter(context, localization.archivedInvoice),
invoice.id)); invoices[0].id));
break; break;
case EntityAction.delete: case EntityAction.delete:
store.dispatch(DeleteInvoiceRequest( store.dispatch(DeleteInvoiceRequest(
snackBarCompleter(context, localization.deletedInvoice), invoice.id)); snackBarCompleter(context, localization.deletedInvoice),
invoices[0].id));
break; break;
} }
} }

View File

@ -1,9 +1,10 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:built_collection/built_collection.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/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.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/app/app_state.dart';
import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
@ -251,31 +252,33 @@ class FilterPaymentsByEntity implements PersistUI {
} }
void handlePaymentAction( void handlePaymentAction(
BuildContext context, PaymentEntity payment, EntityAction action) { BuildContext context, List<PaymentEntity> payments, EntityAction action) {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
switch (action) { switch (action) {
case EntityAction.edit: case EntityAction.edit:
store.dispatch(EditPayment(context: context, payment: payment)); store.dispatch(EditPayment(context: context, payment: payments[0]));
break; break;
case EntityAction.sendEmail: case EntityAction.sendEmail:
store.dispatch(EmailPaymentRequest( store.dispatch(EmailPaymentRequest(
snackBarCompleter(context, localization.emailedPayment), payment)); snackBarCompleter(context, localization.emailedPayment),
payments[0]));
break; break;
case EntityAction.restore: case EntityAction.restore:
store.dispatch(RestorePaymentRequest( store.dispatch(RestorePaymentRequest(
snackBarCompleter(context, localization.restoredPayment), snackBarCompleter(context, localization.restoredPayment),
payment.id)); payments[0].id));
break; break;
case EntityAction.archive: case EntityAction.archive:
store.dispatch(ArchivePaymentRequest( store.dispatch(ArchivePaymentRequest(
snackBarCompleter(context, localization.archivedPayment), snackBarCompleter(context, localization.archivedPayment),
payment.id)); payments[0].id));
break; break;
case EntityAction.delete: case EntityAction.delete:
store.dispatch(DeletePaymentRequest( store.dispatch(DeletePaymentRequest(
snackBarCompleter(context, localization.deletedPayment), payment.id)); snackBarCompleter(context, localization.deletedPayment),
payments[0].id));
break; break;
} }
} }

View File

@ -1,12 +1,13 @@
import 'dart:async'; 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: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: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/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/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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
@ -195,7 +196,7 @@ class FilterProductDropdown {
} }
void handleProductAction( void handleProductAction(
BuildContext context, ProductEntity product, EntityAction action) { BuildContext context, List<ProductEntity> products, EntityAction action) {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final state = store.state; final state = store.state;
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
@ -203,31 +204,32 @@ void handleProductAction(
switch (action) { switch (action) {
case EntityAction.newInvoice: case EntityAction.newInvoice:
final item = final item =
convertProductToInvoiceItem(context: context, product: product); convertProductToInvoiceItem(context: context, product: products[0]);
store.dispatch(EditInvoice( store.dispatch(EditInvoice(
context: context, context: context,
invoice: InvoiceEntity(company: state.selectedCompany) invoice: InvoiceEntity(company: state.selectedCompany)
.rebuild((b) => b..invoiceItems.add(item)))); .rebuild((b) => b..invoiceItems.add(item))));
break; break;
case EntityAction.edit: case EntityAction.edit:
store.dispatch(EditProduct(context: context, product: product)); store.dispatch(EditProduct(context: context, product: products[0]));
break; break;
case EntityAction.clone: case EntityAction.clone:
store.dispatch(EditProduct(context: context, product: product.clone)); store.dispatch(EditProduct(context: context, product: products[0].clone));
break; break;
case EntityAction.restore: case EntityAction.restore:
store.dispatch(RestoreProductRequest( store.dispatch(RestoreProductRequest(
snackBarCompleter(context, localization.restoredProduct), snackBarCompleter(context, localization.restoredProduct),
product.id)); products[0].id));
break; break;
case EntityAction.archive: case EntityAction.archive:
store.dispatch(ArchiveProductRequest( store.dispatch(ArchiveProductRequest(
snackBarCompleter(context, localization.archivedProduct), snackBarCompleter(context, localization.archivedProduct),
product.id)); products[0].id));
break; break;
case EntityAction.delete: case EntityAction.delete:
store.dispatch(DeleteProductRequest( store.dispatch(DeleteProductRequest(
snackBarCompleter(context, localization.deletedProduct), product.id)); snackBarCompleter(context, localization.deletedProduct),
products[0].id));
break; break;
} }
} }

View File

@ -242,53 +242,53 @@ class FilterProjectsByEntity implements PersistUI {
} }
void handleProjectAction( void handleProjectAction(
BuildContext context, ProjectEntity project, EntityAction action) { BuildContext context, List<ProjectEntity> projects, EntityAction action) {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final state = store.state; final state = store.state;
final CompanyEntity company = state.selectedCompany; final CompanyEntity company = state.selectedCompany;
switch (action) { switch (action) {
case EntityAction.edit: case EntityAction.edit:
store.dispatch(EditProject(context: context, project: project)); store.dispatch(EditProject(context: context, project: projects[0]));
break; break;
case EntityAction.newTask: case EntityAction.newTask:
store.dispatch(EditTask( store.dispatch(EditTask(
task: TaskEntity(isRunning: state.uiState.autoStartTasks) task: TaskEntity(isRunning: state.uiState.autoStartTasks)
.rebuild((b) => b .rebuild((b) => b
..projectId = project.id ..projectId = projects[0].id
..clientId = project.clientId), ..clientId = projects[0].clientId),
context: context)); context: context));
break; break;
case EntityAction.newInvoice: case EntityAction.newInvoice:
final items = final items =
convertProjectToInvoiceItem(project: project, context: context); convertProjectToInvoiceItem(project: projects[0], context: context);
store.dispatch(EditInvoice( store.dispatch(EditInvoice(
invoice: InvoiceEntity(company: company).rebuild((b) => b invoice: InvoiceEntity(company: company).rebuild((b) => b
..hasTasks = true ..hasTasks = true
..clientId = project.clientId ..clientId = projects[0].clientId
..invoiceItems.addAll(items)), ..invoiceItems.addAll(items)),
context: context)); context: context));
break; break;
case EntityAction.clone: case EntityAction.clone:
store.dispatch(EditProject(context: context, project: project.clone)); store.dispatch(EditProject(context: context, project: projects[0].clone));
break; break;
case EntityAction.restore: case EntityAction.restore:
store.dispatch(RestoreProjectRequest( store.dispatch(RestoreProjectRequest(
snackBarCompleter( snackBarCompleter(
context, AppLocalization.of(context).restoredProject), context, AppLocalization.of(context).restoredProject),
project.id)); projects[0].id));
break; break;
case EntityAction.archive: case EntityAction.archive:
store.dispatch(ArchiveProjectRequest( store.dispatch(ArchiveProjectRequest(
snackBarCompleter( snackBarCompleter(
context, AppLocalization.of(context).archivedProject), context, AppLocalization.of(context).archivedProject),
project.id)); projects[0].id));
break; break;
case EntityAction.delete: case EntityAction.delete:
store.dispatch(DeleteProjectRequest( store.dispatch(DeleteProjectRequest(
snackBarCompleter( snackBarCompleter(
context, AppLocalization.of(context).deletedProject), context, AppLocalization.of(context).deletedProject),
project.id)); projects[0].id));
break; break;
} }
} }

View File

@ -1,16 +1,17 @@
import 'dart:async'; 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: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: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/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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/pdf.dart'; import 'package:invoiceninja_flutter/utils/pdf.dart';
import 'package:url_launcher/url_launcher.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 { class ViewQuoteList implements PersistUI {
ViewQuoteList({this.context, this.force = false}); ViewQuoteList({this.context, this.force = false});
@ -338,31 +339,31 @@ class ConvertQuoteFailure implements StopSaving {
final dynamic error; final dynamic error;
} }
Future handleQuoteAction( Future handleQuoteAction(BuildContext context, List<InvoiceEntity> quotes,
BuildContext context, InvoiceEntity quote, EntityAction action) async { EntityAction action) async {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
switch (action) { switch (action) {
case EntityAction.edit: case EntityAction.edit:
store.dispatch(EditQuote(context: context, quote: quote)); store.dispatch(EditQuote(context: context, quote: quotes[0]));
break; break;
case EntityAction.pdf: case EntityAction.pdf:
viewPdf(quote, context); viewPdf(quotes[0], context);
break; break;
case EntityAction.clientPortal: case EntityAction.clientPortal:
if (await canLaunch(quote.invitationSilentLink)) { if (await canLaunch(quotes[0].invitationSilentLink)) {
await launch(quote.invitationSilentLink, await launch(quotes[0].invitationSilentLink,
forceSafariVC: false, forceWebView: false); forceSafariVC: false, forceWebView: false);
} }
break; break;
case EntityAction.viewInvoice: case EntityAction.viewInvoice:
store.dispatch( store.dispatch(
ViewInvoice(context: context, invoiceId: quote.quoteInvoiceId)); ViewInvoice(context: context, invoiceId: quotes[0].quoteInvoiceId));
break; break;
case EntityAction.convert: case EntityAction.convert:
final Completer<InvoiceEntity> completer = Completer<InvoiceEntity>(); final Completer<InvoiceEntity> completer = Completer<InvoiceEntity>();
store.dispatch(ConvertQuote(completer, quote.id)); store.dispatch(ConvertQuote(completer, quotes[0].id));
completer.future.then((InvoiceEntity invoice) { completer.future.then((InvoiceEntity invoice) {
store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context)); store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context));
}); });
@ -370,32 +371,35 @@ Future handleQuoteAction(
case EntityAction.markSent: case EntityAction.markSent:
store.dispatch(MarkSentQuoteRequest( store.dispatch(MarkSentQuoteRequest(
snackBarCompleter(context, localization.markedQuoteAsSent), snackBarCompleter(context, localization.markedQuoteAsSent),
quote.id)); quotes[0].id));
break; break;
case EntityAction.sendEmail: case EntityAction.sendEmail:
store.dispatch(ShowEmailQuote( store.dispatch(ShowEmailQuote(
completer: snackBarCompleter(context, localization.emailedQuote), completer: snackBarCompleter(context, localization.emailedQuote),
quote: quote, quote: quotes[0],
context: context)); context: context));
break; break;
case EntityAction.cloneToInvoice: case EntityAction.cloneToInvoice:
store.dispatch( store.dispatch(
EditInvoice(context: context, invoice: quote.cloneToInvoice)); EditInvoice(context: context, invoice: quotes[0].cloneToInvoice));
break; break;
case EntityAction.cloneToQuote: case EntityAction.cloneToQuote:
store.dispatch(EditQuote(context: context, quote: quote.cloneToQuote)); store
.dispatch(EditQuote(context: context, quote: quotes[0].cloneToQuote));
break; break;
case EntityAction.restore: case EntityAction.restore:
store.dispatch(RestoreQuoteRequest( store.dispatch(RestoreQuoteRequest(
snackBarCompleter(context, localization.restoredQuote), quote.id)); snackBarCompleter(context, localization.restoredQuote),
quotes[0].id));
break; break;
case EntityAction.archive: case EntityAction.archive:
store.dispatch(ArchiveQuoteRequest( store.dispatch(ArchiveQuoteRequest(
snackBarCompleter(context, localization.archivedQuote), quote.id)); snackBarCompleter(context, localization.archivedQuote),
quotes[0].id));
break; break;
case EntityAction.delete: case EntityAction.delete:
store.dispatch(DeleteQuoteRequest( store.dispatch(DeleteQuoteRequest(
snackBarCompleter(context, localization.deletedQuote), quote.id)); snackBarCompleter(context, localization.deletedQuote), quotes[0].id));
break; break;
} }
} }

View File

@ -1,17 +1,18 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:built_collection/built_collection.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/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.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/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/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/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:flutter/material.dart'; import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/redux/task/task_selectors.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class ViewTaskList implements PersistUI { class ViewTaskList implements PersistUI {
ViewTaskList({@required this.context, this.force = false}); ViewTaskList({@required this.context, this.force = false});
@ -276,7 +277,7 @@ class FilterTasksByEntity implements PersistUI {
} }
void handleTaskAction( void handleTaskAction(
BuildContext context, TaskEntity task, EntityAction action) { BuildContext context, List<TaskEntity> tasks, EntityAction action) {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final state = store.state; final state = store.state;
final CompanyEntity company = state.selectedCompany; final CompanyEntity company = state.selectedCompany;
@ -284,15 +285,15 @@ void handleTaskAction(
switch (action) { switch (action) {
case EntityAction.edit: case EntityAction.edit:
store.dispatch(EditTask(context: context, task: task)); store.dispatch(EditTask(context: context, task: tasks[0]));
break; break;
case EntityAction.start: case EntityAction.start:
case EntityAction.stop: case EntityAction.stop:
case EntityAction.resume: case EntityAction.resume:
final Completer<TaskEntity> completer = new Completer<TaskEntity>(); final Completer<TaskEntity> completer = new Completer<TaskEntity>();
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
store store.dispatch(
.dispatch(SaveTaskRequest(completer: completer, task: task.toggle())); SaveTaskRequest(completer: completer, task: tasks[0].toggle()));
completer.future.then((savedTask) { completer.future.then((savedTask) {
Scaffold.of(context).showSnackBar(SnackBar( Scaffold.of(context).showSnackBar(SnackBar(
content: SnackBarRow( content: SnackBarRow(
@ -312,31 +313,32 @@ void handleTaskAction(
break; break;
case EntityAction.newInvoice: case EntityAction.newInvoice:
final item = convertTaskToInvoiceItem(task: task, context: context); final item = convertTaskToInvoiceItem(task: tasks[0], context: context);
store.dispatch(EditInvoice( store.dispatch(EditInvoice(
invoice: InvoiceEntity(company: company).rebuild((b) => b invoice: InvoiceEntity(company: company).rebuild((b) => b
..hasTasks = true ..hasTasks = true
..clientId = task.clientId ..clientId = tasks[0].clientId
..invoiceItems.add(item)), ..invoiceItems.add(item)),
context: context)); context: context));
break; break;
case EntityAction.viewInvoice: case EntityAction.viewInvoice:
store.dispatch(ViewInvoice(invoiceId: task.invoiceId, context: context)); store.dispatch(
ViewInvoice(invoiceId: tasks[0].invoiceId, context: context));
break; break;
case EntityAction.clone: case EntityAction.clone:
store.dispatch(EditTask(context: context, task: task.clone)); store.dispatch(EditTask(context: context, task: tasks[0].clone));
break; break;
case EntityAction.restore: case EntityAction.restore:
store.dispatch(RestoreTaskRequest( store.dispatch(RestoreTaskRequest(
snackBarCompleter(context, localization.restoredTask), task.id)); snackBarCompleter(context, localization.restoredTask), tasks[0].id));
break; break;
case EntityAction.archive: case EntityAction.archive:
store.dispatch(ArchiveTaskRequest( store.dispatch(ArchiveTaskRequest(
snackBarCompleter(context, localization.archivedTask), task.id)); snackBarCompleter(context, localization.archivedTask), tasks[0].id));
break; break;
case EntityAction.delete: case EntityAction.delete:
store.dispatch(DeleteTaskRequest( store.dispatch(DeleteTaskRequest(
snackBarCompleter(context, localization.deletedTask), task.id)); snackBarCompleter(context, localization.deletedTask), tasks[0].id));
break; break;
} }
} }

View File

@ -1,13 +1,14 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:built_collection/built_collection.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/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.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/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/expense/expense_actions.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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class ViewVendorList implements PersistUI { class ViewVendorList implements PersistUI {
ViewVendorList({@required this.context, this.force = false}); ViewVendorList({@required this.context, this.force = false});
@ -266,7 +267,7 @@ class FilterVendorsByEntity implements PersistUI {
} }
void handleVendorAction( void handleVendorAction(
BuildContext context, VendorEntity vendor, EntityAction action) { BuildContext context, List<VendorEntity> vendors, EntityAction action) {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final state = store.state; final state = store.state;
final CompanyEntity company = state.selectedCompany; final CompanyEntity company = state.selectedCompany;
@ -274,24 +275,27 @@ void handleVendorAction(
switch (action) { switch (action) {
case EntityAction.edit: case EntityAction.edit:
store.dispatch(EditVendor(context: context, vendor: vendor)); store.dispatch(EditVendor(context: context, vendor: vendors[0]));
break; break;
case EntityAction.newExpense: case EntityAction.newExpense:
store.dispatch(EditExpense( store.dispatch(EditExpense(
expense: ExpenseEntity(company: company, vendor: vendor), expense: ExpenseEntity(company: company, vendor: vendors[0]),
context: context)); context: context));
break; break;
case EntityAction.restore: case EntityAction.restore:
store.dispatch(RestoreVendorRequest( store.dispatch(RestoreVendorRequest(
snackBarCompleter(context, localization.restoredVendor), vendor.id)); snackBarCompleter(context, localization.restoredVendor),
vendors[0].id));
break; break;
case EntityAction.archive: case EntityAction.archive:
store.dispatch(ArchiveVendorRequest( store.dispatch(ArchiveVendorRequest(
snackBarCompleter(context, localization.archivedVendor), vendor.id)); snackBarCompleter(context, localization.archivedVendor),
vendors[0].id));
break; break;
case EntityAction.delete: case EntityAction.delete:
store.dispatch(DeleteVendorRequest( store.dispatch(DeleteVendorRequest(
snackBarCompleter(context, localization.deletedVendor), vendor.id)); snackBarCompleter(context, localization.deletedVendor),
vendors[0].id));
break; break;
} }
} }

View File

@ -8,7 +8,8 @@ Future<void> showEntityActionsDialog({
@required BuildContext context, @required BuildContext context,
@required List<BaseEntity> entities, @required List<BaseEntity> entities,
@required UserCompanyEntity userCompany, @required UserCompanyEntity userCompany,
@required Function(BuildContext, BaseEntity, EntityAction) onEntityAction, @required
Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction,
ClientEntity client, ClientEntity client,
}) async { }) async {
if (entities == null) { if (entities == null) {
@ -49,7 +50,7 @@ class EntityActionListTile extends StatelessWidget {
final List<BaseEntity> entities; final List<BaseEntity> entities;
final EntityAction entityAction; final EntityAction entityAction;
final BuildContext mainContext; final BuildContext mainContext;
final Function(BuildContext, BaseEntity, EntityAction) onEntityAction; final Function(BuildContext, List<BaseEntity>, EntityAction) onEntityAction;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -60,10 +61,7 @@ class EntityActionListTile extends StatelessWidget {
title: Text(localization.lookup(entityAction.toString())), title: Text(localization.lookup(entityAction.toString())),
onTap: () { onTap: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
for (int i = 0; i < entities.length; i++) { onEntityAction(context, entities, entityAction);
final BaseEntity entity = entities[i];
onEntityAction(context, entity, entityAction);
}
}, },
); );
} }

View File

@ -82,7 +82,7 @@ class ClientList extends StatelessWidget {
store.state.uiState.longPressSelectionIsDefault ?? true; store.state.uiState.longPressSelectionIsDefault ?? true;
if (longPressIsSelection) { if (longPressIsSelection) {
viewModel.onEntityAction( viewModel.onEntityAction(
context, client, EntityAction.toggleMultiselect); context, [client], EntityAction.toggleMultiselect);
} else { } else {
showDialog(); showDialog();
} }

View File

@ -5,11 +5,11 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.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_actions.dart';
import 'package:invoiceninja_flutter/redux/client/client_selectors.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/ui/client/client_list.dart';
import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
@ -55,7 +55,7 @@ class ClientListVM {
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, ClientEntity) onClientTap; final Function(BuildContext, ClientEntity) onClientTap;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, ClientEntity, EntityAction) onEntityAction; final Function(BuildContext, List<ClientEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed; final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed;
@ -84,9 +84,9 @@ class ClientListVM {
store.dispatch(ViewClient(clientId: client.id, context: context)); store.dispatch(ViewClient(clientId: client.id, context: context));
}, },
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> client,
(BuildContext context, BaseEntity client, EntityAction action) => EntityAction action) =>
handleClientAction(context, client, action), handleClientAction(context, client, action),
onClearEntityFilterPressed: () => store.dispatch(FilterClientsByEntity()), onClearEntityFilterPressed: () => store.dispatch(FilterClientsByEntity()),
onViewEntityFilterPressed: (BuildContext context) => store.dispatch( onViewEntityFilterPressed: (BuildContext context) => store.dispatch(
ViewGroup( ViewGroup(

View File

@ -35,7 +35,7 @@ class ClientScreenVM {
final bool isInMultiselect; final bool isInMultiselect;
final UserCompanyEntity userCompany; final UserCompanyEntity userCompany;
final Function(BuildContext, ClientEntity, EntityAction) onEntityAction; final Function(BuildContext, List<ClientEntity>, EntityAction) onEntityAction;
static ClientScreenVM fromStore(Store<AppState> store) { static ClientScreenVM fromStore(Store<AppState> store) {
final state = store.state; final state = store.state;
@ -43,9 +43,9 @@ class ClientScreenVM {
return ClientScreenVM( return ClientScreenVM(
userCompany: state.userCompany, userCompany: state.userCompany,
isInMultiselect: state.clientListState.isInMultiselect(), isInMultiselect: state.clientListState.isInMultiselect(),
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> clients,
(BuildContext context, BaseEntity client, EntityAction action) => EntityAction action) =>
handleClientAction(context, client, action), handleClientAction(context, clients, action),
); );
} }
} }

View File

@ -1,23 +1,24 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.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/invoice/invoice_actions.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_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/project/project_actions.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_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/task/task_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_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/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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.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 { class ClientViewScreen extends StatelessWidget {
const ClientViewScreen({Key key}) : super(key: key); const ClientViewScreen({Key key}) : super(key: key);
@ -176,7 +177,7 @@ class ClientViewVM {
} }
}, },
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handleClientAction(context, client, action), handleClientAction(context, [client], action),
); );
} }

View File

@ -63,7 +63,7 @@ class DocumentList extends StatelessWidget {
showDialog(); showDialog();
} else { } else {
viewModel.onEntityAction( viewModel.onEntityAction(
context, document, action); context, [document], action);
} }
}, },
onLongPress: () => showDialog(), onLongPress: () => showDialog(),

View File

@ -1,19 +1,20 @@
import 'dart:async'; 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/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/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/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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/document/document_selectors.dart'; import 'package:redux/redux.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';
class DocumentListBuilder extends StatelessWidget { class DocumentListBuilder extends StatelessWidget {
const DocumentListBuilder({Key key}) : super(key: key); const DocumentListBuilder({Key key}) : super(key: key);
@ -78,9 +79,9 @@ class DocumentListVM {
onDocumentTap: (context, document) { onDocumentTap: (context, document) {
store.dispatch(ViewDocument(documentId: document.id, context: context)); store.dispatch(ViewDocument(documentId: document.id, context: context));
}, },
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> documents,
(BuildContext context, BaseEntity document, EntityAction action) => EntityAction action) =>
handleDocumentAction(context, document, action), handleDocumentAction(context, documents[0], action),
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
); );
} }
@ -94,7 +95,8 @@ class DocumentListVM {
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, DocumentEntity) onDocumentTap; final Function(BuildContext, DocumentEntity) onDocumentTap;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, DocumentEntity, EntityAction) onEntityAction; final Function(BuildContext, List<DocumentEntity>, EntityAction)
onEntityAction;
final Function onClearEntityFilterPressed; final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed;
} }

View File

@ -84,7 +84,7 @@ class ExpenseList extends StatelessWidget {
showDialog(); showDialog();
} else { } else {
viewModel.onEntityAction( viewModel.onEntityAction(
context, expense, action); context, [expense], action);
} }
}, },
onLongPress: () => showDialog(), onLongPress: () => showDialog(),

View File

@ -1,20 +1,21 @@
import 'dart:async'; import 'dart:async';
import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
import 'package:redux/redux.dart'; import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/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/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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/expense/expense_selectors.dart'; import 'package:redux/redux.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';
class ExpenseListBuilder extends StatelessWidget { class ExpenseListBuilder extends StatelessWidget {
const ExpenseListBuilder({Key key}) : super(key: key); const ExpenseListBuilder({Key key}) : super(key: key);
@ -95,9 +96,9 @@ class ExpenseListVM {
onExpenseTap: (context, expense) { onExpenseTap: (context, expense) {
store.dispatch(ViewExpense(expenseId: expense.id, context: context)); store.dispatch(ViewExpense(expenseId: expense.id, context: context));
}, },
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> expenses,
(BuildContext context, BaseEntity expense, EntityAction action) => EntityAction action) =>
handleExpenseAction(context, expense, action), handleExpenseAction(context, expenses[0], action),
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
); );
} }
@ -112,7 +113,8 @@ class ExpenseListVM {
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, ExpenseEntity) onExpenseTap; final Function(BuildContext, ExpenseEntity) onExpenseTap;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, ExpenseEntity, EntityAction) onEntityAction; final Function(BuildContext, List<ExpenseEntity>, EntityAction)
onEntityAction;
final Function onClearEntityFilterPressed; final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed;
} }

View File

@ -106,9 +106,9 @@ class ExpenseViewVM {
userCompany: userCompany, userCompany: userCompany,
context: context, context: context,
entities: [vendor], entities: [vendor],
onEntityAction: (BuildContext context, BaseEntity vendor, onEntityAction: (BuildContext context,
EntityAction action) => List<BaseEntity> vendors, EntityAction action) =>
handleVendorAction(context, vendor, action)); handleVendorAction(context, vendors, action));
} else { } else {
store.dispatch( store.dispatch(
ViewVendor(vendorId: vendor.id, context: context)); ViewVendor(vendorId: vendor.id, context: context));
@ -120,9 +120,9 @@ class ExpenseViewVM {
userCompany: userCompany, userCompany: userCompany,
context: context, context: context,
entities: [client], entities: [client],
onEntityAction: (BuildContext context, BaseEntity client, onEntityAction: (BuildContext context,
EntityAction action) => List<BaseEntity> clients, EntityAction action) =>
handleClientAction(context, client, action)); handleClientAction(context, clients, action));
} else { } else {
store.dispatch( store.dispatch(
ViewClient(clientId: client.id, context: context)); ViewClient(clientId: client.id, context: context));
@ -135,9 +135,9 @@ class ExpenseViewVM {
context: context, context: context,
entities: [invoice], entities: [invoice],
client: client, client: client,
onEntityAction: (BuildContext context, BaseEntity invoice, onEntityAction: (BuildContext context,
EntityAction action) => List<BaseEntity> invoices, EntityAction action) =>
handleInvoiceAction(context, invoice, action)); handleInvoiceAction(context, invoices, action));
} else { } else {
store.dispatch( store.dispatch(
ViewInvoice(invoiceId: invoice.id, context: context)); ViewInvoice(invoiceId: invoice.id, context: context));

View File

@ -101,7 +101,7 @@ class InvoiceList extends StatelessWidget {
showDialog(); showDialog();
} else { } else {
viewModel.onEntityAction( viewModel.onEntityAction(
context, invoice, action); context, [invoice], action);
} }
}, },
onLongPress: () => showDialog(), onLongPress: () => showDialog(),

View File

@ -1,19 +1,20 @@
import 'dart:async'; import 'dart:async';
import 'package:built_collection/built_collection.dart'; 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/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.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 { class InvoiceListBuilder extends StatelessWidget {
const InvoiceListBuilder({Key key}) : super(key: key); const InvoiceListBuilder({Key key}) : super(key: key);
@ -64,7 +65,8 @@ class EntityListVM {
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function onClearEntityFilterPressed; final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed;
final Function(BuildContext, InvoiceEntity, EntityAction) onEntityAction; final Function(BuildContext, List<InvoiceEntity>, EntityAction)
onEntityAction;
} }
class InvoiceListVM extends EntityListVM { class InvoiceListVM extends EntityListVM {
@ -82,7 +84,7 @@ class InvoiceListVM extends EntityListVM {
Function(BuildContext) onRefreshed, Function(BuildContext) onRefreshed,
Function onClearEntityFilterPressed, Function onClearEntityFilterPressed,
Function(BuildContext) onViewEntityFilterPressed, Function(BuildContext) onViewEntityFilterPressed,
Function(BuildContext, InvoiceEntity, EntityAction) onEntityAction, Function(BuildContext, List<InvoiceEntity>, EntityAction) onEntityAction,
}) : super( }) : super(
state: state, state: state,
user: user, user: user,
@ -137,9 +139,9 @@ class InvoiceListVM extends EntityListVM {
ViewClient( ViewClient(
clientId: state.invoiceListState.filterEntityId, clientId: state.invoiceListState.filterEntityId,
context: context)), context: context)),
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> invoices,
(BuildContext context, BaseEntity invoice, EntityAction action) => EntityAction action) =>
handleInvoiceAction(context, invoice, action), handleInvoiceAction(context, invoices, action),
); );
} }
} }

View File

@ -1,23 +1,24 @@
import 'dart:async'; 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/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.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_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/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/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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; import 'package:redux/redux.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';
class InvoiceViewScreen extends StatelessWidget { class InvoiceViewScreen extends StatelessWidget {
const InvoiceViewScreen({Key key}) : super(key: key); const InvoiceViewScreen({Key key}) : super(key: key);
@ -159,9 +160,9 @@ class InvoiceViewVM extends EntityViewVM {
userCompany: state.userCompany, userCompany: state.userCompany,
context: context, context: context,
entities: [client], entities: [client],
onEntityAction: (BuildContext context, BaseEntity client, onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) => EntityAction action) =>
handleClientAction(context, client, action)); handleClientAction(context, clients, action));
} else { } else {
store.dispatch(ViewClient(clientId: client.id, context: context)); store.dispatch(ViewClient(clientId: client.id, context: context));
} }
@ -174,9 +175,9 @@ class InvoiceViewVM extends EntityViewVM {
context: context, context: context,
client: client, client: client,
entities: [payment], entities: [payment],
onEntityAction: (BuildContext context, BaseEntity payment, onEntityAction: (BuildContext context, List<BaseEntity> payments,
EntityAction action) => EntityAction action) =>
handlePaymentAction(context, payment, action)); handlePaymentAction(context, payments, action));
} else { } else {
store.dispatch(ViewPayment(paymentId: payment.id, context: context)); store.dispatch(ViewPayment(paymentId: payment.id, context: context));
} }
@ -187,7 +188,7 @@ class InvoiceViewVM extends EntityViewVM {
store.dispatch(ViewPaymentList(context: context)); store.dispatch(ViewPaymentList(context: context));
}, },
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handleInvoiceAction(context, invoice, action), handleInvoiceAction(context, [invoice], action),
onUploadDocument: (BuildContext context, String path) { onUploadDocument: (BuildContext context, String path) {
final Completer<DocumentEntity> completer = Completer<DocumentEntity>(); final Completer<DocumentEntity> completer = Completer<DocumentEntity>();
final document = DocumentEntity().rebuild((b) => b final document = DocumentEntity().rebuild((b) => b

View File

@ -112,7 +112,7 @@ class PaymentList extends StatelessWidget {
showDialog(); showDialog();
} else { } else {
viewModel.onEntityAction( viewModel.onEntityAction(
context, payment, action); context, [payment], action);
} }
}, },
onLongPress: () => showDialog(), onLongPress: () => showDialog(),

View File

@ -1,20 +1,21 @@
import 'dart:async'; import 'dart:async';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:redux/redux.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_selectors.dart'; import 'package:redux/redux.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';
class PaymentListBuilder extends StatelessWidget { class PaymentListBuilder extends StatelessWidget {
const PaymentListBuilder({Key key}) : super(key: key); const PaymentListBuilder({Key key}) : super(key: key);
@ -79,9 +80,9 @@ class PaymentListVM {
onPaymentTap: (context, payment) { onPaymentTap: (context, payment) {
store.dispatch(ViewPayment(paymentId: payment.id, context: context)); store.dispatch(ViewPayment(paymentId: payment.id, context: context));
}, },
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> payments,
(BuildContext context, BaseEntity payment, EntityAction action) => EntityAction action) =>
handlePaymentAction(context, payment, action), handlePaymentAction(context, payments, action),
onClearEntityFilterPressed: () => onClearEntityFilterPressed: () =>
store.dispatch(FilterPaymentsByEntity()), store.dispatch(FilterPaymentsByEntity()),
onViewClientFilterPressed: (BuildContext context) { onViewClientFilterPressed: (BuildContext context) {
@ -114,5 +115,6 @@ class PaymentListVM {
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function onClearEntityFilterPressed; final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewClientFilterPressed; final Function(BuildContext) onViewClientFilterPressed;
final Function(BuildContext, PaymentEntity, EntityAction) onEntityAction; final Function(BuildContext, List<PaymentEntity>, EntityAction)
onEntityAction;
} }

View File

@ -70,9 +70,9 @@ class PaymentViewVM {
userCompany: state.userCompany, userCompany: state.userCompany,
context: context, context: context,
entities: [client], entities: [client],
onEntityAction: (BuildContext context, BaseEntity client, onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) => EntityAction action) =>
handleClientAction(context, client, action)); handleClientAction(context, clients, action));
} else { } else {
store.dispatch(ViewClient(clientId: client.id, context: context)); store.dispatch(ViewClient(clientId: client.id, context: context));
} }
@ -84,7 +84,7 @@ class PaymentViewVM {
context: context, context: context,
entities: [invoice], entities: [invoice],
client: client, client: client,
onEntityAction: (BuildContext context, BaseEntity invoice, onEntityAction: (BuildContext context, List<BaseEntity> invoice,
EntityAction action) => EntityAction action) =>
handleInvoiceAction(context, invoice, action)); handleInvoiceAction(context, invoice, action));
} else { } else {
@ -92,7 +92,7 @@ class PaymentViewVM {
} }
}, },
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handlePaymentAction(context, payment, action), handlePaymentAction(context, [payment], action),
); );
} }

View File

@ -1,17 +1,18 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.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/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.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/product_screen.dart';
import 'package:invoiceninja_flutter/ui/product/view/product_view_vm.dart'; import 'package:invoiceninja_flutter/ui/product/view/product_view_vm.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:redux/redux.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 { class ProductEditScreen extends StatelessWidget {
const ProductEditScreen({Key key}) : super(key: key); const ProductEditScreen({Key key}) : super(key: key);
@ -102,10 +103,10 @@ class ProductEditVM {
if (action == EntityAction.clone) { if (action == EntityAction.clone) {
Navigator.pop(context); Navigator.pop(context);
WidgetsBinding.instance.addPostFrameCallback((duration) { WidgetsBinding.instance.addPostFrameCallback((duration) {
handleProductAction(context, product, action); handleProductAction(context, [product], action);
}); });
} else { } else {
handleProductAction(context, product, action); handleProductAction(context, [product], action);
} }
}, },
); );

View File

@ -52,7 +52,7 @@ class ProductList extends StatelessWidget {
if (action == EntityAction.more) { if (action == EntityAction.more) {
showDialog(); showDialog();
} else { } else {
viewModel.onEntityAction(context, product, action); viewModel.onEntityAction(context, [product], action);
} }
}, },
onTap: () => viewModel.onProductTap(context, product), onTap: () => viewModel.onProductTap(context, product),

View File

@ -1,17 +1,18 @@
import 'dart:async'; import 'dart:async';
import 'package:built_collection/built_collection.dart'; 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/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.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 { class ProductListBuilder extends StatelessWidget {
const ProductListBuilder({Key key}) : super(key: key); const ProductListBuilder({Key key}) : super(key: key);
@ -66,9 +67,9 @@ class ProductListVM {
onProductTap: (context, product) { onProductTap: (context, product) {
store.dispatch(ViewProduct(productId: product.id, context: context)); store.dispatch(ViewProduct(productId: product.id, context: context));
}, },
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> products,
(BuildContext context, BaseEntity product, EntityAction action) => EntityAction action) =>
handleProductAction(context, product, action), handleProductAction(context, products, action),
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
); );
} }
@ -81,5 +82,6 @@ class ProductListVM {
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, ProductEntity) onProductTap; final Function(BuildContext, ProductEntity) onProductTap;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, ProductEntity, EntityAction) onEntityAction; final Function(BuildContext, List<ProductEntity>, EntityAction)
onEntityAction;
} }

View File

@ -1,16 +1,17 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.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/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/product_screen.dart';
import 'package:invoiceninja_flutter/ui/product/view/product_view.dart'; import 'package:invoiceninja_flutter/ui/product/view/product_view.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.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 { class ProductViewScreen extends StatelessWidget {
const ProductViewScreen({Key key}) : super(key: key); const ProductViewScreen({Key key}) : super(key: key);
@ -93,7 +94,7 @@ class ProductViewVM {
} }
}, },
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handleProductAction(context, product, action), handleProductAction(context, [product], action),
); );
} }

View File

@ -95,7 +95,7 @@ class ProjectList extends StatelessWidget {
showDialog(); showDialog();
} else { } else {
viewModel.onEntityAction( viewModel.onEntityAction(
context, project, action); context, [project], action);
} }
}, },
onLongPress: () => showDialog(), onLongPress: () => showDialog(),

View File

@ -1,19 +1,20 @@
import 'dart:async'; import 'dart:async';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart'; import 'package:built_collection/built_collection.dart';
import 'package:redux/redux.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/project/project_selectors.dart'; import 'package:redux/redux.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';
class ProjectListBuilder extends StatelessWidget { class ProjectListBuilder extends StatelessWidget {
const ProjectListBuilder({Key key}) : super(key: key); const ProjectListBuilder({Key key}) : super(key: key);
@ -83,9 +84,9 @@ class ProjectListVM {
onProjectTap: (context, project) { onProjectTap: (context, project) {
store.dispatch(ViewProject(projectId: project.id, context: context)); store.dispatch(ViewProject(projectId: project.id, context: context));
}, },
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> projects,
(BuildContext context, BaseEntity project, EntityAction action) => EntityAction action) =>
handleProjectAction(context, project, action), handleProjectAction(context, projects, action),
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
); );
} }
@ -100,7 +101,8 @@ class ProjectListVM {
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, ProjectEntity) onProjectTap; final Function(BuildContext, ProjectEntity) onProjectTap;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, ProjectEntity, EntityAction) onEntityAction; final Function(BuildContext, List<ProjectEntity>, EntityAction)
onEntityAction;
final Function onClearEntityFilterPressed; final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed;
} }

View File

@ -84,9 +84,9 @@ class ProjectViewVM {
userCompany: state.userCompany, userCompany: state.userCompany,
context: context, context: context,
entities: [client], entities: [client],
onEntityAction: (BuildContext context, BaseEntity client, onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) => EntityAction action) =>
handleClientAction(context, client, action)); handleClientAction(context, clients, action));
} else { } else {
store.dispatch(ViewClient(clientId: client.id, context: context)); store.dispatch(ViewClient(clientId: client.id, context: context));
} }
@ -119,7 +119,7 @@ class ProjectViewVM {
} }
}, },
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handleProjectAction(context, project, action), handleProjectAction(context, [project], action),
); );
} }

View File

@ -49,7 +49,7 @@ class QuoteListVM extends EntityListVM {
Function(BuildContext) onRefreshed, Function(BuildContext) onRefreshed,
Function onClearEntityFilterPressed, Function onClearEntityFilterPressed,
Function(BuildContext) onViewEntityFilterPressed, Function(BuildContext) onViewEntityFilterPressed,
Function(BuildContext, InvoiceEntity, EntityAction) onEntityAction, Function(BuildContext, List<InvoiceEntity>, EntityAction) onEntityAction,
}) : super( }) : super(
state: state, state: state,
user: user, user: user,
@ -100,8 +100,8 @@ class QuoteListVM extends EntityListVM {
ViewClient( ViewClient(
clientId: state.quoteListState.filterEntityId, context: context)), clientId: state.quoteListState.filterEntityId, context: context)),
onEntityAction: onEntityAction:
(BuildContext context, BaseEntity quote, EntityAction action) => (BuildContext context, List<BaseEntity> quotes, EntityAction action) =>
handleQuoteAction(context, quote, action), handleQuoteAction(context, quotes, action),
); );
} }
} }

View File

@ -125,15 +125,15 @@ class QuoteViewVM extends EntityViewVM {
userCompany: state.userCompany, userCompany: state.userCompany,
context: context, context: context,
entities: [client], entities: [client],
onEntityAction: (BuildContext context, BaseEntity client, onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) => EntityAction action) =>
handleClientAction(context, client, action)); handleClientAction(context, clients, action));
} else { } else {
store.dispatch(ViewClient(clientId: client.id, context: context)); store.dispatch(ViewClient(clientId: client.id, context: context));
} }
}, },
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handleQuoteAction(context, quote, action), handleQuoteAction(context, [quote], action),
onUploadDocument: (BuildContext context, String path) { onUploadDocument: (BuildContext context, String path) {
final Completer<DocumentEntity> completer = Completer<DocumentEntity>(); final Completer<DocumentEntity> completer = Completer<DocumentEntity>();
final document = DocumentEntity().rebuild((b) => b final document = DocumentEntity().rebuild((b) => b

View File

@ -110,7 +110,7 @@ class TaskList extends StatelessWidget {
showDialog(); showDialog();
} else { } else {
viewModel.onEntityAction( viewModel.onEntityAction(
context, task, action); context, [task], action);
} }
}, },
onLongPress: () => showDialog(), onLongPress: () => showDialog(),

View File

@ -1,20 +1,21 @@
import 'dart:async'; import 'dart:async';
import 'package:invoiceninja_flutter/redux/project/project_actions.dart';
import 'package:redux/redux.dart'; import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/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/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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/task/task_selectors.dart'; import 'package:redux/redux.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';
class TaskListBuilder extends StatelessWidget { class TaskListBuilder extends StatelessWidget {
const TaskListBuilder({Key key}) : super(key: key); const TaskListBuilder({Key key}) : super(key: key);
@ -97,8 +98,8 @@ class TaskListVM {
store.dispatch(ViewTask(taskId: task.id, context: context)); store.dispatch(ViewTask(taskId: task.id, context: context));
}, },
onEntityAction: onEntityAction:
(BuildContext context, BaseEntity task, EntityAction action) => (BuildContext context, List<BaseEntity> tasks, EntityAction action) =>
handleTaskAction(context, task, action), handleTaskAction(context, tasks, action),
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
); );
} }
@ -114,7 +115,7 @@ class TaskListVM {
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, TaskEntity) onTaskTap; final Function(BuildContext, TaskEntity) onTaskTap;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, TaskEntity, EntityAction) onEntityAction; final Function(BuildContext, List<TaskEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed; final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed;
} }

View File

@ -113,9 +113,9 @@ class TaskViewVM {
userCompany: state.userCompany, userCompany: state.userCompany,
context: context, context: context,
entities: [client], entities: [client],
onEntityAction: (BuildContext context, BaseEntity client, onEntityAction: (BuildContext context, List<BaseEntity> clients,
EntityAction action) => EntityAction action) =>
handleClientAction(context, client, action)); handleClientAction(context, clients, action));
} else { } else {
store.dispatch(ViewClient(clientId: client.id, context: context)); store.dispatch(ViewClient(clientId: client.id, context: context));
} }
@ -127,9 +127,9 @@ class TaskViewVM {
context: context, context: context,
entities: [project], entities: [project],
client: client, client: client,
onEntityAction: (BuildContext context, BaseEntity project, onEntityAction: (BuildContext context, List<BaseEntity> projects,
EntityAction action) => EntityAction action) =>
handleProjectAction(context, project, action)); handleProjectAction(context, projects, action));
} else { } else {
store.dispatch(ViewProject(projectId: project.id, context: context)); store.dispatch(ViewProject(projectId: project.id, context: context));
} }
@ -141,9 +141,9 @@ class TaskViewVM {
context: context, context: context,
entities: [invoice], entities: [invoice],
client: client, client: client,
onEntityAction: (BuildContext context, BaseEntity invoice, onEntityAction: (BuildContext context, List<BaseEntity> invoices,
EntityAction action) => EntityAction action) =>
handleInvoiceAction(context, invoice, action)); handleInvoiceAction(context, invoices, action));
} else { } else {
store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context)); store.dispatch(ViewInvoice(invoiceId: invoice.id, context: context));
} }
@ -170,7 +170,7 @@ class TaskViewVM {
} }
}, },
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handleTaskAction(context, task, action), handleTaskAction(context, [task], action),
); );
} }

View File

@ -54,7 +54,7 @@ class VendorList extends StatelessWidget {
showDialog(); showDialog();
} else { } else {
viewModel.onEntityAction( viewModel.onEntityAction(
context, vendor, action); context, [vendor], action);
} }
}, },
onLongPress: () => showDialog(), onLongPress: () => showDialog(),

View File

@ -1,19 +1,20 @@
import 'dart:async'; 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/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.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/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.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/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_selectors.dart'; import 'package:redux/redux.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';
class VendorListBuilder extends StatelessWidget { class VendorListBuilder extends StatelessWidget {
const VendorListBuilder({Key key}) : super(key: key); const VendorListBuilder({Key key}) : super(key: key);
@ -77,9 +78,9 @@ class VendorListVM {
onVendorTap: (context, vendor) { onVendorTap: (context, vendor) {
store.dispatch(ViewVendor(vendorId: vendor.id, context: context)); store.dispatch(ViewVendor(vendorId: vendor.id, context: context));
}, },
onEntityAction: onEntityAction: (BuildContext context, List<BaseEntity> vendors,
(BuildContext context, BaseEntity vendor, EntityAction action) => EntityAction action) =>
handleVendorAction(context, vendor, action), handleVendorAction(context, vendors, action),
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
); );
} }
@ -93,7 +94,7 @@ class VendorListVM {
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, VendorEntity) onVendorTap; final Function(BuildContext, VendorEntity) onVendorTap;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, VendorEntity, EntityAction) onEntityAction; final Function(BuildContext, List<VendorEntity>, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed; final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed; final Function(BuildContext) onViewEntityFilterPressed;
} }

View File

@ -1,19 +1,20 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.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/expense/expense_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_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/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/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:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.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 { class VendorViewScreen extends StatelessWidget {
const VendorViewScreen({Key key}) : super(key: key); const VendorViewScreen({Key key}) : super(key: key);
@ -108,7 +109,7 @@ class VendorViewVM {
expense: ExpenseEntity(company: company, vendor: vendor), expense: ExpenseEntity(company: company, vendor: vendor),
context: context)), context: context)),
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handleVendorAction(context, vendor, action), handleVendorAction(context, [vendor], action),
); );
} }