Refactor
This commit is contained in:
parent
30a028a07d
commit
ea16feae8f
|
|
@ -9,6 +9,7 @@ import 'package:invoiceninja_flutter/data/models/static/static_data_model.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
|
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
|
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/document/document_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart';
|
import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/group/group_actions.dart';
|
import 'package:invoiceninja_flutter/redux/group/group_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
|
import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
|
||||||
|
|
@ -21,6 +22,7 @@ import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
|
import 'package:invoiceninja_flutter/redux/ui/pref_state.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/user/user_actions.dart';
|
import 'package:invoiceninja_flutter/redux/user/user_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
|
import 'package:invoiceninja_flutter/redux/vendor/vendor_actions.dart';
|
||||||
|
import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/dialogs.dart';
|
import 'package:invoiceninja_flutter/utils/dialogs.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
|
|
||||||
|
|
@ -662,49 +664,80 @@ void editEntityById(
|
||||||
Completer completer}) {
|
Completer completer}) {
|
||||||
final store = StoreProvider.of<AppState>(context);
|
final store = StoreProvider.of<AppState>(context);
|
||||||
final navigator = Navigator.of(context);
|
final navigator = Navigator.of(context);
|
||||||
|
final localization = AppLocalization.of(context);
|
||||||
final map = store.state.getEntityMap(entityType);
|
final map = store.state.getEntityMap(entityType);
|
||||||
|
final entity = map[entityId] as BaseEntity;
|
||||||
|
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
case EntityType.client:
|
case EntityType.client:
|
||||||
store.dispatch(EditClient(
|
store.dispatch(
|
||||||
|
EditClient(
|
||||||
client: map[entityId],
|
client: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
));
|
snackBarCompleter<ClientEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdClient
|
||||||
|
: localization.updatedClient)),
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case EntityType.user:
|
case EntityType.user:
|
||||||
store.dispatch(EditUser(
|
store.dispatch(
|
||||||
|
EditUser(
|
||||||
user: map[entityId],
|
user: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
));
|
snackBarCompleter<UserEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdUser
|
||||||
|
: localization.updatedUser)),
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case EntityType.project:
|
case EntityType.project:
|
||||||
store.dispatch(EditProject(
|
store.dispatch(EditProject(
|
||||||
project: map[entityId],
|
project: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
));
|
snackBarCompleter<ProjectEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdProject
|
||||||
|
: localization.updatedProject)));
|
||||||
break;
|
break;
|
||||||
case EntityType.taxRate:
|
case EntityType.taxRate:
|
||||||
store.dispatch(EditTaxRate(
|
store.dispatch(EditTaxRate(
|
||||||
taxRate: map[entityId],
|
taxRate: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
));
|
snackBarCompleter<TaxRateEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdTaxRate
|
||||||
|
: localization.updatedTaxRate)));
|
||||||
break;
|
break;
|
||||||
case EntityType.companyGateway:
|
case EntityType.companyGateway:
|
||||||
store.dispatch(EditCompanyGateway(
|
store.dispatch(EditCompanyGateway(
|
||||||
companyGateway: map[entityId],
|
companyGateway: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
));
|
snackBarCompleter<CompanyGatewayEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdCompanyGateway
|
||||||
|
: localization.updatedCompanyGateway)));
|
||||||
break;
|
break;
|
||||||
case EntityType.invoice:
|
case EntityType.invoice:
|
||||||
store.dispatch(EditInvoice(
|
store.dispatch(EditInvoice(
|
||||||
invoice: map[entityId],
|
invoice: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
|
snackBarCompleter<InvoiceEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdInvoice
|
||||||
|
: localization.updatedInvoice),
|
||||||
invoiceItemIndex: subIndex,
|
invoiceItemIndex: subIndex,
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
|
|
@ -715,7 +748,12 @@ void editEntityById(
|
||||||
store.dispatch(EditQuote(
|
store.dispatch(EditQuote(
|
||||||
quote: map[entityId],
|
quote: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
|
snackBarCompleter<InvoiceEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdQuote
|
||||||
|
: localization.updatedQuote),
|
||||||
quoteItemIndex: subIndex,
|
quoteItemIndex: subIndex,
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
|
|
@ -723,28 +761,47 @@ void editEntityById(
|
||||||
store.dispatch(EditVendor(
|
store.dispatch(EditVendor(
|
||||||
vendor: map[entityId],
|
vendor: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
|
snackBarCompleter<VendorEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdVendor
|
||||||
|
: localization.updatedVendor),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
case EntityType.product:
|
case EntityType.product:
|
||||||
store.dispatch(EditProduct(
|
store.dispatch(EditProduct(
|
||||||
product: map[entityId],
|
product: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
));
|
snackBarCompleter<ProductEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdProduct
|
||||||
|
: localization.updatedProduct)));
|
||||||
break;
|
break;
|
||||||
case EntityType.task:
|
case EntityType.task:
|
||||||
store.dispatch(EditTask(
|
store.dispatch(EditTask(
|
||||||
task: map[entityId],
|
task: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
|
snackBarCompleter<TaskEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdTask
|
||||||
|
: localization.updatedTask),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
case EntityType.expense:
|
case EntityType.expense:
|
||||||
store.dispatch(EditExpense(
|
store.dispatch(EditExpense(
|
||||||
expense: map[entityId],
|
expense: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
|
snackBarCompleter<ExpenseEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdExpense
|
||||||
|
: localization.updatedExpense),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
//case EntityType.expenseCategory:
|
//case EntityType.expenseCategory:
|
||||||
|
|
@ -757,14 +814,24 @@ void editEntityById(
|
||||||
store.dispatch(EditPayment(
|
store.dispatch(EditPayment(
|
||||||
payment: map[entityId],
|
payment: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
|
snackBarCompleter<PaymentEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdPayment
|
||||||
|
: localization.updatedPayment),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
case EntityType.group:
|
case EntityType.group:
|
||||||
store.dispatch(EditGroup(
|
store.dispatch(EditGroup(
|
||||||
group: map[entityId],
|
group: map[entityId],
|
||||||
navigator: navigator,
|
navigator: navigator,
|
||||||
completer: completer,
|
completer: completer ??
|
||||||
|
snackBarCompleter<GroupEntity>(
|
||||||
|
context,
|
||||||
|
entity.isNew
|
||||||
|
? localization.createdGroup
|
||||||
|
: localization.updatedGroup),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
// TODO Add to starter
|
// TODO Add to starter
|
||||||
|
|
@ -782,3 +849,59 @@ void editEntity(
|
||||||
entityType: entity.entityType,
|
entityType: entity.entityType,
|
||||||
subIndex: subIndex,
|
subIndex: subIndex,
|
||||||
completer: completer);
|
completer: completer);
|
||||||
|
|
||||||
|
void handleEntityAction(
|
||||||
|
BuildContext context, BaseEntity entity, dynamic action) {
|
||||||
|
handleEntitiesActions(context, [entity], action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleEntitiesActions(
|
||||||
|
BuildContext context, List<BaseEntity> entities, dynamic action) {
|
||||||
|
if (entities.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (entities.first.entityType) {
|
||||||
|
case EntityType.client:
|
||||||
|
handleClientAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.product:
|
||||||
|
handleProductAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.invoice:
|
||||||
|
handleInvoiceAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.payment:
|
||||||
|
handlePaymentAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.quote:
|
||||||
|
handleQuoteAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.task:
|
||||||
|
handleTaskAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.project:
|
||||||
|
handleProjectAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.expense:
|
||||||
|
handleExpenseAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.vendor:
|
||||||
|
handleVendorAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.user:
|
||||||
|
handleUserAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.companyGateway:
|
||||||
|
handleCompanyGatewayAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.taxRate:
|
||||||
|
handleTaxRateAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.group:
|
||||||
|
handleGroupAction(context, entities, action);
|
||||||
|
break;
|
||||||
|
case EntityType.document:
|
||||||
|
handleDocumentAction(context, entities, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||||
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/app/actions_menu_button.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||||
|
import 'buttons/edit_icon_button.dart';
|
||||||
import 'entities/entity_state_title.dart';
|
import 'entities/entity_state_title.dart';
|
||||||
|
|
||||||
class ViewScaffold extends StatelessWidget {
|
class ViewScaffold extends StatelessWidget {
|
||||||
|
|
@ -19,6 +23,10 @@ class ViewScaffold extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final store = StoreProvider.of<AppState>(context);
|
||||||
|
final state = store.state;
|
||||||
|
final userCompany = state.userCompany;
|
||||||
|
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -28,6 +36,24 @@ class ViewScaffold extends StatelessWidget {
|
||||||
automaticallyImplyLeading: isMobile(context),
|
automaticallyImplyLeading: isMobile(context),
|
||||||
title: EntityStateTitle(entity: entity),
|
title: EntityStateTitle(entity: entity),
|
||||||
bottom: appBarBottom,
|
bottom: appBarBottom,
|
||||||
|
actions: entity.isNew
|
||||||
|
? []
|
||||||
|
: [
|
||||||
|
userCompany.canEditEntity(entity)
|
||||||
|
? EditIconButton(
|
||||||
|
isVisible: !entity.isDeleted,
|
||||||
|
onPressed: () =>
|
||||||
|
editEntity(context: context, entity: entity),
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
ActionMenuButton(
|
||||||
|
isSaving: state.isSaving,
|
||||||
|
entity: entity,
|
||||||
|
onSelected: (context, action) =>
|
||||||
|
handleEntityAction(context, entity, action),
|
||||||
|
entityActions: entity.getActions(userCompany: userCompany),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: body,
|
body: body,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import 'package:invoiceninja_flutter/data/models/models.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
|
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
|
|
||||||
import 'package:invoiceninja_flutter/ui/client/client_screen.dart';
|
|
||||||
import 'package:invoiceninja_flutter/ui/client/view/client_view.dart';
|
import 'package:invoiceninja_flutter/ui/client/view/client_view.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/completers.dart';
|
import 'package:invoiceninja_flutter/utils/completers.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ class CompanyGatewayEditVM {
|
||||||
@required this.origCompanyGateway,
|
@required this.origCompanyGateway,
|
||||||
@required this.onSavePressed,
|
@required this.onSavePressed,
|
||||||
@required this.onCancelPressed,
|
@required this.onCancelPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.isLoading,
|
@required this.isLoading,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -64,13 +63,6 @@ class CompanyGatewayEditVM {
|
||||||
onChanged: (CompanyGatewayEntity companyGateway) {
|
onChanged: (CompanyGatewayEntity companyGateway) {
|
||||||
store.dispatch(UpdateCompanyGateway(companyGateway));
|
store.dispatch(UpdateCompanyGateway(companyGateway));
|
||||||
},
|
},
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(CompanyGatewayScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(companyGateway.isNew
|
|
||||||
? CompanyGatewayScreen.route
|
|
||||||
: CompanyGatewayViewScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCancelPressed: (BuildContext context) {
|
onCancelPressed: (BuildContext context) {
|
||||||
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
||||||
},
|
},
|
||||||
|
|
@ -111,7 +103,6 @@ class CompanyGatewayEditVM {
|
||||||
final Function(CompanyGatewayEntity) onChanged;
|
final Function(CompanyGatewayEntity) onChanged;
|
||||||
final Function(BuildContext) onSavePressed;
|
final Function(BuildContext) onSavePressed;
|
||||||
final Function(BuildContext) onCancelPressed;
|
final Function(BuildContext) onCancelPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
final bool isSaving;
|
final bool isSaving;
|
||||||
final CompanyGatewayEntity origCompanyGateway;
|
final CompanyGatewayEntity origCompanyGateway;
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,12 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/document/document_selectors.dart';
|
import 'package:invoiceninja_flutter/redux/document/document_selectors.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/actions_menu_button.dart';
|
import 'package:invoiceninja_flutter/ui/app/view_scaffold.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/buttons/edit_icon_button.dart';
|
|
||||||
import 'package:invoiceninja_flutter/ui/app/entities/entity_state_title.dart';
|
|
||||||
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_details.dart';
|
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_details.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_documents.dart';
|
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_documents.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_vm.dart';
|
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_vm.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_overview.dart';
|
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_overview.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
|
||||||
|
|
||||||
class ExpenseView extends StatefulWidget {
|
class ExpenseView extends StatefulWidget {
|
||||||
const ExpenseView({
|
const ExpenseView({
|
||||||
|
|
@ -45,20 +42,46 @@ class _ExpenseViewState extends State<ExpenseView>
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
final viewModel = widget.viewModel;
|
final viewModel = widget.viewModel;
|
||||||
final company = viewModel.state.company;
|
final company = viewModel.state.company;
|
||||||
|
final expense = viewModel.expense;
|
||||||
|
final documentState = viewModel.state.documentState;
|
||||||
|
final documents =
|
||||||
|
memoizedExpenseDocumentsSelector(documentState.map, viewModel.expense);
|
||||||
|
|
||||||
return WillPopScope(
|
return ViewScaffold(
|
||||||
onWillPop: () async {
|
entity: expense,
|
||||||
viewModel.onBackPressed();
|
appBarBottom: TabBar(
|
||||||
return true;
|
|
||||||
},
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: _CustomAppBar(
|
|
||||||
viewModel: viewModel,
|
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
|
tabs: [
|
||||||
|
Tab(
|
||||||
|
text: localization.overview,
|
||||||
),
|
),
|
||||||
body: CustomTabBarView(
|
Tab(
|
||||||
viewModel: viewModel,
|
text: localization.details,
|
||||||
|
),
|
||||||
|
Tab(
|
||||||
|
text: documents.isEmpty
|
||||||
|
? localization.documents
|
||||||
|
: '${localization.documents} (${documents.length})',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: TabBarView(
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
|
children: <Widget>[
|
||||||
|
RefreshIndicator(
|
||||||
|
onRefresh: () => viewModel.onRefreshed(context),
|
||||||
|
child: ExpenseOverview(viewModel: viewModel),
|
||||||
|
),
|
||||||
|
RefreshIndicator(
|
||||||
|
onRefresh: () => viewModel.onRefreshed(context),
|
||||||
|
child: ExpenseViewDetails(expense: viewModel.expense),
|
||||||
|
),
|
||||||
|
RefreshIndicator(
|
||||||
|
onRefresh: () => viewModel.onRefreshed(context),
|
||||||
|
child: ExpenseViewDocuments(
|
||||||
|
viewModel: viewModel, expense: viewModel.expense),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
floatingActionButton: company.isEnterprisePlan
|
floatingActionButton: company.isEnterprisePlan
|
||||||
? Builder(builder: (BuildContext context) {
|
? Builder(builder: (BuildContext context) {
|
||||||
|
|
@ -80,112 +103,6 @@ class _ExpenseViewState extends State<ExpenseView>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
: null,
|
: null,
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CustomTabBarView extends StatefulWidget {
|
|
||||||
const CustomTabBarView({
|
|
||||||
@required this.viewModel,
|
|
||||||
@required this.controller,
|
|
||||||
});
|
|
||||||
|
|
||||||
final ExpenseViewVM viewModel;
|
|
||||||
final TabController controller;
|
|
||||||
|
|
||||||
@override
|
|
||||||
_CustomTabBarViewState createState() => _CustomTabBarViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CustomTabBarViewState extends State<CustomTabBarView> {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final viewModel = widget.viewModel;
|
|
||||||
|
|
||||||
return TabBarView(
|
|
||||||
controller: widget.controller,
|
|
||||||
children: <Widget>[
|
|
||||||
RefreshIndicator(
|
|
||||||
onRefresh: () => viewModel.onRefreshed(context),
|
|
||||||
child: ExpenseOverview(viewModel: viewModel),
|
|
||||||
),
|
|
||||||
RefreshIndicator(
|
|
||||||
onRefresh: () => viewModel.onRefreshed(context),
|
|
||||||
child: ExpenseViewDetails(expense: viewModel.expense),
|
|
||||||
),
|
|
||||||
RefreshIndicator(
|
|
||||||
onRefresh: () => viewModel.onRefreshed(context),
|
|
||||||
child: ExpenseViewDocuments(
|
|
||||||
viewModel: viewModel, expense: viewModel.expense),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|
||||||
const _CustomAppBar({
|
|
||||||
@required this.viewModel,
|
|
||||||
@required this.controller,
|
|
||||||
});
|
|
||||||
|
|
||||||
final ExpenseViewVM viewModel;
|
|
||||||
final TabController controller;
|
|
||||||
|
|
||||||
@override
|
|
||||||
final Size preferredSize = const Size(double.infinity, kToolbarHeight * 2);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final localization = AppLocalization.of(context);
|
|
||||||
final expense = viewModel.expense;
|
|
||||||
final userCompany = viewModel.state.userCompany;
|
|
||||||
final documentState = viewModel.state.documentState;
|
|
||||||
final documents =
|
|
||||||
memoizedExpenseDocumentsSelector(documentState.map, viewModel.expense);
|
|
||||||
|
|
||||||
return AppBar(
|
|
||||||
automaticallyImplyLeading: isMobile(context),
|
|
||||||
title: EntityStateTitle(
|
|
||||||
entity: expense,
|
|
||||||
title: expense.publicNotes.isNotEmpty
|
|
||||||
? expense.publicNotes
|
|
||||||
: localization.expense,
|
|
||||||
),
|
|
||||||
bottom: TabBar(
|
|
||||||
controller: controller,
|
|
||||||
tabs: [
|
|
||||||
Tab(
|
|
||||||
text: localization.overview,
|
|
||||||
),
|
|
||||||
Tab(
|
|
||||||
text: localization.details,
|
|
||||||
),
|
|
||||||
Tab(
|
|
||||||
text: documents.isEmpty
|
|
||||||
? localization.documents
|
|
||||||
: '${localization.documents} (${documents.length})',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
actions: expense.isNew
|
|
||||||
? []
|
|
||||||
: [
|
|
||||||
userCompany.canEditEntity(expense)
|
|
||||||
? EditIconButton(
|
|
||||||
isVisible: !expense.isDeleted,
|
|
||||||
onPressed: () => viewModel.onEditPressed(context),
|
|
||||||
)
|
|
||||||
: Container(),
|
|
||||||
ActionMenuButton(
|
|
||||||
isSaving: viewModel.isSaving,
|
|
||||||
entity: expense,
|
|
||||||
onSelected: viewModel.onEntityAction,
|
|
||||||
entityActions:
|
|
||||||
viewModel.expense.getActions(userCompany: userCompany),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +46,6 @@ class ExpenseViewVM {
|
||||||
@required this.onEntityAction,
|
@required this.onEntityAction,
|
||||||
@required this.onEntityPressed,
|
@required this.onEntityPressed,
|
||||||
@required this.onEditPressed,
|
@required this.onEditPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.onRefreshed,
|
@required this.onRefreshed,
|
||||||
@required this.onUploadDocument,
|
@required this.onUploadDocument,
|
||||||
@required this.onDeleteDocument,
|
@required this.onDeleteDocument,
|
||||||
|
|
@ -85,11 +84,6 @@ class ExpenseViewVM {
|
||||||
context, AppLocalization.of(context).updatedExpense));
|
context, AppLocalization.of(context).updatedExpense));
|
||||||
},
|
},
|
||||||
onRefreshed: (context) => _handleRefresh(context),
|
onRefreshed: (context) => _handleRefresh(context),
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(ExpenseScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(ExpenseScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onEntityPressed: (BuildContext context, EntityType entityType,
|
onEntityPressed: (BuildContext context, EntityType entityType,
|
||||||
[longPress = false]) {
|
[longPress = false]) {
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
|
|
@ -157,7 +151,6 @@ class ExpenseViewVM {
|
||||||
final Function(BuildContext, EntityAction) onEntityAction;
|
final Function(BuildContext, EntityAction) onEntityAction;
|
||||||
final Function(BuildContext, EntityType, [bool]) onEntityPressed;
|
final Function(BuildContext, EntityType, [bool]) onEntityPressed;
|
||||||
final Function(BuildContext) onEditPressed;
|
final Function(BuildContext) onEditPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final Function(BuildContext) onRefreshed;
|
final Function(BuildContext) onRefreshed;
|
||||||
final Function(BuildContext, String) onUploadDocument;
|
final Function(BuildContext, String) onUploadDocument;
|
||||||
final Function(BuildContext, DocumentEntity) onDeleteDocument;
|
final Function(BuildContext, DocumentEntity) onDeleteDocument;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/app/edit_scaffold.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
|
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/group/edit/group_edit_vm.dart';
|
import 'package:invoiceninja_flutter/ui/group/edit/group_edit_vm.dart';
|
||||||
|
|
@ -79,44 +80,19 @@ class _GroupEditState extends State<GroupEdit> {
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
final group = viewModel.group;
|
final group = viewModel.group;
|
||||||
|
|
||||||
return WillPopScope(
|
return EditScaffold(
|
||||||
onWillPop: () async {
|
onCancelPressed: (context) => viewModel.onCancelPressed(context),
|
||||||
viewModel.onBackPressed();
|
title: group.isNew ? localization.newGroup : localization.editGroup,
|
||||||
return true;
|
onSavePressed: (context) {
|
||||||
},
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
automaticallyImplyLeading: isMobile(context),
|
|
||||||
title: Text(viewModel.group.isNew
|
|
||||||
? localization.newGroup
|
|
||||||
: localization.editGroup),
|
|
||||||
actions: <Widget>[
|
|
||||||
if (!isMobile(context))
|
|
||||||
FlatButton(
|
|
||||||
child: Text(
|
|
||||||
localization.cancel,
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
onPressed: () => viewModel.onCancelPressed(context),
|
|
||||||
),
|
|
||||||
ActionFlatButton(
|
|
||||||
tooltip: localization.save,
|
|
||||||
isVisible: !(group.isDeleted ?? false),
|
|
||||||
// TODO remove this
|
|
||||||
isDirty: group.isNew || group != viewModel.origGroup,
|
|
||||||
isSaving: viewModel.isSaving,
|
|
||||||
onPressed: () {
|
|
||||||
if (!_formKey.currentState.validate()) {
|
if (!_formKey.currentState.validate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
viewModel.onSavePressed(context);
|
viewModel.onSavePressed(context);
|
||||||
},
|
},
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: Form(
|
body: Form(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: Builder(builder: (BuildContext context) {
|
child: Builder(
|
||||||
|
builder: (BuildContext context) {
|
||||||
return ListView(
|
return ListView(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
FormCard(
|
FormCard(
|
||||||
|
|
@ -129,7 +105,8 @@ class _GroupEditState extends State<GroupEdit> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
})),
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ class GroupEditVM {
|
||||||
@required this.origGroup,
|
@required this.origGroup,
|
||||||
@required this.onSavePressed,
|
@required this.onSavePressed,
|
||||||
@required this.onCancelPressed,
|
@required this.onCancelPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.isLoading,
|
@required this.isLoading,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -64,12 +63,6 @@ class GroupEditVM {
|
||||||
onChanged: (GroupEntity group) {
|
onChanged: (GroupEntity group) {
|
||||||
store.dispatch(UpdateGroup(group));
|
store.dispatch(UpdateGroup(group));
|
||||||
},
|
},
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(GroupSettingsScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(
|
|
||||||
group.isNew ? GroupSettingsScreen.route : GroupViewScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCancelPressed: (BuildContext context) {
|
onCancelPressed: (BuildContext context) {
|
||||||
createEntity(context: context, entity: GroupEntity(), force: true);
|
createEntity(context: context, entity: GroupEntity(), force: true);
|
||||||
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
||||||
|
|
@ -104,7 +97,6 @@ class GroupEditVM {
|
||||||
final Function(GroupEntity) onChanged;
|
final Function(GroupEntity) onChanged;
|
||||||
final Function(BuildContext) onSavePressed;
|
final Function(BuildContext) onSavePressed;
|
||||||
final Function(BuildContext) onCancelPressed;
|
final Function(BuildContext) onCancelPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
final bool isSaving;
|
final bool isSaving;
|
||||||
final GroupEntity origGroup;
|
final GroupEntity origGroup;
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ class EntityViewVM {
|
||||||
@required this.onUploadDocument,
|
@required this.onUploadDocument,
|
||||||
@required this.onDeleteDocument,
|
@required this.onDeleteDocument,
|
||||||
@required this.onEditPressed,
|
@required this.onEditPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.onClientPressed,
|
@required this.onClientPressed,
|
||||||
@required this.onPaymentsPressed,
|
@required this.onPaymentsPressed,
|
||||||
@required this.onPaymentPressed,
|
@required this.onPaymentPressed,
|
||||||
|
|
@ -70,7 +69,6 @@ class EntityViewVM {
|
||||||
final Function(BuildContext) onPaymentsPressed;
|
final Function(BuildContext) onPaymentsPressed;
|
||||||
final Function(BuildContext, PaymentEntity, [bool]) onPaymentPressed;
|
final Function(BuildContext, PaymentEntity, [bool]) onPaymentPressed;
|
||||||
final Function(BuildContext) onRefreshed;
|
final Function(BuildContext) onRefreshed;
|
||||||
final Function onBackPressed;
|
|
||||||
final Function(BuildContext, String) onUploadDocument;
|
final Function(BuildContext, String) onUploadDocument;
|
||||||
final Function(BuildContext, DocumentEntity) onDeleteDocument;
|
final Function(BuildContext, DocumentEntity) onDeleteDocument;
|
||||||
final Function(BuildContext, DocumentEntity) onViewExpense;
|
final Function(BuildContext, DocumentEntity) onViewExpense;
|
||||||
|
|
@ -90,7 +88,6 @@ class InvoiceViewVM extends EntityViewVM {
|
||||||
Function(BuildContext, PaymentEntity, [bool]) onPaymentPressed,
|
Function(BuildContext, PaymentEntity, [bool]) onPaymentPressed,
|
||||||
Function(BuildContext) onPaymentsPressed,
|
Function(BuildContext) onPaymentsPressed,
|
||||||
Function(BuildContext) onRefreshed,
|
Function(BuildContext) onRefreshed,
|
||||||
Function onBackPressed,
|
|
||||||
Function(BuildContext, String) onUploadDocument,
|
Function(BuildContext, String) onUploadDocument,
|
||||||
Function(BuildContext, DocumentEntity) onDeleteDocument,
|
Function(BuildContext, DocumentEntity) onDeleteDocument,
|
||||||
Function(BuildContext, DocumentEntity) onViewExpense,
|
Function(BuildContext, DocumentEntity) onViewExpense,
|
||||||
|
|
@ -107,7 +104,6 @@ class InvoiceViewVM extends EntityViewVM {
|
||||||
onPaymentPressed: onPaymentPressed,
|
onPaymentPressed: onPaymentPressed,
|
||||||
onPaymentsPressed: onPaymentsPressed,
|
onPaymentsPressed: onPaymentsPressed,
|
||||||
onRefreshed: onRefreshed,
|
onRefreshed: onRefreshed,
|
||||||
onBackPressed: onBackPressed,
|
|
||||||
onUploadDocument: onUploadDocument,
|
onUploadDocument: onUploadDocument,
|
||||||
onDeleteDocument: onDeleteDocument,
|
onDeleteDocument: onDeleteDocument,
|
||||||
onViewExpense: onViewExpense);
|
onViewExpense: onViewExpense);
|
||||||
|
|
@ -140,11 +136,6 @@ class InvoiceViewVM extends EntityViewVM {
|
||||||
context, AppLocalization.of(context).updatedInvoice));
|
context, AppLocalization.of(context).updatedInvoice));
|
||||||
},
|
},
|
||||||
onRefreshed: (context) => _handleRefresh(context),
|
onRefreshed: (context) => _handleRefresh(context),
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(InvoiceScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(InvoiceScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onClientPressed: (BuildContext context, [bool longPress = false]) {
|
onClientPressed: (BuildContext context, [bool longPress = false]) {
|
||||||
if (longPress) {
|
if (longPress) {
|
||||||
showEntityActionsDialog(
|
showEntityActionsDialog(
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ class ProductViewVM {
|
||||||
@required this.company,
|
@required this.company,
|
||||||
@required this.onEntityAction,
|
@required this.onEntityAction,
|
||||||
@required this.onEditPressed,
|
@required this.onEditPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.isSaving,
|
@required this.isSaving,
|
||||||
@required this.isLoading,
|
@required this.isLoading,
|
||||||
@required this.isDirty,
|
@required this.isDirty,
|
||||||
|
|
@ -83,11 +82,6 @@ class ProductViewVM {
|
||||||
onRefreshed: (context, loadActivities) =>
|
onRefreshed: (context, loadActivities) =>
|
||||||
_handleRefresh(context, loadActivities),
|
_handleRefresh(context, loadActivities),
|
||||||
*/
|
*/
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(ProductScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(ProductScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onEntityAction: (BuildContext context, EntityAction action) =>
|
onEntityAction: (BuildContext context, EntityAction action) =>
|
||||||
handleProductAction(context, [product], action),
|
handleProductAction(context, [product], action),
|
||||||
);
|
);
|
||||||
|
|
@ -98,7 +92,6 @@ class ProductViewVM {
|
||||||
final CompanyEntity company;
|
final CompanyEntity company;
|
||||||
final Function(BuildContext, EntityAction) onEntityAction;
|
final Function(BuildContext, EntityAction) onEntityAction;
|
||||||
final Function(BuildContext) onEditPressed;
|
final Function(BuildContext) onEditPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final Function(BuildContext, bool) onRefreshed;
|
final Function(BuildContext, bool) onRefreshed;
|
||||||
final bool isSaving;
|
final bool isSaving;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ class ProjectViewVM {
|
||||||
@required this.onEntityAction,
|
@required this.onEntityAction,
|
||||||
@required this.onTasksPressed,
|
@required this.onTasksPressed,
|
||||||
@required this.onEditPressed,
|
@required this.onEditPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.onAddTaskPressed,
|
@required this.onAddTaskPressed,
|
||||||
@required this.onClientPressed,
|
@required this.onClientPressed,
|
||||||
@required this.onRefreshed,
|
@required this.onRefreshed,
|
||||||
|
|
@ -113,11 +112,6 @@ class ProjectViewVM {
|
||||||
..clientId = project.clientId),
|
..clientId = project.clientId),
|
||||||
force: true);
|
force: true);
|
||||||
},
|
},
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(ProjectScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(ProjectScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onEntityAction: (BuildContext context, EntityAction action) =>
|
onEntityAction: (BuildContext context, EntityAction action) =>
|
||||||
handleProjectAction(context, [project], action),
|
handleProjectAction(context, [project], action),
|
||||||
);
|
);
|
||||||
|
|
@ -130,7 +124,6 @@ class ProjectViewVM {
|
||||||
final Function(BuildContext, EntityAction) onEntityAction;
|
final Function(BuildContext, EntityAction) onEntityAction;
|
||||||
final Function(BuildContext) onEditPressed;
|
final Function(BuildContext) onEditPressed;
|
||||||
final Function(BuildContext, [bool]) onClientPressed;
|
final Function(BuildContext, [bool]) onClientPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final Function(BuildContext) onAddTaskPressed;
|
final Function(BuildContext) onAddTaskPressed;
|
||||||
final Function(BuildContext, {bool longPress}) onTasksPressed;
|
final Function(BuildContext, {bool longPress}) onTasksPressed;
|
||||||
final Function(BuildContext) onRefreshed;
|
final Function(BuildContext) onRefreshed;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ class QuoteViewVM extends EntityViewVM {
|
||||||
Function(BuildContext) onPaymentsPressed,
|
Function(BuildContext) onPaymentsPressed,
|
||||||
Function(BuildContext, PaymentEntity) onPaymentPressed,
|
Function(BuildContext, PaymentEntity) onPaymentPressed,
|
||||||
Function(BuildContext) onRefreshed,
|
Function(BuildContext) onRefreshed,
|
||||||
Function onBackPressed,
|
|
||||||
Function(BuildContext, String) onUploadDocument,
|
Function(BuildContext, String) onUploadDocument,
|
||||||
Function(BuildContext, DocumentEntity) onDeleteDocument,
|
Function(BuildContext, DocumentEntity) onDeleteDocument,
|
||||||
Function(BuildContext, DocumentEntity) onViewExpense,
|
Function(BuildContext, DocumentEntity) onViewExpense,
|
||||||
|
|
@ -71,7 +70,6 @@ class QuoteViewVM extends EntityViewVM {
|
||||||
onPaymentsPressed: onPaymentsPressed,
|
onPaymentsPressed: onPaymentsPressed,
|
||||||
onPaymentPressed: onPaymentPressed,
|
onPaymentPressed: onPaymentPressed,
|
||||||
onRefreshed: onRefreshed,
|
onRefreshed: onRefreshed,
|
||||||
onBackPressed: onBackPressed,
|
|
||||||
onUploadDocument: onUploadDocument,
|
onUploadDocument: onUploadDocument,
|
||||||
onDeleteDocument: onDeleteDocument,
|
onDeleteDocument: onDeleteDocument,
|
||||||
onViewExpense: onViewExpense,
|
onViewExpense: onViewExpense,
|
||||||
|
|
@ -107,11 +105,6 @@ class QuoteViewVM extends EntityViewVM {
|
||||||
context, AppLocalization.of(context).updatedQuote));
|
context, AppLocalization.of(context).updatedQuote));
|
||||||
},
|
},
|
||||||
onRefreshed: (context) => _handleRefresh(context),
|
onRefreshed: (context) => _handleRefresh(context),
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(QuoteScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(QuoteScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onClientPressed: (BuildContext context, [bool longPress = false]) {
|
onClientPressed: (BuildContext context, [bool longPress = false]) {
|
||||||
if (longPress) {
|
if (longPress) {
|
||||||
showEntityActionsDialog(
|
showEntityActionsDialog(
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ class TaskViewVM {
|
||||||
@required this.state,
|
@required this.state,
|
||||||
@required this.onEntityAction,
|
@required this.onEntityAction,
|
||||||
@required this.onEditPressed,
|
@required this.onEditPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.onRefreshed,
|
@required this.onRefreshed,
|
||||||
@required this.onClientPressed,
|
@required this.onClientPressed,
|
||||||
@required this.onProjectPressed,
|
@required this.onProjectPressed,
|
||||||
|
|
@ -157,11 +156,6 @@ class TaskViewVM {
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
onRefreshed: (context) => _handleRefresh(context),
|
onRefreshed: (context) => _handleRefresh(context),
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(TaskScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(TaskScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onEntityAction: (BuildContext context, EntityAction action) =>
|
onEntityAction: (BuildContext context, EntityAction action) =>
|
||||||
handleTaskAction(context, [task], action),
|
handleTaskAction(context, [task], action),
|
||||||
);
|
);
|
||||||
|
|
@ -174,7 +168,6 @@ class TaskViewVM {
|
||||||
final CompanyEntity company;
|
final CompanyEntity company;
|
||||||
final Function(BuildContext, EntityAction) onEntityAction;
|
final Function(BuildContext, EntityAction) onEntityAction;
|
||||||
final Function(BuildContext, [TaskTime]) onEditPressed;
|
final Function(BuildContext, [TaskTime]) onEditPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final Function(BuildContext) onFabPressed;
|
final Function(BuildContext) onFabPressed;
|
||||||
final Function(BuildContext) onRefreshed;
|
final Function(BuildContext) onRefreshed;
|
||||||
final Function(BuildContext, [bool]) onClientPressed;
|
final Function(BuildContext, [bool]) onClientPressed;
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ class TaxRateEditVM {
|
||||||
@required this.origTaxRate,
|
@required this.origTaxRate,
|
||||||
@required this.onSavePressed,
|
@required this.onSavePressed,
|
||||||
@required this.onCancelPressed,
|
@required this.onCancelPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.isLoading,
|
@required this.isLoading,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -68,13 +67,6 @@ class TaxRateEditVM {
|
||||||
createEntity(context: context, entity: TaxRateEntity(), force: true);
|
createEntity(context: context, entity: TaxRateEntity(), force: true);
|
||||||
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
||||||
},
|
},
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(TaxRateSettingsScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(taxRate.isNew
|
|
||||||
? TaxRateSettingsScreen.route
|
|
||||||
: TaxRateViewScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSavePressed: (BuildContext context) {
|
onSavePressed: (BuildContext context) {
|
||||||
final Completer<TaxRateEntity> completer =
|
final Completer<TaxRateEntity> completer =
|
||||||
new Completer<TaxRateEntity>();
|
new Completer<TaxRateEntity>();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:invoiceninja_flutter/constants.dart';
|
import 'package:invoiceninja_flutter/constants.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/data/models/entities.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/app/edit_scaffold.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/forms/app_form.dart';
|
import 'package:invoiceninja_flutter/ui/app/forms/app_form.dart';
|
||||||
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
|
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
|
||||||
|
|
@ -108,40 +109,16 @@ class _UserEditState extends State<UserEdit> {
|
||||||
final user = viewModel.user;
|
final user = viewModel.user;
|
||||||
final userCompany = user.userCompany;
|
final userCompany = user.userCompany;
|
||||||
|
|
||||||
return WillPopScope(
|
return EditScaffold(
|
||||||
onWillPop: () async {
|
title:
|
||||||
viewModel.onBackPressed();
|
viewModel.user.isNew ? localization.newUser : localization.editUser,
|
||||||
return true;
|
onCancelPressed: (context) => viewModel.onCancelPressed(context),
|
||||||
},
|
onSavePressed: (context) {
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
automaticallyImplyLeading: isMobile(context),
|
|
||||||
title: Text(viewModel.user.isNew
|
|
||||||
? localization.newUser
|
|
||||||
: localization.editUser),
|
|
||||||
actions: <Widget>[
|
|
||||||
if (!isMobile(context))
|
|
||||||
FlatButton(
|
|
||||||
child: Text(
|
|
||||||
localization.cancel,
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
onPressed: () => viewModel.onCancelPressed(context),
|
|
||||||
),
|
|
||||||
ActionFlatButton(
|
|
||||||
tooltip: localization.save,
|
|
||||||
isVisible: user.isActive,
|
|
||||||
isDirty: user.isNew || user != viewModel.origUser,
|
|
||||||
isSaving: viewModel.isSaving,
|
|
||||||
onPressed: () {
|
|
||||||
if (!_formKey.currentState.validate()) {
|
if (!_formKey.currentState.validate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
viewModel.onSavePressed(context);
|
viewModel.onSavePressed(context);
|
||||||
},
|
},
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: AppForm(
|
body: AppForm(
|
||||||
focusNode: _focusNode,
|
focusNode: _focusNode,
|
||||||
formKey: _formKey,
|
formKey: _formKey,
|
||||||
|
|
@ -219,8 +196,7 @@ class _UserEditState extends State<UserEdit> {
|
||||||
onChanged: (value) =>
|
onChanged: (value) =>
|
||||||
_togglePermission(kPermissionCreateAll),
|
_togglePermission(kPermissionCreateAll),
|
||||||
),
|
),
|
||||||
onTap: () =>
|
onTap: () => _togglePermission(kPermissionCreateAll)),
|
||||||
_togglePermission(kPermissionCreateAll)),
|
|
||||||
DataCell(
|
DataCell(
|
||||||
_PermissionCheckbox(
|
_PermissionCheckbox(
|
||||||
userCompany: userCompany,
|
userCompany: userCompany,
|
||||||
|
|
@ -245,8 +221,7 @@ class _UserEditState extends State<UserEdit> {
|
||||||
EntityType.payment,
|
EntityType.payment,
|
||||||
EntityType.quote,
|
EntityType.quote,
|
||||||
].map((EntityType type) {
|
].map((EntityType type) {
|
||||||
final createPermission =
|
final createPermission = 'create_' + toSnakeCase('$type');
|
||||||
'create_' + toSnakeCase('$type');
|
|
||||||
final editPermission = 'edit_' + toSnakeCase('$type');
|
final editPermission = 'edit_' + toSnakeCase('$type');
|
||||||
final viewPermission = 'view_' + toSnakeCase('$type');
|
final viewPermission = 'view_' + toSnakeCase('$type');
|
||||||
return DataRow(cells: [
|
return DataRow(cells: [
|
||||||
|
|
@ -298,7 +273,6 @@ class _UserEditState extends State<UserEdit> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ class UserEditVM {
|
||||||
@required this.origUser,
|
@required this.origUser,
|
||||||
@required this.onSavePressed,
|
@required this.onSavePressed,
|
||||||
@required this.onCancelPressed,
|
@required this.onCancelPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.isLoading,
|
@required this.isLoading,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -66,12 +65,6 @@ class UserEditVM {
|
||||||
onUserChanged: (UserEntity user) {
|
onUserChanged: (UserEntity user) {
|
||||||
store.dispatch(UpdateUser(user));
|
store.dispatch(UpdateUser(user));
|
||||||
},
|
},
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(UserScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(
|
|
||||||
user.isNew ? UserScreen.route : UserViewScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCancelPressed: (BuildContext context) {
|
onCancelPressed: (BuildContext context) {
|
||||||
createEntity(context: context, entity: UserEntity(), force: true);
|
createEntity(context: context, entity: UserEntity(), force: true);
|
||||||
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
|
||||||
|
|
@ -107,7 +100,6 @@ class UserEditVM {
|
||||||
final Function(UserEntity) onUserChanged;
|
final Function(UserEntity) onUserChanged;
|
||||||
final Function(BuildContext) onSavePressed;
|
final Function(BuildContext) onSavePressed;
|
||||||
final Function(BuildContext) onCancelPressed;
|
final Function(BuildContext) onCancelPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
final bool isSaving;
|
final bool isSaving;
|
||||||
final UserEntity origUser;
|
final UserEntity origUser;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ class VendorViewVM {
|
||||||
@required this.onEntityAction,
|
@required this.onEntityAction,
|
||||||
@required this.onEntityPressed,
|
@required this.onEntityPressed,
|
||||||
@required this.onEditPressed,
|
@required this.onEditPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.onRefreshed,
|
@required this.onRefreshed,
|
||||||
@required this.isSaving,
|
@required this.isSaving,
|
||||||
@required this.isLoading,
|
@required this.isLoading,
|
||||||
|
|
@ -77,11 +76,6 @@ class VendorViewVM {
|
||||||
context, AppLocalization.of(context).updatedVendor));
|
context, AppLocalization.of(context).updatedVendor));
|
||||||
},
|
},
|
||||||
onRefreshed: (context) => _handleRefresh(context),
|
onRefreshed: (context) => _handleRefresh(context),
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(VendorScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(VendorScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onEntityPressed: (BuildContext context, EntityType entityType,
|
onEntityPressed: (BuildContext context, EntityType entityType,
|
||||||
[longPress = false]) {
|
[longPress = false]) {
|
||||||
switch (entityType) {
|
switch (entityType) {
|
||||||
|
|
@ -115,7 +109,6 @@ class VendorViewVM {
|
||||||
final Function(BuildContext, EntityAction) onEntityAction;
|
final Function(BuildContext, EntityAction) onEntityAction;
|
||||||
final Function(BuildContext) onEditPressed;
|
final Function(BuildContext) onEditPressed;
|
||||||
final Function(BuildContext, EntityType, [bool]) onEntityPressed;
|
final Function(BuildContext, EntityType, [bool]) onEntityPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final Function(BuildContext) onRefreshed;
|
final Function(BuildContext) onRefreshed;
|
||||||
final Function(BuildContext) onAddExpensePressed;
|
final Function(BuildContext) onAddExpensePressed;
|
||||||
final bool isSaving;
|
final bool isSaving;
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ class StubViewVM {
|
||||||
@required this.company,
|
@required this.company,
|
||||||
@required this.onEntityAction,
|
@required this.onEntityAction,
|
||||||
@required this.onEditPressed,
|
@required this.onEditPressed,
|
||||||
@required this.onBackPressed,
|
|
||||||
@required this.onRefreshed,
|
@required this.onRefreshed,
|
||||||
@required this.isSaving,
|
@required this.isSaving,
|
||||||
@required this.isLoading,
|
@required this.isLoading,
|
||||||
|
|
@ -75,11 +74,6 @@ class StubViewVM {
|
||||||
context, AppLocalization.of(context).updatedStub));
|
context, AppLocalization.of(context).updatedStub));
|
||||||
},
|
},
|
||||||
onRefreshed: (context) => _handleRefresh(context),
|
onRefreshed: (context) => _handleRefresh(context),
|
||||||
onBackPressed: () {
|
|
||||||
if (state.uiState.currentRoute.contains(StubScreen.route)) {
|
|
||||||
store.dispatch(UpdateCurrentRoute(StubScreen.route));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onEntityAction: (BuildContext context, EntityAction action) =>
|
onEntityAction: (BuildContext context, EntityAction action) =>
|
||||||
handleStubAction(context, stub, action),
|
handleStubAction(context, stub, action),
|
||||||
);
|
);
|
||||||
|
|
@ -90,7 +84,6 @@ class StubViewVM {
|
||||||
final CompanyEntity company;
|
final CompanyEntity company;
|
||||||
final Function(BuildContext, EntityAction) onEntityAction;
|
final Function(BuildContext, EntityAction) onEntityAction;
|
||||||
final Function(BuildContext) onEditPressed;
|
final Function(BuildContext) onEditPressed;
|
||||||
final Function onBackPressed;
|
|
||||||
final Function(BuildContext) onRefreshed;
|
final Function(BuildContext) onRefreshed;
|
||||||
final bool isSaving;
|
final bool isSaving;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue