Tablet layout

This commit is contained in:
Hillel Coren 2019-08-19 13:42:08 +03:00
parent efb77a0193
commit cb9da60103
12 changed files with 151 additions and 167 deletions

View File

@ -1,23 +1,28 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.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/dashboard/dashboard_actions.dart'; import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_state.dart';
import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart'; import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'app_drawer_vm.dart'; import 'app_drawer_vm.dart';
class AppScaffold extends StatelessWidget { class AppScaffold extends StatelessWidget {
const AppScaffold( const AppScaffold({@required this.appBarTitle,
{@required this.appBar, @required this.appBarActions,
@required this.body, @required this.body,
@required this.bottomNavigationBar, @required this.bottomNavigationBar,
@required this.floatingActionButton}); @required this.floatingActionButton});
final AppBar appBar;
final Widget body; final Widget body;
final AppBottomBar bottomNavigationBar; final AppBottomBar bottomNavigationBar;
final FloatingActionButton floatingActionButton; final FloatingActionButton floatingActionButton;
final Widget appBarTitle;
final List<Widget> appBarActions;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
@ -29,7 +34,17 @@ class AppScaffold extends StatelessWidget {
}, },
child: Scaffold( child: Scaffold(
drawer: AppDrawerBuilder(), drawer: AppDrawerBuilder(),
appBar: appBar, appBar: AppBar(
leading: !isMobile(context)
? IconButton(
icon: Icon(Icons.menu),
onPressed: () =>
store.dispatch(UpdateSidebar(AppSidebar.menu)),
)
: null,
title: appBarTitle,
actions: appBarActions,
),
body: body, body: body,
bottomNavigationBar: bottomNavigationBar, bottomNavigationBar: bottomNavigationBar,
floatingActionButton: floatingActionButton, floatingActionButton: floatingActionButton,

View File

@ -1,5 +1,3 @@
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_state.dart';
import 'package:invoiceninja_flutter/ui/app/app_scaffold.dart'; import 'package:invoiceninja_flutter/ui/app/app_scaffold.dart';
import 'package:invoiceninja_flutter/ui/app/list_filter.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart'; import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart';
@ -12,7 +10,6 @@ import 'package:invoiceninja_flutter/ui/client/client_list_vm.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart'; import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
class ClientScreen extends StatelessWidget { class ClientScreen extends StatelessWidget {
static const String route = '/client'; static const String route = '/client';
@ -26,29 +23,21 @@ class ClientScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
leading: !isMobile(context) key: ValueKey(state.clientListState.filterClearedAt),
? IconButton( entityType: EntityType.client,
icon: Icon(Icons.menu), onFilterChanged: (value) {
onPressed: () => store.dispatch(UpdateSidebar(AppSidebar.menu)), store.dispatch(FilterClients(value));
) },
: null, ),
title: ListFilter( appBarActions: [
key: ValueKey(state.clientListState.filterClearedAt), ListFilterButton(
entityType: EntityType.client, entityType: EntityType.client,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterClients(value)); store.dispatch(FilterClients(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.client,
onFilterPressed: (String value) {
store.dispatch(FilterClients(value));
},
),
],
),
body: ClientListBuilder(), body: ClientListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.client, entityType: EntityType.client,

View File

@ -22,23 +22,21 @@ class DocumentScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(state.documentListState.filterClearedAt),
key: ValueKey(state.documentListState.filterClearedAt), entityType: EntityType.document,
onFilterChanged: (value) {
store.dispatch(FilterDocuments(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.document, entityType: EntityType.document,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterDocuments(value)); store.dispatch(FilterDocuments(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.document,
onFilterPressed: (String value) {
store.dispatch(FilterDocuments(value));
},
),
],
),
body: DocumentListBuilder(), body: DocumentListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.document, entityType: EntityType.document,

View File

@ -22,23 +22,21 @@ class ExpenseScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(store.state.expenseListState.filterClearedAt),
key: ValueKey(store.state.expenseListState.filterClearedAt), entityType: EntityType.expense,
onFilterChanged: (value) {
store.dispatch(FilterExpenses(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.expense, entityType: EntityType.expense,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterExpenses(value)); store.dispatch(FilterExpenses(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.expense,
onFilterPressed: (String value) {
store.dispatch(FilterExpenses(value));
},
),
],
),
body: ExpenseListBuilder(), body: ExpenseListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.expense, entityType: EntityType.expense,

View File

@ -21,23 +21,21 @@ class InvoiceScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(store.state.invoiceListState.filterClearedAt),
key: ValueKey(store.state.invoiceListState.filterClearedAt), entityType: EntityType.invoice,
onFilterChanged: (value) {
store.dispatch(FilterInvoices(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.invoice, entityType: EntityType.invoice,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterInvoices(value)); store.dispatch(FilterInvoices(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.invoice,
onFilterPressed: (String value) {
store.dispatch(FilterInvoices(value));
},
),
],
),
body: InvoiceListBuilder(), body: InvoiceListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.invoice, entityType: EntityType.invoice,
@ -66,32 +64,32 @@ class InvoiceScreen extends StatelessWidget {
store.dispatch(FilterInvoicesByCustom2(value)), store.dispatch(FilterInvoicesByCustom2(value)),
statuses: [ statuses: [
InvoiceStatusEntity().rebuild( InvoiceStatusEntity().rebuild(
(b) => b (b) => b
..id = 1 ..id = 1
..name = localization.draft, ..name = localization.draft,
), ),
InvoiceStatusEntity().rebuild( InvoiceStatusEntity().rebuild(
(b) => b (b) => b
..id = 2 ..id = 2
..name = localization.sent, ..name = localization.sent,
), ),
InvoiceStatusEntity().rebuild( InvoiceStatusEntity().rebuild(
(b) => b (b) => b
..id = 3 ..id = 3
..name = localization.viewed, ..name = localization.viewed,
), ),
InvoiceStatusEntity().rebuild( InvoiceStatusEntity().rebuild(
(b) => b (b) => b
..id = 5 ..id = 5
..name = localization.partial, ..name = localization.partial,
), ),
InvoiceStatusEntity().rebuild( InvoiceStatusEntity().rebuild(
(b) => b (b) => b
..id = 6 ..id = 6
..name = localization.paid, ..name = localization.paid,
), ),
InvoiceStatusEntity().rebuild( InvoiceStatusEntity().rebuild(
(b) => b (b) => b
..id = -1 ..id = -1
..name = localization.pastDue, ..name = localization.pastDue,
), ),
@ -99,17 +97,17 @@ class InvoiceScreen extends StatelessWidget {
), ),
floatingActionButton: user.canCreate(EntityType.invoice) floatingActionButton: user.canCreate(EntityType.invoice)
? FloatingActionButton( ? FloatingActionButton(
backgroundColor: Theme.of(context).primaryColorDark, backgroundColor: Theme.of(context).primaryColorDark,
onPressed: () { onPressed: () {
store.dispatch(EditInvoice( store.dispatch(EditInvoice(
invoice: InvoiceEntity(company: company).rebuild((b) => b invoice: InvoiceEntity(company: company).rebuild((b) => b
..clientId = ..clientId =
store.state.invoiceListState.filterEntityId ?? 0), store.state.invoiceListState.filterEntityId ?? 0),
context: context)); context: context));
}, },
child: Icon(Icons.add, color: Colors.white), child: Icon(Icons.add, color: Colors.white),
tooltip: localization.newInvoice, tooltip: localization.newInvoice,
) )
: null, : null,
); );
} }

View File

@ -19,23 +19,21 @@ class PaymentScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(store.state.paymentListState.filterClearedAt),
key: ValueKey(store.state.paymentListState.filterClearedAt), entityType: EntityType.payment,
onFilterChanged: (value) {
store.dispatch(FilterPayments(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.payment, entityType: EntityType.payment,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterPayments(value)); store.dispatch(FilterPayments(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.payment,
onFilterPressed: (String value) {
store.dispatch(FilterPayments(value));
},
),
],
),
body: PaymentListBuilder(), body: PaymentListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.payment, entityType: EntityType.payment,

View File

@ -22,23 +22,21 @@ class ProductScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(store.state.productListState.filterClearedAt),
key: ValueKey(store.state.productListState.filterClearedAt), entityType: EntityType.product,
onFilterChanged: (value) {
store.dispatch(FilterProducts(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.product, entityType: EntityType.product,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterProducts(value)); store.dispatch(FilterProducts(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.product,
onFilterPressed: (String value) {
store.dispatch(FilterProducts(value));
},
),
],
),
body: ProductListBuilder(), body: ProductListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.product, entityType: EntityType.product,

View File

@ -21,23 +21,21 @@ class ProjectScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(store.state.projectListState.filterClearedAt),
key: ValueKey(store.state.projectListState.filterClearedAt), entityType: EntityType.project,
onFilterChanged: (value) {
store.dispatch(FilterProjects(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.project, entityType: EntityType.project,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterProjects(value)); store.dispatch(FilterProjects(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.project,
onFilterPressed: (String value) {
store.dispatch(FilterProjects(value));
},
),
],
),
body: ProjectListBuilder(), body: ProjectListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.project, entityType: EntityType.project,

View File

@ -21,23 +21,21 @@ class QuoteScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(store.state.quoteListState.filterClearedAt),
key: ValueKey(store.state.quoteListState.filterClearedAt), entityType: EntityType.quote,
onFilterChanged: (value) {
store.dispatch(FilterQuotes(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.quote, entityType: EntityType.quote,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterQuotes(value)); store.dispatch(FilterQuotes(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.quote,
onFilterPressed: (String value) {
store.dispatch(FilterQuotes(value));
},
),
],
),
body: QuoteListBuilder(), body: QuoteListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.quote, entityType: EntityType.quote,

View File

@ -22,23 +22,21 @@ class TaskScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(store.state.taskListState.filterClearedAt),
key: ValueKey(store.state.taskListState.filterClearedAt), entityType: EntityType.task,
onFilterChanged: (value) {
store.dispatch(FilterTasks(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.task, entityType: EntityType.task,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterTasks(value)); store.dispatch(FilterTasks(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.task,
onFilterPressed: (String value) {
store.dispatch(FilterTasks(value));
},
),
],
),
body: TaskListBuilder(), body: TaskListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.task, entityType: EntityType.task,

View File

@ -21,23 +21,21 @@ class VendorScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter( key: ValueKey(store.state.vendorListState.filterClearedAt),
key: ValueKey(store.state.vendorListState.filterClearedAt), entityType: EntityType.vendor,
onFilterChanged: (value) {
store.dispatch(FilterVendors(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.vendor, entityType: EntityType.vendor,
onFilterChanged: (value) { onFilterPressed: (String value) {
store.dispatch(FilterVendors(value)); store.dispatch(FilterVendors(value));
}, },
), ),
actions: [ ],
ListFilterButton(
entityType: EntityType.vendor,
onFilterPressed: (String value) {
store.dispatch(FilterVendors(value));
},
),
],
),
body: VendorListBuilder(), body: VendorListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.vendor, entityType: EntityType.vendor,

View File

@ -24,15 +24,14 @@ class StubScreen extends StatelessWidget {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
return AppScaffold( return AppScaffold(
appBar: AppBar( appBarTitle: ListFilter(
title: ListFilter(
key: ValueKey(state.stubListState.filterClearedAt), key: ValueKey(state.stubListState.filterClearedAt),
entityType: EntityType.stub, entityType: EntityType.stub,
onFilterChanged: (value) { onFilterChanged: (value) {
store.dispatch(FilterStubs(value)); store.dispatch(FilterStubs(value));
}, },
), ),
actions: [ appBarActions: [
ListFilterButton( ListFilterButton(
entityType: EntityType.stub, entityType: EntityType.stub,
onFilterPressed: (String value) { onFilterPressed: (String value) {
@ -40,7 +39,6 @@ class StubScreen extends StatelessWidget {
}, },
), ),
], ],
),
body: StubListBuilder(), body: StubListBuilder(),
bottomNavigationBar: AppBottomBar( bottomNavigationBar: AppBottomBar(
entityType: EntityType.stub, entityType: EntityType.stub,