Tablet layout

This commit is contained in:
Hillel Coren 2019-08-16 11:52:18 +03:00
parent 81da98a219
commit 28c791734a
11 changed files with 78 additions and 19 deletions

View File

@ -46,9 +46,13 @@ Middleware<AppState> _editClient() {
next(action); next(action);
store.dispatch(UpdateCurrentRoute(ClientEditScreen.route));
/*
if (action.trackRoute) { if (action.trackRoute) {
store.dispatch(UpdateCurrentRoute(ClientEditScreen.route)); store.dispatch(UpdateCurrentRoute(ClientEditScreen.route));
} }
*/
if (isMobile(action.context)) { if (isMobile(action.context)) {
Navigator.of(action.context).pushNamed(ClientEditScreen.route); Navigator.of(action.context).pushNamed(ClientEditScreen.route);
@ -166,14 +170,16 @@ Middleware<AppState> _saveClient(ClientRepository repository) {
.then((ClientEntity client) { .then((ClientEntity client) {
if (action.client.isNew) { if (action.client.isNew) {
store.dispatch(AddClientSuccess(client)); store.dispatch(AddClientSuccess(client));
final clientUIState = store.state.clientUIState;
if (clientUIState.saveCompleter != null) {
clientUIState.saveCompleter.complete(client);
}
} else { } else {
store.dispatch(SaveClientSuccess(client)); store.dispatch(SaveClientSuccess(client));
} }
action.completer.complete(client); action.completer.complete(client);
final clientUIState = store.state.clientUIState;
if (clientUIState.saveCompleter != null) {
clientUIState.saveCompleter.complete(client);
}
}).catchError((Object error) { }).catchError((Object error) {
print(error); print(error);
store.dispatch(SaveClientFailure(error)); store.dispatch(SaveClientFailure(error));

View File

@ -13,25 +13,28 @@ import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ViewQuoteList implements PersistUI { class ViewQuoteList implements PersistUI {
ViewQuoteList(this.context); ViewQuoteList({this.context, this.force = false});
final BuildContext context; final BuildContext context;
final bool force;
} }
class ViewQuote implements PersistUI { class ViewQuote implements PersistUI {
ViewQuote({this.quoteId, this.context}); ViewQuote({this.quoteId, this.context, this.force = false});
final int quoteId; final int quoteId;
final BuildContext context; final BuildContext context;
final bool force;
} }
class EditQuote implements PersistUI { class EditQuote implements PersistUI {
EditQuote({this.quote, this.context, this.completer, this.quoteItem}); EditQuote({this.quote, this.context, this.completer, this.quoteItem, this.force = false});
final InvoiceEntity quote; final InvoiceEntity quote;
final InvoiceItemEntity quoteItem; final InvoiceItemEntity quoteItem;
final BuildContext context; final BuildContext context;
final Completer completer; final Completer completer;
final bool force;
} }
class ShowEmailQuote { class ShowEmailQuote {

View File

@ -251,7 +251,7 @@ class AppDrawer extends StatelessWidget {
entityType: EntityType.quote, entityType: EntityType.quote,
icon: getEntityIcon(EntityType.quote), icon: getEntityIcon(EntityType.quote),
title: localization.quotes, title: localization.quotes,
onTap: () => store.dispatch(ViewQuoteList(context)), onTap: () => store.dispatch(ViewQuoteList(context: context)),
onCreateTap: () { onCreateTap: () {
if (isMobile(context)) { if (isMobile(context)) {
navigator.pop(); navigator.pop();

View File

@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.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';

View File

@ -12,6 +12,7 @@ import 'package:invoiceninja_flutter/ui/client/client_screen.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit.dart'; import 'package:invoiceninja_flutter/ui/client/edit/client_edit.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/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
class ClientEditScreen extends StatelessWidget { class ClientEditScreen extends StatelessWidget {
@ -110,11 +111,13 @@ class ClientEditVM {
if (state.uiState.currentRoute.contains(ClientScreen.route)) { if (state.uiState.currentRoute.contains(ClientScreen.route)) {
store.dispatch(UpdateCurrentRoute(ClientViewScreen.route)); store.dispatch(UpdateCurrentRoute(ClientViewScreen.route));
} }
if (client.isNew && state.clientUIState.saveCompleter == null) { if (isMobile(context)) {
Navigator.of(context) if (client.isNew && state.clientUIState.saveCompleter == null) {
.pushReplacementNamed(ClientViewScreen.route); Navigator.of(context)
} else { .pushReplacementNamed(ClientViewScreen.route);
Navigator.of(context).pop(savedClient); } else {
Navigator.of(context).pop(savedClient);
}
} }
}).catchError((Object error) { }).catchError((Object error) {
showDialog<ErrorDialog>( showDialog<ErrorDialog>(

View File

@ -111,7 +111,7 @@ class ClientViewVM {
} else { } else {
store.dispatch(FilterQuotesByEntity( store.dispatch(FilterQuotesByEntity(
entityId: client.id, entityType: EntityType.client)); entityId: client.id, entityType: EntityType.client));
store.dispatch(ViewQuoteList(context)); store.dispatch(ViewQuoteList(context: context));
} }
break; break;
case EntityType.payment: case EntityType.payment:

View File

@ -11,6 +11,7 @@ import 'package:invoiceninja_flutter/ui/quote/edit/quote_edit_notes_vm.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/action_icon_button.dart'; import 'package:invoiceninja_flutter/ui/app/buttons/action_icon_button.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
class InvoiceEdit extends StatefulWidget { class InvoiceEdit extends StatefulWidget {
const InvoiceEdit({ const InvoiceEdit({
@ -73,6 +74,14 @@ class _InvoiceEditState extends State<InvoiceEdit>
? localization.editQuote ? localization.editQuote
: localization.editInvoice), : localization.editInvoice),
actions: <Widget>[ actions: <Widget>[
if (!isMobile(context))
FlatButton(
child: Text(
localization.cancel,
style: TextStyle(color: Colors.white),
),
onPressed: () => viewModel.onCancelPressed(context),
),
ActionIconButton( ActionIconButton(
icon: Icons.cloud_upload, icon: Icons.cloud_upload,
tooltip: localization.save, tooltip: localization.save,

View File

@ -1,8 +1,12 @@
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/client_model.dart'; import 'package:invoiceninja_flutter/data/models/client_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/client/client_selectors.dart'; import 'package:invoiceninja_flutter/redux/client/client_selectors.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/invoice/tax_rate_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/invoice/tax_rate_dropdown.dart';
import 'package:invoiceninja_flutter/ui/invoice/edit/invoice_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart';
@ -152,6 +156,10 @@ class InvoiceEditDetailsState extends State<InvoiceEditDetails> {
}, },
onAddPressed: (completer) { onAddPressed: (completer) {
viewModel.onAddClientPressed(context, completer); viewModel.onAddClientPressed(context, completer);
completer.future.then((client) {
final store = StoreProvider.of<AppState>(context);
store.dispatch(UpdateCurrentRoute(InvoiceEditScreen.route));
});
}, },
) )
: TextFormField( : TextFormField(

View File

@ -84,6 +84,7 @@ class InvoiceEditDetailsVM extends EntityEditDetailsVM {
client: ClientEntity(), client: ClientEntity(),
context: context, context: context,
completer: completer, completer: completer,
force: true,
trackRoute: false)); trackRoute: false));
completer.future.then((SelectableEntity client) { completer.future.then((SelectableEntity client) {
Scaffold.of(context).showSnackBar(SnackBar( Scaffold.of(context).showSnackBar(SnackBar(

View File

@ -6,6 +6,7 @@ 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/invoice/invoice_screen.dart'; import 'package:invoiceninja_flutter/ui/invoice/invoice_screen.dart';
import 'package:invoiceninja_flutter/ui/invoice/view/invoice_view_vm.dart'; import 'package:invoiceninja_flutter/ui/invoice/view/invoice_view_vm.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
@ -43,6 +44,7 @@ class EntityEditVM {
@required this.onItemsAdded, @required this.onItemsAdded,
@required this.onBackPressed, @required this.onBackPressed,
@required this.isSaving, @required this.isSaving,
@required this.onCancelPressed,
}); });
final AppState state; final AppState state;
@ -54,6 +56,7 @@ class EntityEditVM {
final Function(List<InvoiceItemEntity>, int) onItemsAdded; final Function(List<InvoiceItemEntity>, int) onItemsAdded;
final Function onBackPressed; final Function onBackPressed;
final bool isSaving; final bool isSaving;
final Function(BuildContext) onCancelPressed;
} }
class InvoiceEditVM extends EntityEditVM { class InvoiceEditVM extends EntityEditVM {
@ -67,6 +70,7 @@ class InvoiceEditVM extends EntityEditVM {
Function(List<InvoiceItemEntity>, int) onItemsAdded, Function(List<InvoiceItemEntity>, int) onItemsAdded,
Function onBackPressed, Function onBackPressed,
bool isSaving, bool isSaving,
Function(BuildContext) onCancelPressed,
}) : super( }) : super(
state: state, state: state,
company: company, company: company,
@ -77,6 +81,7 @@ class InvoiceEditVM extends EntityEditVM {
onItemsAdded: onItemsAdded, onItemsAdded: onItemsAdded,
onBackPressed: onBackPressed, onBackPressed: onBackPressed,
isSaving: isSaving, isSaving: isSaving,
onCancelPressed: onCancelPressed,
); );
factory InvoiceEditVM.fromStore(Store<AppState> store) { factory InvoiceEditVM.fromStore(Store<AppState> store) {
@ -102,10 +107,13 @@ class InvoiceEditVM extends EntityEditVM {
SaveInvoiceRequest(completer: completer, invoice: invoice)); SaveInvoiceRequest(completer: completer, invoice: invoice));
return completer.future.then((savedInvoice) { return completer.future.then((savedInvoice) {
store.dispatch(UpdateCurrentRoute(InvoiceViewScreen.route)); store.dispatch(UpdateCurrentRoute(InvoiceViewScreen.route));
if (invoice.isNew) { if (isMobile(context)) {
Navigator.of(context).pushReplacementNamed(InvoiceViewScreen.route); if (invoice.isNew) {
} else { Navigator.of(context)
Navigator.of(context).pop(savedInvoice); .pushReplacementNamed(InvoiceViewScreen.route);
} else {
Navigator.of(context).pop(savedInvoice);
}
} }
}).catchError((Object error) { }).catchError((Object error) {
showDialog<ErrorDialog>( showDialog<ErrorDialog>(
@ -126,6 +134,16 @@ class InvoiceEditVM extends EntityEditVM {
store.dispatch(EditInvoiceItem(items[0])); store.dispatch(EditInvoiceItem(items[0]));
} }
}, },
onCancelPressed: (BuildContext context) {
store.dispatch(EditInvoice(
invoice: InvoiceEntity(), context: context, force: true));
if (invoice.isNew) {
store.dispatch(ViewInvoiceList(context: context, force: true));
} else {
store.dispatch(ViewInvoice(
context: context, invoiceId: invoice.id, force: true));
}
},
); );
} }
} }

View File

@ -44,6 +44,7 @@ class QuoteEditVM extends EntityEditVM {
Function(List<InvoiceItemEntity>, int) onItemsAdded, Function(List<InvoiceItemEntity>, int) onItemsAdded,
Function onBackPressed, Function onBackPressed,
bool isSaving, bool isSaving,
Function(BuildContext) onCancelPressed,
}) : super( }) : super(
state: state, state: state,
company: company, company: company,
@ -54,6 +55,7 @@ class QuoteEditVM extends EntityEditVM {
onItemsAdded: onItemsAdded, onItemsAdded: onItemsAdded,
onBackPressed: onBackPressed, onBackPressed: onBackPressed,
isSaving: isSaving, isSaving: isSaving,
onCancelPressed: onCancelPressed,
); );
factory QuoteEditVM.fromStore(Store<AppState> store) { factory QuoteEditVM.fromStore(Store<AppState> store) {
@ -96,6 +98,16 @@ class QuoteEditVM extends EntityEditVM {
} }
store.dispatch(AddQuoteItems(items)); store.dispatch(AddQuoteItems(items));
}, },
onCancelPressed: (BuildContext context) {
store.dispatch(
EditQuote(quote: InvoiceEntity(), context: context, force: true));
if (quote.isNew) {
store.dispatch(ViewQuoteList(context: context, force: true));
} else {
store.dispatch(
ViewQuote(context: context, quoteId: quote.id, force: true));
}
},
); );
} }
} }