From 3926008ebb066927f0e984dcc8d1df059a9a1d0b Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Fri, 6 Mar 2020 10:27:53 +0200 Subject: [PATCH] Bulk actions --- lib/data/repositories/product_repository.dart | 8 ++--- lib/data/repositories/project_repository.dart | 8 ++--- lib/data/repositories/quote_repository.dart | 8 ++--- lib/redux/app/app_state.dart | 2 +- lib/redux/invoice/invoice_reducer.dart | 8 ----- lib/redux/quote/quote_actions.dart | 31 +++++++++---------- lib/redux/quote/quote_middleware.dart | 28 ++++++++--------- lib/redux/quote/quote_reducer.dart | 17 +++++++--- stubs/data/repositories/stub_repository | 8 ++--- 9 files changed, 50 insertions(+), 68 deletions(-) diff --git a/lib/data/repositories/product_repository.dart b/lib/data/repositories/product_repository.dart index c58913834..03a7fff9d 100644 --- a/lib/data/repositories/product_repository.dart +++ b/lib/data/repositories/product_repository.dart @@ -46,8 +46,7 @@ class ProductRepository { return productResponse.data.toList(); } - Future saveData(Credentials credentials, ProductEntity product, - [EntityAction action]) async { + Future saveData(Credentials credentials, ProductEntity product) async { final data = serializers.serializeWith(ProductEntity.serializer, product); dynamic response; @@ -56,10 +55,7 @@ class ProductRepository { credentials.url + '/products', credentials.token, data: json.encode(data)); } else { - var url = credentials.url + '/products/${product.id}?'; - if (action != null) { - url += '&action=' + action.toString(); - } + final url = credentials.url + '/products/${product.id}'; response = await webClient.put(url, credentials.token, data: json.encode(data)); } diff --git a/lib/data/repositories/project_repository.dart b/lib/data/repositories/project_repository.dart index aaabb89b7..8e5a0986a 100644 --- a/lib/data/repositories/project_repository.dart +++ b/lib/data/repositories/project_repository.dart @@ -57,8 +57,7 @@ class ProjectRepository { return projectResponse.data.toList(); } - Future saveData(Credentials credentials, ProjectEntity project, - [EntityAction action]) async { + Future saveData(Credentials credentials, ProjectEntity project) async { final data = serializers.serializeWith(ProjectEntity.serializer, project); dynamic response; @@ -67,10 +66,7 @@ class ProjectRepository { credentials.url + '/projects', credentials.token, data: json.encode(data)); } else { - var url = credentials.url + '/projects/${project.id}?'; - if (action != null) { - url += '&action=' + action.toString(); - } + final url = credentials.url + '/projects/${project.id}'; response = await webClient.put(url, credentials.token, data: json.encode(data)); } diff --git a/lib/data/repositories/quote_repository.dart b/lib/data/repositories/quote_repository.dart index 7ab795788..9721c46b2 100644 --- a/lib/data/repositories/quote_repository.dart +++ b/lib/data/repositories/quote_repository.dart @@ -57,8 +57,7 @@ class QuoteRepository { return invoiceResponse.data.toList(); } - Future saveData(Credentials credentials, InvoiceEntity quote, - [EntityAction action]) async { + Future saveData(Credentials credentials, InvoiceEntity quote) async { final data = serializers.serializeWith(InvoiceEntity.serializer, quote); dynamic response; @@ -67,10 +66,7 @@ class QuoteRepository { credentials.url + '/quotes?', credentials.token, data: json.encode(data)); } else { - var url = '${credentials.url}/quotes/${quote.id}?'; - if (action != null) { - url += '&action=' + action.toString(); - } + final url = '${credentials.url}/quotes/${quote.id}'; response = await webClient.put(url, credentials.token, data: json.encode(data)); } diff --git a/lib/redux/app/app_state.dart b/lib/redux/app/app_state.dart index 6419b15d2..ed2341a01 100644 --- a/lib/redux/app/app_state.dart +++ b/lib/redux/app/app_state.dart @@ -503,7 +503,7 @@ abstract class AppState implements Built { //return 'Currency Map: ${staticState.currencyMap}'; //return 'History: $historyList'; //return 'Use inclusive: ${invoiceUIState.editing.usesInclusiveTaxes}'; - return 'Invitations: ${invoiceUIState.editing.invitations}'; + //return 'Invitations: ${invoiceUIState.editing.invitations}'; //return 'Token: ${userCompanyStates.map((state) => state.token.token).where((name) => name.isNotEmpty).toList().join(', ')}'; //return 'Settings: ${company.settings.companyLogo}'; //return 'Designs: ${company.designs}'; diff --git a/lib/redux/invoice/invoice_reducer.dart b/lib/redux/invoice/invoice_reducer.dart index c26298b21..6f33f270a 100644 --- a/lib/redux/invoice/invoice_reducer.dart +++ b/lib/redux/invoice/invoice_reducer.dart @@ -268,7 +268,6 @@ final invoicesReducer = combineReducers([ TypedReducer(_restoreInvoiceRequest), TypedReducer(_restoreInvoiceSuccess), TypedReducer(_restoreInvoiceFailure), - TypedReducer(_convertQuoteSuccess), ]); InvoiceState _markInvoicesSentSuccess( @@ -397,13 +396,6 @@ InvoiceState _addInvoice(InvoiceState invoiceState, AddInvoiceSuccess action) { ..list.add(action.invoice.id)); } -InvoiceState _convertQuoteSuccess( - InvoiceState invoiceState, ConvertQuoteSuccess action) { - return invoiceState.rebuild((b) => b - ..map[action.invoice.id] = action.invoice - ..list.add(action.invoice.id)); -} - InvoiceState _updateInvoice(InvoiceState invoiceState, dynamic action) { return invoiceState .rebuild((b) => b..map[action.invoice.id] = action.invoice); diff --git a/lib/redux/quote/quote_actions.dart b/lib/redux/quote/quote_actions.dart index e0d77c9ba..60dd9fb57 100644 --- a/lib/redux/quote/quote_actions.dart +++ b/lib/redux/quote/quote_actions.dart @@ -217,23 +217,23 @@ class EmailQuoteFailure implements StopSaving { final dynamic error; } -class MarkSentQuoteRequest implements StartSaving { - MarkSentQuoteRequest(this.completer, this.quoteId); +class MarkSentQuotesRequest implements StartSaving { + MarkSentQuotesRequest(this.completer, this.quoteIds); final Completer completer; - final String quoteId; + final List quoteIds; } class MarkSentQuoteSuccess implements StopSaving, PersistData { - MarkSentQuoteSuccess(this.quote); + MarkSentQuoteSuccess(this.quotes); - final InvoiceEntity quote; + final List quotes; } class MarkSentQuoteFailure implements StopSaving { - MarkSentQuoteFailure(this.quote); + MarkSentQuoteFailure(this.error); - final InvoiceEntity quote; + final Object error; } class ArchiveQuotesRequest implements StartSaving { @@ -357,18 +357,17 @@ class FilterQuotesByCustom4 implements PersistUI { final String value; } -class ConvertQuote implements PersistData { - ConvertQuote(this.completer, this.quoteId); +class ConvertQuotes implements PersistData { + ConvertQuotes(this.completer, this.quoteIds); - final String quoteId; + final List quoteIds; final Completer completer; } class ConvertQuoteSuccess implements StopSaving, PersistData { - ConvertQuoteSuccess({this.quote, this.invoice}); + ConvertQuoteSuccess({this.quotes}); - final InvoiceEntity quote; - final InvoiceEntity invoice; + final List quotes; } class ConvertQuoteFailure implements StopSaving { @@ -415,7 +414,7 @@ Future handleQuoteAction( break; case EntityAction.convert: final Completer completer = Completer(); - store.dispatch(ConvertQuote(completer, quote.id)); + store.dispatch(ConvertQuotes(completer, quoteIds)); completer.future.then((InvoiceEntity invoice) { viewEntityById( context: context, @@ -424,9 +423,9 @@ Future handleQuoteAction( }); break; case EntityAction.markSent: - store.dispatch(MarkSentQuoteRequest( + store.dispatch(MarkSentQuotesRequest( snackBarCompleter(context, localization.markedQuoteAsSent), - quote.id)); + quoteIds)); break; case EntityAction.sendEmail: store.dispatch(ShowEmailQuote( diff --git a/lib/redux/quote/quote_middleware.dart b/lib/redux/quote/quote_middleware.dart index 28e2264d1..ea1b7f1fa 100644 --- a/lib/redux/quote/quote_middleware.dart +++ b/lib/redux/quote/quote_middleware.dart @@ -34,7 +34,7 @@ List> createStoreQuotesMiddleware([ TypedMiddleware(viewQuoteList), TypedMiddleware(viewQuote), TypedMiddleware(editQuote), - TypedMiddleware(convertQuote), + TypedMiddleware(convertQuote), TypedMiddleware(showEmailQuote), TypedMiddleware(loadQuotes), TypedMiddleware(loadQuote), @@ -43,7 +43,7 @@ List> createStoreQuotesMiddleware([ TypedMiddleware(deleteQuote), TypedMiddleware(restoreQuote), TypedMiddleware(emailQuote), - TypedMiddleware(markSentQuote), + TypedMiddleware(markSentQuote), ]; } @@ -209,13 +209,13 @@ Middleware _restoreQuote(QuoteRepository repository) { Middleware _convertQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { - final action = dynamicAction as ConvertQuote; - final quote = store.state.quoteState.map[action.quoteId]; + final action = dynamicAction as ConvertQuotes; repository - .saveData(store.state.credentials, quote, EntityAction.convert) - .then((InvoiceEntity invoice) { - store.dispatch(ConvertQuoteSuccess(quote: quote, invoice: invoice)); - action.completer.complete(invoice); + .bulkAction( + store.state.credentials, action.quoteIds, EntityAction.convert) + .then((quotes) { + store.dispatch(ConvertQuoteSuccess(quotes: quotes)); + action.completer.complete(quotes); }).catchError((Object error) { print(error); store.dispatch(ConvertQuoteFailure(error)); @@ -228,18 +228,18 @@ Middleware _convertQuote(QuoteRepository repository) { Middleware _markSentQuote(QuoteRepository repository) { return (Store store, dynamic dynamicAction, NextDispatcher next) { - final action = dynamicAction as MarkSentQuoteRequest; - final origQuote = store.state.quoteState.map[action.quoteId]; + final action = dynamicAction as MarkSentQuotesRequest; repository - .saveData(store.state.credentials, origQuote, EntityAction.markSent) - .then((InvoiceEntity quote) { - store.dispatch(MarkSentQuoteSuccess(quote)); + .bulkAction( + store.state.credentials, action.quoteIds, EntityAction.markSent) + .then((quotes) { + store.dispatch(MarkSentQuoteSuccess(quotes)); if (action.completer != null) { action.completer.complete(null); } }).catchError((Object error) { print(error); - store.dispatch(MarkSentQuoteFailure(origQuote)); + store.dispatch(MarkSentQuoteFailure(error)); if (action.completer != null) { action.completer.completeError(error); } diff --git a/lib/redux/quote/quote_reducer.dart b/lib/redux/quote/quote_reducer.dart index c6ab53e71..1b9121322 100644 --- a/lib/redux/quote/quote_reducer.dart +++ b/lib/redux/quote/quote_reducer.dart @@ -256,7 +256,12 @@ final quotesReducer = combineReducers([ QuoteState _markSentQuoteSuccess( QuoteState quoteState, MarkSentQuoteSuccess action) { - return quoteState.rebuild((b) => b..map[action.quote.id] = action.quote); + final quoteMap = Map.fromIterable( + action.quotes, + key: (dynamic item) => item.id, + value: (dynamic item) => item, + ); + return quoteState.rebuild((b) => b..map.addAll(quoteMap)); } QuoteState _archiveQuoteRequest( @@ -362,10 +367,12 @@ QuoteState _restoreQuoteFailure( QuoteState _convertQuoteSuccess( QuoteState quoteState, ConvertQuoteSuccess action) { - final quote = action.quote.rebuild((b) => b - ..invoiceId = action.invoice.id - ..statusId = kQuoteStatusApproved); - return quoteState.rebuild((b) => b..map[action.quote.id] = quote); + final quoteMap = Map.fromIterable( + action.quotes, + key: (dynamic item) => item.id, + value: (dynamic item) => item, + ); + return quoteState.rebuild((b) => b..map.addAll(quoteMap)); } QuoteState _addQuote(QuoteState quoteState, AddQuoteSuccess action) { diff --git a/stubs/data/repositories/stub_repository b/stubs/data/repositories/stub_repository index 480fc4ea7..f86bc853c 100644 --- a/stubs/data/repositories/stub_repository +++ b/stubs/data/repositories/stub_repository @@ -61,8 +61,7 @@ class StubRepository { Future saveData( - Credentials credentials, StubEntity stub, - [EntityAction action]) async { + Credentials credentials, StubEntity stub) async { final data = serializers.serializeWith(StubEntity.serializer, stub); dynamic response; @@ -72,10 +71,7 @@ class StubRepository { credentials.token, data: json.encode(data)); } else { - var url = '${credentials.url}/stubs/${stub.id}?'; - if (action != null) { - url += '&action=$action'; - } + var url = '${credentials.url}/stubs/${stub.id}'; response = await webClient.put(url, credentials.token, data: json.encode(data)); }