Bulk actions

This commit is contained in:
Hillel Coren 2020-03-06 10:27:53 +02:00
parent 9de2e83101
commit 3926008ebb
9 changed files with 50 additions and 68 deletions

View File

@ -46,8 +46,7 @@ class ProductRepository {
return productResponse.data.toList(); return productResponse.data.toList();
} }
Future<ProductEntity> saveData(Credentials credentials, ProductEntity product, Future<ProductEntity> saveData(Credentials credentials, ProductEntity product) async {
[EntityAction action]) async {
final data = serializers.serializeWith(ProductEntity.serializer, product); final data = serializers.serializeWith(ProductEntity.serializer, product);
dynamic response; dynamic response;
@ -56,10 +55,7 @@ class ProductRepository {
credentials.url + '/products', credentials.token, credentials.url + '/products', credentials.token,
data: json.encode(data)); data: json.encode(data));
} else { } else {
var url = credentials.url + '/products/${product.id}?'; final url = credentials.url + '/products/${product.id}';
if (action != null) {
url += '&action=' + action.toString();
}
response = response =
await webClient.put(url, credentials.token, data: json.encode(data)); await webClient.put(url, credentials.token, data: json.encode(data));
} }

View File

@ -57,8 +57,7 @@ class ProjectRepository {
return projectResponse.data.toList(); return projectResponse.data.toList();
} }
Future<ProjectEntity> saveData(Credentials credentials, ProjectEntity project, Future<ProjectEntity> saveData(Credentials credentials, ProjectEntity project) async {
[EntityAction action]) async {
final data = serializers.serializeWith(ProjectEntity.serializer, project); final data = serializers.serializeWith(ProjectEntity.serializer, project);
dynamic response; dynamic response;
@ -67,10 +66,7 @@ class ProjectRepository {
credentials.url + '/projects', credentials.token, credentials.url + '/projects', credentials.token,
data: json.encode(data)); data: json.encode(data));
} else { } else {
var url = credentials.url + '/projects/${project.id}?'; final url = credentials.url + '/projects/${project.id}';
if (action != null) {
url += '&action=' + action.toString();
}
response = response =
await webClient.put(url, credentials.token, data: json.encode(data)); await webClient.put(url, credentials.token, data: json.encode(data));
} }

View File

@ -57,8 +57,7 @@ class QuoteRepository {
return invoiceResponse.data.toList(); return invoiceResponse.data.toList();
} }
Future<InvoiceEntity> saveData(Credentials credentials, InvoiceEntity quote, Future<InvoiceEntity> saveData(Credentials credentials, InvoiceEntity quote) async {
[EntityAction action]) async {
final data = serializers.serializeWith(InvoiceEntity.serializer, quote); final data = serializers.serializeWith(InvoiceEntity.serializer, quote);
dynamic response; dynamic response;
@ -67,10 +66,7 @@ class QuoteRepository {
credentials.url + '/quotes?', credentials.token, credentials.url + '/quotes?', credentials.token,
data: json.encode(data)); data: json.encode(data));
} else { } else {
var url = '${credentials.url}/quotes/${quote.id}?'; final url = '${credentials.url}/quotes/${quote.id}';
if (action != null) {
url += '&action=' + action.toString();
}
response = response =
await webClient.put(url, credentials.token, data: json.encode(data)); await webClient.put(url, credentials.token, data: json.encode(data));
} }

View File

@ -503,7 +503,7 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
//return 'Currency Map: ${staticState.currencyMap}'; //return 'Currency Map: ${staticState.currencyMap}';
//return 'History: $historyList'; //return 'History: $historyList';
//return 'Use inclusive: ${invoiceUIState.editing.usesInclusiveTaxes}'; //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 'Token: ${userCompanyStates.map((state) => state.token.token).where((name) => name.isNotEmpty).toList().join(', ')}';
//return 'Settings: ${company.settings.companyLogo}'; //return 'Settings: ${company.settings.companyLogo}';
//return 'Designs: ${company.designs}'; //return 'Designs: ${company.designs}';

View File

@ -268,7 +268,6 @@ final invoicesReducer = combineReducers<InvoiceState>([
TypedReducer<InvoiceState, RestoreInvoicesRequest>(_restoreInvoiceRequest), TypedReducer<InvoiceState, RestoreInvoicesRequest>(_restoreInvoiceRequest),
TypedReducer<InvoiceState, RestoreInvoicesSuccess>(_restoreInvoiceSuccess), TypedReducer<InvoiceState, RestoreInvoicesSuccess>(_restoreInvoiceSuccess),
TypedReducer<InvoiceState, RestoreInvoicesFailure>(_restoreInvoiceFailure), TypedReducer<InvoiceState, RestoreInvoicesFailure>(_restoreInvoiceFailure),
TypedReducer<InvoiceState, ConvertQuoteSuccess>(_convertQuoteSuccess),
]); ]);
InvoiceState _markInvoicesSentSuccess( InvoiceState _markInvoicesSentSuccess(
@ -397,13 +396,6 @@ InvoiceState _addInvoice(InvoiceState invoiceState, AddInvoiceSuccess action) {
..list.add(action.invoice.id)); ..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) { InvoiceState _updateInvoice(InvoiceState invoiceState, dynamic action) {
return invoiceState return invoiceState
.rebuild((b) => b..map[action.invoice.id] = action.invoice); .rebuild((b) => b..map[action.invoice.id] = action.invoice);

View File

@ -217,23 +217,23 @@ class EmailQuoteFailure implements StopSaving {
final dynamic error; final dynamic error;
} }
class MarkSentQuoteRequest implements StartSaving { class MarkSentQuotesRequest implements StartSaving {
MarkSentQuoteRequest(this.completer, this.quoteId); MarkSentQuotesRequest(this.completer, this.quoteIds);
final Completer completer; final Completer completer;
final String quoteId; final List<String> quoteIds;
} }
class MarkSentQuoteSuccess implements StopSaving, PersistData { class MarkSentQuoteSuccess implements StopSaving, PersistData {
MarkSentQuoteSuccess(this.quote); MarkSentQuoteSuccess(this.quotes);
final InvoiceEntity quote; final List<InvoiceEntity> quotes;
} }
class MarkSentQuoteFailure implements StopSaving { class MarkSentQuoteFailure implements StopSaving {
MarkSentQuoteFailure(this.quote); MarkSentQuoteFailure(this.error);
final InvoiceEntity quote; final Object error;
} }
class ArchiveQuotesRequest implements StartSaving { class ArchiveQuotesRequest implements StartSaving {
@ -357,18 +357,17 @@ class FilterQuotesByCustom4 implements PersistUI {
final String value; final String value;
} }
class ConvertQuote implements PersistData { class ConvertQuotes implements PersistData {
ConvertQuote(this.completer, this.quoteId); ConvertQuotes(this.completer, this.quoteIds);
final String quoteId; final List<String> quoteIds;
final Completer completer; final Completer completer;
} }
class ConvertQuoteSuccess implements StopSaving, PersistData { class ConvertQuoteSuccess implements StopSaving, PersistData {
ConvertQuoteSuccess({this.quote, this.invoice}); ConvertQuoteSuccess({this.quotes});
final InvoiceEntity quote; final List<InvoiceEntity> quotes;
final InvoiceEntity invoice;
} }
class ConvertQuoteFailure implements StopSaving { class ConvertQuoteFailure implements StopSaving {
@ -415,7 +414,7 @@ Future handleQuoteAction(
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(ConvertQuotes(completer, quoteIds));
completer.future.then((InvoiceEntity invoice) { completer.future.then((InvoiceEntity invoice) {
viewEntityById( viewEntityById(
context: context, context: context,
@ -424,9 +423,9 @@ Future handleQuoteAction(
}); });
break; break;
case EntityAction.markSent: case EntityAction.markSent:
store.dispatch(MarkSentQuoteRequest( store.dispatch(MarkSentQuotesRequest(
snackBarCompleter<Null>(context, localization.markedQuoteAsSent), snackBarCompleter<Null>(context, localization.markedQuoteAsSent),
quote.id)); quoteIds));
break; break;
case EntityAction.sendEmail: case EntityAction.sendEmail:
store.dispatch(ShowEmailQuote( store.dispatch(ShowEmailQuote(

View File

@ -34,7 +34,7 @@ List<Middleware<AppState>> createStoreQuotesMiddleware([
TypedMiddleware<AppState, ViewQuoteList>(viewQuoteList), TypedMiddleware<AppState, ViewQuoteList>(viewQuoteList),
TypedMiddleware<AppState, ViewQuote>(viewQuote), TypedMiddleware<AppState, ViewQuote>(viewQuote),
TypedMiddleware<AppState, EditQuote>(editQuote), TypedMiddleware<AppState, EditQuote>(editQuote),
TypedMiddleware<AppState, ConvertQuote>(convertQuote), TypedMiddleware<AppState, ConvertQuotes>(convertQuote),
TypedMiddleware<AppState, ShowEmailQuote>(showEmailQuote), TypedMiddleware<AppState, ShowEmailQuote>(showEmailQuote),
TypedMiddleware<AppState, LoadQuotes>(loadQuotes), TypedMiddleware<AppState, LoadQuotes>(loadQuotes),
TypedMiddleware<AppState, LoadQuote>(loadQuote), TypedMiddleware<AppState, LoadQuote>(loadQuote),
@ -43,7 +43,7 @@ List<Middleware<AppState>> createStoreQuotesMiddleware([
TypedMiddleware<AppState, DeleteQuotesRequest>(deleteQuote), TypedMiddleware<AppState, DeleteQuotesRequest>(deleteQuote),
TypedMiddleware<AppState, RestoreQuotesRequest>(restoreQuote), TypedMiddleware<AppState, RestoreQuotesRequest>(restoreQuote),
TypedMiddleware<AppState, EmailQuoteRequest>(emailQuote), TypedMiddleware<AppState, EmailQuoteRequest>(emailQuote),
TypedMiddleware<AppState, MarkSentQuoteRequest>(markSentQuote), TypedMiddleware<AppState, MarkSentQuotesRequest>(markSentQuote),
]; ];
} }
@ -209,13 +209,13 @@ Middleware<AppState> _restoreQuote(QuoteRepository repository) {
Middleware<AppState> _convertQuote(QuoteRepository repository) { Middleware<AppState> _convertQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ConvertQuote; final action = dynamicAction as ConvertQuotes;
final quote = store.state.quoteState.map[action.quoteId];
repository repository
.saveData(store.state.credentials, quote, EntityAction.convert) .bulkAction(
.then((InvoiceEntity invoice) { store.state.credentials, action.quoteIds, EntityAction.convert)
store.dispatch(ConvertQuoteSuccess(quote: quote, invoice: invoice)); .then((quotes) {
action.completer.complete(invoice); store.dispatch(ConvertQuoteSuccess(quotes: quotes));
action.completer.complete(quotes);
}).catchError((Object error) { }).catchError((Object error) {
print(error); print(error);
store.dispatch(ConvertQuoteFailure(error)); store.dispatch(ConvertQuoteFailure(error));
@ -228,18 +228,18 @@ Middleware<AppState> _convertQuote(QuoteRepository repository) {
Middleware<AppState> _markSentQuote(QuoteRepository repository) { Middleware<AppState> _markSentQuote(QuoteRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as MarkSentQuoteRequest; final action = dynamicAction as MarkSentQuotesRequest;
final origQuote = store.state.quoteState.map[action.quoteId];
repository repository
.saveData(store.state.credentials, origQuote, EntityAction.markSent) .bulkAction(
.then((InvoiceEntity quote) { store.state.credentials, action.quoteIds, EntityAction.markSent)
store.dispatch(MarkSentQuoteSuccess(quote)); .then((quotes) {
store.dispatch(MarkSentQuoteSuccess(quotes));
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(MarkSentQuoteFailure(origQuote)); store.dispatch(MarkSentQuoteFailure(error));
if (action.completer != null) { if (action.completer != null) {
action.completer.completeError(error); action.completer.completeError(error);
} }

View File

@ -256,7 +256,12 @@ final quotesReducer = combineReducers<QuoteState>([
QuoteState _markSentQuoteSuccess( QuoteState _markSentQuoteSuccess(
QuoteState quoteState, MarkSentQuoteSuccess action) { QuoteState quoteState, MarkSentQuoteSuccess action) {
return quoteState.rebuild((b) => b..map[action.quote.id] = action.quote); final quoteMap = Map<String, InvoiceEntity>.fromIterable(
action.quotes,
key: (dynamic item) => item.id,
value: (dynamic item) => item,
);
return quoteState.rebuild((b) => b..map.addAll(quoteMap));
} }
QuoteState _archiveQuoteRequest( QuoteState _archiveQuoteRequest(
@ -362,10 +367,12 @@ QuoteState _restoreQuoteFailure(
QuoteState _convertQuoteSuccess( QuoteState _convertQuoteSuccess(
QuoteState quoteState, ConvertQuoteSuccess action) { QuoteState quoteState, ConvertQuoteSuccess action) {
final quote = action.quote.rebuild((b) => b final quoteMap = Map<String, InvoiceEntity>.fromIterable(
..invoiceId = action.invoice.id action.quotes,
..statusId = kQuoteStatusApproved); key: (dynamic item) => item.id,
return quoteState.rebuild((b) => b..map[action.quote.id] = quote); value: (dynamic item) => item,
);
return quoteState.rebuild((b) => b..map.addAll(quoteMap));
} }
QuoteState _addQuote(QuoteState quoteState, AddQuoteSuccess action) { QuoteState _addQuote(QuoteState quoteState, AddQuoteSuccess action) {

View File

@ -61,8 +61,7 @@ class StubRepository {
Future<StubEntity> saveData( Future<StubEntity> saveData(
Credentials credentials, StubEntity stub, Credentials credentials, StubEntity stub) async {
[EntityAction action]) async {
final data = serializers.serializeWith(StubEntity.serializer, stub); final data = serializers.serializeWith(StubEntity.serializer, stub);
dynamic response; dynamic response;
@ -72,10 +71,7 @@ class StubRepository {
credentials.token, credentials.token,
data: json.encode(data)); data: json.encode(data));
} else { } else {
var url = '${credentials.url}/stubs/${stub.id}?'; var url = '${credentials.url}/stubs/${stub.id}';
if (action != null) {
url += '&action=$action';
}
response = await webClient.put(url, credentials.token, data: json.encode(data)); response = await webClient.put(url, credentials.token, data: json.encode(data));
} }