This commit is contained in:
Hillel Coren 2019-10-11 09:50:04 +03:00
parent 5a316302fd
commit a6d0e78f16
29 changed files with 145 additions and 94 deletions

View File

@ -84,6 +84,8 @@ class RefreshData {
class ClearLastError {} class ClearLastError {}
class DiscardChanges {}
class FilterCompany { class FilterCompany {
FilterCompany(this.filter); FilterCompany(this.filter);

View File

@ -448,20 +448,26 @@ void _setLastLoadWasSuccesfull() async {
} }
*/ */
bool hasChanges({Store<AppState> store, BuildContext context, bool force}) { bool hasChanges({
@required Store<AppState> store,
@required BuildContext context,
@required dynamic action,
}) {
final localization = AppLocalization.of(context);
if (context == null) { if (context == null) {
print('WARNING: context is null in hasChanges'); print('WARNING: context is null in hasChanges');
return false; return false;
} else if (force == null) {
print('WARNING: force is null in hasChanges');
return false;
} }
if (store.state.hasChanges() && !isMobile(context) && !force) { if (store.state.hasChanges() && !isMobile(context)) {
showDialog<MessageDialog>( showDialog<MessageDialog>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return MessageDialog(AppLocalization.of(context).errorUnsavedChanges); return MessageDialog(localization.errorUnsavedChanges, onDiscard: () {
store.dispatch(DiscardChanges());
store.dispatch(action);
});
}); });
return true; return true;
} else { } else {

View File

@ -43,8 +43,8 @@ Middleware<AppState> _editClient() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditClient; final action = dynamicAction as EditClient;
if (hasChanges( if (!action.force &&
store: store, context: action.context, force: action.force)) { hasChanges(store: store, context: action.context, action: action)) {
return; return;
} }
@ -63,8 +63,10 @@ Middleware<AppState> _viewClient() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewClient; final action = dynamicAction as ViewClient;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store,
context: action.context,
action: action)) {
return; return;
} }
@ -82,8 +84,10 @@ Middleware<AppState> _viewClientList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewClientList; final action = dynamicAction as ViewClientList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store,
context: action.context,
action: action)) {
return; return;
} }

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
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/client/client_actions.dart'; import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/client/client_state.dart'; import 'package:invoiceninja_flutter/redux/client/client_state.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
@ -92,6 +93,9 @@ final editingReducer = combineReducers<ClientEntity>([
TypedReducer<ClientEntity, SelectCompany>((client, action) { TypedReducer<ClientEntity, SelectCompany>((client, action) {
return ClientEntity(); return ClientEntity();
}), }),
TypedReducer<ClientEntity, DiscardChanges>((client, action) {
return ClientEntity();
}),
]); ]);
final clientListReducer = combineReducers<ListUIState>([ final clientListReducer = combineReducers<ListUIState>([

View File

@ -25,8 +25,8 @@ Middleware<AppState> _createViewDashboard() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewDashboard; final action = dynamicAction as ViewDashboard;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -45,8 +45,8 @@ Middleware<AppState> _editExpense() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditExpense; final action = dynamicAction as EditExpense;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -70,8 +70,8 @@ Middleware<AppState> _viewExpense() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewExpense; final action = dynamicAction as ViewExpense;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -89,8 +89,8 @@ Middleware<AppState> _viewExpenseList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewExpenseList; final action = dynamicAction as ViewExpenseList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,3 +1,4 @@
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
@ -32,6 +33,7 @@ final editingReducer = combineReducers<ExpenseEntity>([
return action.expense.rebuild((b) => b..isChanged = true); return action.expense.rebuild((b) => b..isChanged = true);
}), }),
TypedReducer<ExpenseEntity, SelectCompany>(_clearEditing), TypedReducer<ExpenseEntity, SelectCompany>(_clearEditing),
TypedReducer<ExpenseEntity, DiscardChanges>(_clearEditing),
]); ]);
ExpenseEntity _clearEditing(ExpenseEntity expense, dynamic action) { ExpenseEntity _clearEditing(ExpenseEntity expense, dynamic action) {

View File

@ -44,8 +44,8 @@ Middleware<AppState> _editGroup() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditGroup; final action = dynamicAction as EditGroup;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -69,8 +69,8 @@ Middleware<AppState> _viewGroup() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewGroup; final action = dynamicAction as ViewGroup;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -88,8 +88,8 @@ Middleware<AppState> _viewGroupList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewGroupList; final action = dynamicAction as ViewGroupList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,4 +1,5 @@
import 'package:invoiceninja_flutter/data/models/group_model.dart'; import 'package:invoiceninja_flutter/data/models/group_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart'; import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
@ -33,6 +34,7 @@ final editingReducer = combineReducers<GroupEntity>([
return action.group.rebuild((b) => b..isChanged = true); return action.group.rebuild((b) => b..isChanged = true);
}), }),
TypedReducer<GroupEntity, SelectCompany>(_clearEditing), TypedReducer<GroupEntity, SelectCompany>(_clearEditing),
TypedReducer<GroupEntity, DiscardChanges>(_clearEditing),
]); ]);
GroupEntity _clearEditing(GroupEntity group, dynamic action) { GroupEntity _clearEditing(GroupEntity group, dynamic action) {

View File

@ -53,8 +53,8 @@ Middleware<AppState> _viewInvoiceList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewInvoiceList; final action = dynamicAction as ViewInvoiceList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -78,8 +78,8 @@ Middleware<AppState> _viewInvoice() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewInvoice; final action = dynamicAction as ViewInvoice;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -98,8 +98,8 @@ Middleware<AppState> _editInvoice() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditInvoice; final action = dynamicAction as EditInvoice;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,4 +1,5 @@
import 'package:invoiceninja_flutter/data/models/invoice_model.dart'; import 'package:invoiceninja_flutter/data/models/invoice_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_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/ui/entity_ui_state.dart'; import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
@ -59,6 +60,7 @@ final editingReducer = combineReducers<InvoiceEntity>([
TypedReducer<InvoiceEntity, DeleteInvoiceItem>(_removeInvoiceItem), TypedReducer<InvoiceEntity, DeleteInvoiceItem>(_removeInvoiceItem),
TypedReducer<InvoiceEntity, UpdateInvoiceItem>(_updateInvoiceItem), TypedReducer<InvoiceEntity, UpdateInvoiceItem>(_updateInvoiceItem),
TypedReducer<InvoiceEntity, SelectCompany>(_clearEditing), TypedReducer<InvoiceEntity, SelectCompany>(_clearEditing),
TypedReducer<InvoiceEntity, DiscardChanges>(_clearEditing),
]); ]);
InvoiceEntity _clearEditing(InvoiceEntity client, dynamic action) { InvoiceEntity _clearEditing(InvoiceEntity client, dynamic action) {

View File

@ -47,8 +47,8 @@ Middleware<AppState> _editPayment() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditPayment; final action = dynamicAction as EditPayment;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -69,8 +69,8 @@ Middleware<AppState> _editPayment() {
Middleware<AppState> _viewPayment() { Middleware<AppState> _viewPayment() {
return (Store<AppState> store, dynamic action, NextDispatcher next) async { return (Store<AppState> store, dynamic action, NextDispatcher next) async {
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -88,8 +88,8 @@ Middleware<AppState> _viewPaymentList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewPaymentList; final action = dynamicAction as ViewPaymentList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,3 +1,4 @@
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
@ -32,9 +33,10 @@ final editingReducer = combineReducers<PaymentEntity>([
return action.payment.rebuild((b) => b..isChanged = true); return action.payment.rebuild((b) => b..isChanged = true);
}), }),
TypedReducer<PaymentEntity, SelectCompany>(_clearEditing), TypedReducer<PaymentEntity, SelectCompany>(_clearEditing),
TypedReducer<PaymentEntity, DiscardChanges>(_clearEditing),
]); ]);
PaymentEntity _clearEditing(PaymentEntity payment, SelectCompany action) { PaymentEntity _clearEditing(PaymentEntity payment, dynamic action) {
return PaymentEntity(); return PaymentEntity();
} }

View File

@ -41,8 +41,8 @@ Middleware<AppState> _editProduct() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditProduct; final action = dynamicAction as EditProduct;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -61,8 +61,8 @@ Middleware<AppState> _viewProduct() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewProduct; final action = dynamicAction as ViewProduct;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -80,8 +80,8 @@ Middleware<AppState> _viewProductList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewProductList; final action = dynamicAction as ViewProductList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,5 +1,6 @@
import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/product_model.dart'; import 'package:invoiceninja_flutter/data/models/product_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_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/product/product_state.dart'; import 'package:invoiceninja_flutter/redux/product/product_state.dart';
@ -34,6 +35,7 @@ final editingReducer = combineReducers<ProductEntity>([
TypedReducer<ProductEntity, ArchiveProductSuccess>(_updateEditing), TypedReducer<ProductEntity, ArchiveProductSuccess>(_updateEditing),
TypedReducer<ProductEntity, DeleteProductSuccess>(_updateEditing), TypedReducer<ProductEntity, DeleteProductSuccess>(_updateEditing),
TypedReducer<ProductEntity, SelectCompany>(_clearEditing), TypedReducer<ProductEntity, SelectCompany>(_clearEditing),
TypedReducer<ProductEntity, DiscardChanges>(_clearEditing),
]); ]);
ProductEntity _clearEditing(ProductEntity client, dynamic action) { ProductEntity _clearEditing(ProductEntity client, dynamic action) {

View File

@ -45,8 +45,8 @@ Middleware<AppState> _editProject() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditProject; final action = dynamicAction as EditProject;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -70,8 +70,8 @@ Middleware<AppState> _viewProject() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewProject; final action = dynamicAction as ViewProject;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -89,8 +89,8 @@ Middleware<AppState> _viewProjectList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewProjectList; final action = dynamicAction as ViewProjectList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
@ -48,6 +49,7 @@ final editingReducer = combineReducers<ProjectEntity>([
}), }),
TypedReducer<ProjectEntity, UpdateProject>(_updateEditing), TypedReducer<ProjectEntity, UpdateProject>(_updateEditing),
TypedReducer<ProjectEntity, SelectCompany>(_clearEditing), TypedReducer<ProjectEntity, SelectCompany>(_clearEditing),
TypedReducer<ProjectEntity, DiscardChanges>(_clearEditing),
]); ]);
ProjectEntity _clearEditing(ProjectEntity project, dynamic dynamicAction) { ProjectEntity _clearEditing(ProjectEntity project, dynamic dynamicAction) {

View File

@ -53,8 +53,8 @@ Middleware<AppState> _viewQuote() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewQuote; final action = dynamicAction as ViewQuote;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -72,8 +72,8 @@ Middleware<AppState> _viewQuoteList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewQuoteList; final action = dynamicAction as ViewQuoteList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -97,8 +97,8 @@ Middleware<AppState> _editQuote() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditQuote; final action = dynamicAction as EditQuote;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,5 +1,6 @@
import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/invoice_model.dart'; import 'package:invoiceninja_flutter/data/models/invoice_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_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/quote/quote_state.dart'; import 'package:invoiceninja_flutter/redux/quote/quote_state.dart';
@ -57,6 +58,7 @@ final editingReducer = combineReducers<InvoiceEntity>([
TypedReducer<InvoiceEntity, DeleteQuoteItem>(_removeQuoteItem), TypedReducer<InvoiceEntity, DeleteQuoteItem>(_removeQuoteItem),
TypedReducer<InvoiceEntity, UpdateQuoteItem>(_updateQuoteItem), TypedReducer<InvoiceEntity, UpdateQuoteItem>(_updateQuoteItem),
TypedReducer<InvoiceEntity, SelectCompany>(_clearEditing), TypedReducer<InvoiceEntity, SelectCompany>(_clearEditing),
TypedReducer<InvoiceEntity, DiscardChanges>(_clearEditing),
]); ]);
InvoiceEntity _clearEditing(InvoiceEntity client, dynamic action) { InvoiceEntity _clearEditing(InvoiceEntity client, dynamic action) {

View File

@ -30,8 +30,8 @@ Middleware<AppState> _viewSettings() {
final action = dynamicAction as ViewSettings; final action = dynamicAction as ViewSettings;
final uiState = store.state.uiState; final uiState = store.state.uiState;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -44,8 +44,8 @@ Middleware<AppState> _editTask() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditTask; final action = dynamicAction as EditTask;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -69,8 +69,8 @@ Middleware<AppState> _viewTask() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewTask; final action = dynamicAction as ViewTask;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -88,8 +88,8 @@ Middleware<AppState> _viewTaskList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewTaskList; final action = dynamicAction as ViewTaskList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,3 +1,4 @@
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
@ -44,6 +45,7 @@ final editingReducer = combineReducers<TaskEntity>([
TypedReducer<TaskEntity, DeleteTaskTime>(_removeTaskTime), TypedReducer<TaskEntity, DeleteTaskTime>(_removeTaskTime),
TypedReducer<TaskEntity, UpdateTaskTime>(_updateTaskTime), TypedReducer<TaskEntity, UpdateTaskTime>(_updateTaskTime),
TypedReducer<TaskEntity, SelectCompany>(_clearEditing), TypedReducer<TaskEntity, SelectCompany>(_clearEditing),
TypedReducer<TaskEntity, DiscardChanges>(_clearEditing),
]); ]);
TaskEntity _clearEditing(TaskEntity task, dynamic action) { TaskEntity _clearEditing(TaskEntity task, dynamic action) {

View File

@ -45,8 +45,8 @@ Middleware<AppState> _editVendor() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as EditVendor; final action = dynamicAction as EditVendor;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -70,8 +70,8 @@ Middleware<AppState> _viewVendor() {
NextDispatcher next) async { NextDispatcher next) async {
final action = dynamicAction as ViewVendor; final action = dynamicAction as ViewVendor;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -89,8 +89,8 @@ Middleware<AppState> _viewVendorList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewVendorList; final action = dynamicAction as ViewVendorList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
@ -63,6 +64,7 @@ final editingReducer = combineReducers<VendorEntity>([
TypedReducer<VendorEntity, DeleteVendorContact>(_removeContact), TypedReducer<VendorEntity, DeleteVendorContact>(_removeContact),
TypedReducer<VendorEntity, UpdateVendorContact>(_updateContact), TypedReducer<VendorEntity, UpdateVendorContact>(_updateContact),
TypedReducer<VendorEntity, SelectCompany>(_clearEditing), TypedReducer<VendorEntity, SelectCompany>(_clearEditing),
TypedReducer<VendorEntity, DiscardChanges>(_clearEditing),
]); ]);
VendorEntity _clearEditing(VendorEntity vendor, dynamic action) { VendorEntity _clearEditing(VendorEntity vendor, dynamic action) {

View File

@ -3,10 +3,11 @@ import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class MessageDialog extends StatelessWidget { class MessageDialog extends StatelessWidget {
const MessageDialog(this.message, {this.onDismiss}); const MessageDialog(this.message, {this.onDismiss, this.onDiscard});
final String message; final String message;
final Function onDismiss; final Function onDismiss;
final Function onDiscard;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -22,16 +23,26 @@ class MessageDialog extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
/*
Text(localization.anErrorOccurred,
style: Theme.of(context).textTheme.title),
*/
SizedBox(height: 20.0), SizedBox(height: 20.0),
Text( Text(
message, message,
style: Theme.of(context).textTheme.title, style: Theme.of(context).textTheme.title,
), ),
SizedBox(height: 40.0), SizedBox(height: 40.0),
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (onDiscard != null)
Padding(
padding: const EdgeInsets.only(right: 10),
child: FlatButton(
child: Text(localization.discardChanges),
onPressed: () {
Navigator.of(context).pop();
onDiscard();
}
),
),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
@ -43,6 +54,8 @@ class MessageDialog extends StatelessWidget {
), ),
], ],
), ),
],
),
), ),
), ),
Expanded(child: Container()), Expanded(child: Container()),

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
class AppForm extends StatelessWidget { class AppForm extends StatelessWidget {
const AppForm({ const AppForm({

View File

@ -14,6 +14,7 @@ abstract class LocaleCodeAware {
mixin LocalizationsProvider on LocaleCodeAware { mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = { static final Map<String, Map<String, String>> _localizedValues = {
'en': { 'en': {
'discard_changes': 'Discard Changes',
'default_value': 'Default value', 'default_value': 'Default value',
'disabled': 'Disabled', 'disabled': 'Disabled',
'currency_format': 'Currency Format', 'currency_format': 'Currency Format',
@ -112,7 +113,7 @@ mixin LocalizationsProvider on LocaleCodeAware {
'email_login': 'Email Login', 'email_login': 'Email Login',
'create_new': 'Create New', 'create_new': 'Create New',
'no_record_selected': 'No record selected', 'no_record_selected': 'No record selected',
'error_unsaved_changes': 'Please cancel or save your changes', 'error_unsaved_changes': 'Your changes have not been saved',
'download': 'Download', 'download': 'Download',
'requires_an_enterprise_plan': 'Requires an enterprise plan', 'requires_an_enterprise_plan': 'Requires an enterprise plan',
'take_picture': 'Take Picture', 'take_picture': 'Take Picture',
@ -14835,6 +14836,8 @@ mixin LocalizationsProvider on LocaleCodeAware {
String get defaultValue => _localizedValues[localeCode]['default_value']; String get defaultValue => _localizedValues[localeCode]['default_value'];
String get discardChanges => _localizedValues[localeCode]['discard_changes'];
String lookup(String key) { String lookup(String key) {
final lookupKey = toSnakeCase(key); final lookupKey = toSnakeCase(key);

View File

@ -43,8 +43,8 @@ Middleware<AppState> _editStub() {
final action = dynamicAction as EditStub; final action = dynamicAction as EditStub;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -68,8 +68,8 @@ Middleware<AppState> _viewStub() {
final action = dynamicAction as ViewStub; final action = dynamicAction as ViewStub;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }
@ -88,8 +88,8 @@ Middleware<AppState> _viewStubList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) { return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewStubList; final action = dynamicAction as ViewStubList;
if (hasChanges( if (!action.force && hasChanges(
store: store, context: action.context, force: action.force)) { store: store, context: action.context, action: action)) {
return; return;
} }

View File

@ -1,4 +1,5 @@
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart'; import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
@ -32,6 +33,7 @@ final editingReducer = combineReducers<StubEntity>([
return action.stub.rebuild((b) => b..isChanged = true); return action.stub.rebuild((b) => b..isChanged = true);
}), }),
TypedReducer<StubEntity, SelectCompany>(_clearEditing), TypedReducer<StubEntity, SelectCompany>(_clearEditing),
TypedReducer<StubEntity, DiscardChanges>(_clearEditing),
]); ]);
StubEntity _clearEditing(StubEntity stub, dynamic action) { StubEntity _clearEditing(StubEntity stub, dynamic action) {