Tablet layout
This commit is contained in:
parent
6081af2314
commit
c6096efb2f
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:invoiceninja_flutter/constants.dart';
|
import 'package:invoiceninja_flutter/constants.dart';
|
||||||
import 'package:invoiceninja_flutter/data/file_storage.dart';
|
import 'package:invoiceninja_flutter/data/file_storage.dart';
|
||||||
|
|
@ -15,8 +16,10 @@ import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/static/static_state.dart';
|
import 'package:invoiceninja_flutter/redux/static/static_state.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/ui/ui_state.dart';
|
import 'package:invoiceninja_flutter/redux/ui/ui_state.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
|
import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/app/dialogs/alert_dialog.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/main_screen.dart';
|
import 'package:invoiceninja_flutter/ui/app/main_screen.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/auth/login_vm.dart';
|
import 'package:invoiceninja_flutter/ui/auth/login_vm.dart';
|
||||||
|
import 'package:invoiceninja_flutter/utils/localization.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:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
@ -421,3 +424,16 @@ void _setLastLoadWasSuccesfull() async {
|
||||||
prefs.setBool('initialized', true);
|
prefs.setBool('initialized', true);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool hasChanges(Store<AppState> store, dynamic action) {
|
||||||
|
if (store.state.hasChanges() && !isMobile(action.context) && !action.force) {
|
||||||
|
showDialog<MessageDialog>(
|
||||||
|
context: action.context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return MessageDialog(AppLocalization.of(context).errorUnsavedChanges);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,23 +12,29 @@ import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
|
|
||||||
class ViewClientList implements PersistUI {
|
class ViewClientList implements PersistUI {
|
||||||
ViewClientList(this.context);
|
ViewClientList({@required this.context, this.force = false});
|
||||||
|
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
|
final bool force;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewClient implements PersistUI {
|
class ViewClient implements PersistUI {
|
||||||
ViewClient({this.clientId, this.context});
|
ViewClient({
|
||||||
|
@required this.clientId,
|
||||||
|
@required this.context,
|
||||||
|
this.force = false,
|
||||||
|
});
|
||||||
|
|
||||||
final int clientId;
|
final int clientId;
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
|
final bool force;
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditClient implements PersistUI {
|
class EditClient implements PersistUI {
|
||||||
EditClient(
|
EditClient(
|
||||||
{this.client,
|
{@required this.client,
|
||||||
|
@required this.context,
|
||||||
this.contact,
|
this.contact,
|
||||||
this.context,
|
|
||||||
this.completer,
|
this.completer,
|
||||||
this.trackRoute = true});
|
this.trackRoute = true});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:invoiceninja_flutter/data/models/models.dart';
|
import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/app/app_middleware.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/app/dialogs/alert_dialog.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/localization.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/client/client_actions.dart';
|
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
|
||||||
|
|
@ -42,13 +41,17 @@ List<Middleware<AppState>> createStoreClientsMiddleware([
|
||||||
|
|
||||||
Middleware<AppState> _editClient() {
|
Middleware<AppState> _editClient() {
|
||||||
return (Store<AppState> store, dynamic action, NextDispatcher next) async {
|
return (Store<AppState> store, dynamic action, NextDispatcher next) async {
|
||||||
|
if (hasChanges(store, action)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
next(action);
|
next(action);
|
||||||
|
|
||||||
if (action.trackRoute) {
|
if (action.trackRoute) {
|
||||||
store.dispatch(UpdateCurrentRoute(ClientEditScreen.route));
|
store.dispatch(UpdateCurrentRoute(ClientEditScreen.route));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action.context != null && isMobile(action.context)) {
|
if (isMobile(action.context)) {
|
||||||
final client =
|
final client =
|
||||||
await Navigator.of(action.context).pushNamed(ClientEditScreen.route);
|
await Navigator.of(action.context).pushNamed(ClientEditScreen.route);
|
||||||
|
|
||||||
|
|
@ -61,17 +64,12 @@ Middleware<AppState> _editClient() {
|
||||||
|
|
||||||
Middleware<AppState> _viewClient() {
|
Middleware<AppState> _viewClient() {
|
||||||
return (Store<AppState> store, dynamic action, NextDispatcher next) async {
|
return (Store<AppState> store, dynamic action, NextDispatcher next) async {
|
||||||
next(action);
|
if (hasChanges(store, action)) {
|
||||||
|
|
||||||
if (store.state.hasChanges() && !isMobile(action.context)) {
|
|
||||||
showDialog<AlertDialog>(
|
|
||||||
context: action.context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return MessageDialog(AppLocalization.of(context).errorUnsavedChanges);
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next(action);
|
||||||
|
|
||||||
store.dispatch(UpdateCurrentRoute(ClientViewScreen.route));
|
store.dispatch(UpdateCurrentRoute(ClientViewScreen.route));
|
||||||
|
|
||||||
if (isMobile(action.context)) {
|
if (isMobile(action.context)) {
|
||||||
|
|
@ -82,15 +80,15 @@ Middleware<AppState> _viewClient() {
|
||||||
|
|
||||||
Middleware<AppState> _viewClientList() {
|
Middleware<AppState> _viewClientList() {
|
||||||
return (Store<AppState> store, dynamic action, NextDispatcher next) {
|
return (Store<AppState> store, dynamic action, NextDispatcher next) {
|
||||||
next(action);
|
if (hasChanges(store, action)) {
|
||||||
|
|
||||||
if (store.state.hasChanges()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next(action);
|
||||||
|
|
||||||
store.dispatch(UpdateCurrentRoute(ClientScreen.route));
|
store.dispatch(UpdateCurrentRoute(ClientScreen.route));
|
||||||
|
|
||||||
if (action.context != null && isMobile(action.context)) {
|
if (isMobile(action.context)) {
|
||||||
Navigator.of(action.context).pushNamedAndRemoveUntil(
|
Navigator.of(action.context).pushNamedAndRemoveUntil(
|
||||||
ClientScreen.route, (Route<dynamic> route) => false);
|
ClientScreen.route, (Route<dynamic> route) => false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ final editingReducer = combineReducers<ClientEntity>([
|
||||||
TypedReducer<ClientEntity, AddContact>(_addContact),
|
TypedReducer<ClientEntity, AddContact>(_addContact),
|
||||||
TypedReducer<ClientEntity, DeleteContact>(_removeContact),
|
TypedReducer<ClientEntity, DeleteContact>(_removeContact),
|
||||||
TypedReducer<ClientEntity, UpdateContact>(_updateContact),
|
TypedReducer<ClientEntity, UpdateContact>(_updateContact),
|
||||||
|
TypedReducer<ClientEntity, ViewClient>(_clearEditing),
|
||||||
|
TypedReducer<ClientEntity, ViewClientList>(_clearEditing),
|
||||||
TypedReducer<ClientEntity, SelectCompany>(_clearEditing),
|
TypedReducer<ClientEntity, SelectCompany>(_clearEditing),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
|
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
|
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/dialogs/alert_dialog.dart';
|
import 'package:invoiceninja_flutter/ui/app/dialogs/alert_dialog.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
|
|
||||||
import 'package:invoiceninja_flutter/ui/product/edit/product_edit_vm.dart';
|
import 'package:invoiceninja_flutter/ui/product/edit/product_edit_vm.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';
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import 'package:built_collection/built_collection.dart';
|
||||||
import 'package:built_value/built_value.dart';
|
import 'package:built_value/built_value.dart';
|
||||||
import 'package:built_value/serializer.dart';
|
import 'package:built_value/serializer.dart';
|
||||||
import 'package:invoiceninja_flutter/data/models/company_model.dart';
|
import 'package:invoiceninja_flutter/data/models/company_model.dart';
|
||||||
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
|
||||||
import 'package:invoiceninja_flutter/redux/client/client_state.dart';
|
import 'package:invoiceninja_flutter/redux/client/client_state.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/dashboard/dashboard_state.dart';
|
import 'package:invoiceninja_flutter/redux/dashboard/dashboard_state.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/invoice/invoice_state.dart';
|
import 'package:invoiceninja_flutter/redux/invoice/invoice_state.dart';
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ class AppDrawer extends StatelessWidget {
|
||||||
entityType: EntityType.client,
|
entityType: EntityType.client,
|
||||||
icon: getEntityIcon(EntityType.client),
|
icon: getEntityIcon(EntityType.client),
|
||||||
title: localization.clients,
|
title: localization.clients,
|
||||||
onTap: () => store.dispatch(ViewClientList(context)),
|
onTap: () => store.dispatch(ViewClientList(context: context)),
|
||||||
onCreateTap: () {
|
onCreateTap: () {
|
||||||
if (isMobile(context)) {
|
if (isMobile(context)) {
|
||||||
navigator.pop();
|
navigator.pop();
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,11 @@ class _ClientEditState extends State<ClientEdit>
|
||||||
title: Text(
|
title: Text(
|
||||||
client.isNew ? localization.newClient : localization.editClient),
|
client.isNew ? localization.newClient : localization.editClient),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
|
if (!isMobile(context))
|
||||||
|
FlatButton(
|
||||||
|
child: Text(localization.cancel),
|
||||||
|
onPressed: () => viewModel.onCancelPressed(context),
|
||||||
|
),
|
||||||
ActionIconButton(
|
ActionIconButton(
|
||||||
icon: Icons.cloud_upload,
|
icon: Icons.cloud_upload,
|
||||||
tooltip: localization.save,
|
tooltip: localization.save,
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ class ClientEditVM {
|
||||||
@required this.onChanged,
|
@required this.onChanged,
|
||||||
@required this.onSavePressed,
|
@required this.onSavePressed,
|
||||||
@required this.onBackPressed,
|
@required this.onBackPressed,
|
||||||
|
@required this.onCancelPressed,
|
||||||
@required this.staticState,
|
@required this.staticState,
|
||||||
@required this.copyBillingAddress,
|
@required this.copyBillingAddress,
|
||||||
@required this.copyShippingAddress,
|
@required this.copyShippingAddress,
|
||||||
|
|
@ -87,6 +88,15 @@ class ClientEditVM {
|
||||||
..state = client.shippingState
|
..state = client.shippingState
|
||||||
..postalCode = client.shippingPostalCode
|
..postalCode = client.shippingPostalCode
|
||||||
..countryId = client.shippingCountryId))),
|
..countryId = client.shippingCountryId))),
|
||||||
|
onCancelPressed: (BuildContext context) {
|
||||||
|
store.dispatch(EditClient(client: ClientEntity(), context: context));
|
||||||
|
if (client.isNew) {
|
||||||
|
store.dispatch(ViewClientList(context: context, force: true));
|
||||||
|
} else {
|
||||||
|
store.dispatch(
|
||||||
|
ViewClient(context: context, clientId: client.id, force: true));
|
||||||
|
}
|
||||||
|
},
|
||||||
onSavePressed: (BuildContext context) {
|
onSavePressed: (BuildContext context) {
|
||||||
if (!client.hasNameSet) {
|
if (!client.hasNameSet) {
|
||||||
showDialog<ErrorDialog>(
|
showDialog<ErrorDialog>(
|
||||||
|
|
@ -138,6 +148,7 @@ class ClientEditVM {
|
||||||
final Function(ClientEntity) onChanged;
|
final Function(ClientEntity) onChanged;
|
||||||
final Function(BuildContext) onSavePressed;
|
final Function(BuildContext) onSavePressed;
|
||||||
final Function onBackPressed;
|
final Function onBackPressed;
|
||||||
|
final Function(BuildContext) onCancelPressed;
|
||||||
final StaticState staticState;
|
final StaticState staticState;
|
||||||
final Function() copyShippingAddress;
|
final Function() copyShippingAddress;
|
||||||
final Function() copyBillingAddress;
|
final Function() copyBillingAddress;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue