Mock data
This commit is contained in:
parent
15bc8ef735
commit
6805d58718
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
// This version must be updated in tandem with the pubspec version.
|
// This version must be updated in tandem with the pubspec version.
|
||||||
const String kAppVersion = '2.0.8';
|
const String kAppVersion = '2.0.13';
|
||||||
const String kSiteUrl = 'https://invoiceninja.com';
|
const String kSiteUrl = 'https://invoiceninja.com';
|
||||||
//const String kAppUrl = 'https://admin.invoiceninja.com';
|
//const String kAppUrl = 'https://admin.invoiceninja.com';
|
||||||
const String kAppUrl = 'https://staging.invoicing.co';
|
const String kAppUrl = 'https://staging.invoicing.co';
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ const dynamic kMockLogin = '''
|
||||||
"late_fee_endless_percent": 0,
|
"late_fee_endless_percent": 0,
|
||||||
"client_online_payment_notification": true,
|
"client_online_payment_notification": true,
|
||||||
"client_manual_payment_notification": true,
|
"client_manual_payment_notification": true,
|
||||||
"name": "",
|
"name": "Test Account",
|
||||||
"company_logo": "",
|
"company_logo": "",
|
||||||
"website": "",
|
"website": "",
|
||||||
"address1": "",
|
"address1": "",
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import 'package:invoiceninja_flutter/ui/app/responsive_padding.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/utils/platforms.dart';
|
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||||
|
import 'package:invoiceninja_flutter/.env.dart';
|
||||||
|
|
||||||
class EntityDropdown extends StatefulWidget {
|
class EntityDropdown extends StatefulWidget {
|
||||||
const EntityDropdown({
|
const EntityDropdown({
|
||||||
|
|
@ -111,7 +112,8 @@ class _EntityDropdownState extends State<EntityDropdown> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (isNotMobile(context)) {
|
// TODO remove DEMO_MODE check
|
||||||
|
if (isNotMobile(context) && !Config.DEMO_MODE) {
|
||||||
return TypeAheadFormField<String>(
|
return TypeAheadFormField<String>(
|
||||||
noItemsFoundBuilder: (context) => SizedBox(),
|
noItemsFoundBuilder: (context) => SizedBox(),
|
||||||
suggestionsBoxDecoration: SuggestionsBoxDecoration(
|
suggestionsBoxDecoration: SuggestionsBoxDecoration(
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ 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/utils/platforms.dart';
|
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||||
import 'package:invoiceninja_flutter/utils/strings.dart';
|
import 'package:invoiceninja_flutter/utils/strings.dart';
|
||||||
|
import 'package:invoiceninja_flutter/.env.dart';
|
||||||
|
|
||||||
class ReportsScreen extends StatelessWidget {
|
class ReportsScreen extends StatelessWidget {
|
||||||
const ReportsScreen({
|
const ReportsScreen({
|
||||||
|
|
@ -69,7 +70,8 @@ class ReportsScreen extends StatelessWidget {
|
||||||
? null
|
? null
|
||||||
: IconButton(
|
: IconButton(
|
||||||
icon: Icon(Icons.menu),
|
icon: Icon(Icons.menu),
|
||||||
onPressed: () => store
|
onPressed: () =>
|
||||||
|
store
|
||||||
.dispatch(UserSettingsChanged(sidebar: AppSidebar.menu)),
|
.dispatch(UserSettingsChanged(sidebar: AppSidebar.menu)),
|
||||||
),
|
),
|
||||||
title: Row(
|
title: Row(
|
||||||
|
|
@ -113,10 +115,12 @@ class ReportsScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
if (isMobile(context) || !state.prefState.isHistoryVisible)
|
if (isMobile(context) || !state.prefState.isHistoryVisible)
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) => IconButton(
|
builder: (context) =>
|
||||||
|
IconButton(
|
||||||
icon: Icon(Icons.menu),
|
icon: Icon(Icons.menu),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (isMobile(context) || state.prefState.isHistoryFloated) {
|
if (isMobile(context) ||
|
||||||
|
state.prefState.isHistoryFloated) {
|
||||||
Scaffold.of(context).openEndDrawer();
|
Scaffold.of(context).openEndDrawer();
|
||||||
} else {
|
} else {
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
|
|
@ -129,7 +133,8 @@ class ReportsScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: ListView(
|
||||||
key: ValueKey(
|
key: ValueKey(
|
||||||
'${viewModel.state.isSaving}_${reportsState.report}_${reportsState.group}'),
|
'${viewModel.state.isSaving}_${reportsState.report}_${reportsState
|
||||||
|
.group}'),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Flex(
|
Flex(
|
||||||
direction: isMobile(context) ? Axis.vertical : Axis.horizontal,
|
direction: isMobile(context) ? Axis.vertical : Axis.horizontal,
|
||||||
|
|
@ -159,7 +164,8 @@ class ReportsScreen extends StatelessWidget {
|
||||||
//kReportTaxRate,
|
//kReportTaxRate,
|
||||||
//kReportQuote,
|
//kReportQuote,
|
||||||
]
|
]
|
||||||
.map((report) => DropdownMenuItem(
|
.map((report) =>
|
||||||
|
DropdownMenuItem(
|
||||||
value: report,
|
value: report,
|
||||||
child: Text(localization.lookup(report)),
|
child: Text(localization.lookup(report)),
|
||||||
))
|
))
|
||||||
|
|
@ -170,7 +176,8 @@ class ReportsScreen extends StatelessWidget {
|
||||||
labelText: localization.startDate,
|
labelText: localization.startDate,
|
||||||
selectedDate: reportsState.customStartDate,
|
selectedDate: reportsState.customStartDate,
|
||||||
allowClearing: true,
|
allowClearing: true,
|
||||||
onSelected: (date) => viewModel.onSettingsChanged(
|
onSelected: (date) =>
|
||||||
|
viewModel.onSettingsChanged(
|
||||||
customStartDate: date),
|
customStartDate: date),
|
||||||
),
|
),
|
||||||
DatePicker(
|
DatePicker(
|
||||||
|
|
@ -254,7 +261,8 @@ class ReportsScreen extends StatelessWidget {
|
||||||
.where((column) =>
|
.where((column) =>
|
||||||
getReportColumnType(column, context) ==
|
getReportColumnType(column, context) ==
|
||||||
ReportColumnType.number)
|
ReportColumnType.number)
|
||||||
.map((column) => DropdownMenuItem(
|
.map((column) =>
|
||||||
|
DropdownMenuItem(
|
||||||
child: Text(localization.lookup(column)),
|
child: Text(localization.lookup(column)),
|
||||||
value: column,
|
value: column,
|
||||||
))
|
))
|
||||||
|
|
@ -267,7 +275,8 @@ class ReportsScreen extends StatelessWidget {
|
||||||
),
|
),
|
||||||
ReportDataTable(
|
ReportDataTable(
|
||||||
key: ValueKey(
|
key: ValueKey(
|
||||||
'${viewModel.state.isSaving}_${reportsState.group}_${reportsState.selectedGroup}'),
|
'${viewModel.state.isSaving}_${reportsState
|
||||||
|
.group}_${reportsState.selectedGroup}'),
|
||||||
viewModel: viewModel,
|
viewModel: viewModel,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -401,7 +410,8 @@ class _ReportDataTableState extends State<ReportDataTable> {
|
||||||
sortAscending: reportSettings.sortTotalsAscending,
|
sortAscending: reportSettings.sortTotalsAscending,
|
||||||
columns: reportResult.totalColumns(
|
columns: reportResult.totalColumns(
|
||||||
context,
|
context,
|
||||||
(index, ascending) => widget.viewModel
|
(index, ascending) =>
|
||||||
|
widget.viewModel
|
||||||
.onReportTotalsSorted(index, ascending)),
|
.onReportTotalsSorted(index, ascending)),
|
||||||
rows: reportResult.totalRows(context),
|
rows: reportResult.totalRows(context),
|
||||||
),
|
),
|
||||||
|
|
@ -426,7 +436,8 @@ class _ReportDataTableState extends State<ReportDataTable> {
|
||||||
columns: reportResult.tableColumns(
|
columns: reportResult.tableColumns(
|
||||||
context,
|
context,
|
||||||
(index, ascending) =>
|
(index, ascending) =>
|
||||||
widget.viewModel.onReportSorted(sortedColumns[index], ascending)),
|
widget.viewModel
|
||||||
|
.onReportSorted(sortedColumns[index], ascending)),
|
||||||
source: dataTableSource,
|
source: dataTableSource,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -435,7 +446,6 @@ class _ReportDataTableState extends State<ReportDataTable> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum ReportColumnType {
|
enum ReportColumnType {
|
||||||
string,
|
string,
|
||||||
dateTime,
|
dateTime,
|
||||||
|
|
@ -667,8 +677,8 @@ class ReportResult {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DataColumn> tableColumns(
|
List<DataColumn> tableColumns(BuildContext context,
|
||||||
BuildContext context, Function(int, bool) onSortCallback) {
|
Function(int, bool) onSortCallback) {
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
final store = StoreProvider.of<AppState>(context);
|
final store = StoreProvider.of<AppState>(context);
|
||||||
final company = store.state.company;
|
final company = store.state.company;
|
||||||
|
|
@ -680,7 +690,9 @@ class ReportResult {
|
||||||
label: Container(
|
label: Container(
|
||||||
constraints: BoxConstraints(minWidth: 80),
|
constraints: BoxConstraints(minWidth: 80),
|
||||||
child: Text(
|
child: Text(
|
||||||
(company.getCustomFieldLabel(column).isNotEmpty
|
(company
|
||||||
|
.getCustomFieldLabel(column)
|
||||||
|
.isNotEmpty
|
||||||
? company.getCustomFieldLabel(column)
|
? company.getCustomFieldLabel(column)
|
||||||
: localization.lookup(column)) +
|
: localization.lookup(column)) +
|
||||||
' ',
|
' ',
|
||||||
|
|
@ -694,8 +706,7 @@ class ReportResult {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
DataRow tableFilters(
|
DataRow tableFilters(BuildContext context,
|
||||||
BuildContext context,
|
|
||||||
Map<String, TextEditingController> textEditingControllers,
|
Map<String, TextEditingController> textEditingControllers,
|
||||||
Function(String, String) onFilterChanged) {
|
Function(String, String) onFilterChanged) {
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
|
|
@ -707,14 +718,17 @@ class ReportResult {
|
||||||
if (textEditingControllers == null ||
|
if (textEditingControllers == null ||
|
||||||
!textEditingControllers.containsKey(column))
|
!textEditingControllers.containsKey(column))
|
||||||
DataCell(Text(textEditingControllers == null ? 'null' : 'test'))
|
DataCell(Text(textEditingControllers == null ? 'null' : 'test'))
|
||||||
else if (getReportColumnType(column, context) == ReportColumnType.bool)
|
else
|
||||||
|
if (getReportColumnType(column, context) == ReportColumnType.bool)
|
||||||
DataCell(AppDropdownButton<bool>(
|
DataCell(AppDropdownButton<bool>(
|
||||||
labelText: null,
|
labelText: null,
|
||||||
showBlank: true,
|
showBlank: true,
|
||||||
blankValue: null,
|
blankValue: null,
|
||||||
value: textEditingControllers[column].text == 'true'
|
value: textEditingControllers[column].text == 'true'
|
||||||
? true
|
? true
|
||||||
: textEditingControllers[column].text == 'false' ? false : null,
|
: textEditingControllers[column].text == 'false'
|
||||||
|
? false
|
||||||
|
: null,
|
||||||
onChanged: (dynamic value) {
|
onChanged: (dynamic value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
textEditingControllers[column].text = '';
|
textEditingControllers[column].text = '';
|
||||||
|
|
@ -726,16 +740,21 @@ class ReportResult {
|
||||||
},
|
},
|
||||||
items: [
|
items: [
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
child: Text(AppLocalization.of(context).yes),
|
child: Text(AppLocalization
|
||||||
|
.of(context)
|
||||||
|
.yes),
|
||||||
value: true,
|
value: true,
|
||||||
),
|
),
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
child: Text(AppLocalization.of(context).no),
|
child: Text(AppLocalization
|
||||||
|
.of(context)
|
||||||
|
.no),
|
||||||
value: false,
|
value: false,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
else if (getReportColumnType(column, context) ==
|
else
|
||||||
|
if (getReportColumnType(column, context) ==
|
||||||
ReportColumnType.number)
|
ReportColumnType.number)
|
||||||
DataCell(TextFormField(
|
DataCell(TextFormField(
|
||||||
controller: textEditingControllers[column],
|
controller: textEditingControllers[column],
|
||||||
|
|
@ -756,14 +775,16 @@ class ReportResult {
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
))
|
))
|
||||||
else if (getReportColumnType(column, context) ==
|
else
|
||||||
|
if (getReportColumnType(column, context) ==
|
||||||
ReportColumnType.dateTime ||
|
ReportColumnType.dateTime ||
|
||||||
getReportColumnType(column, context) == ReportColumnType.date)
|
getReportColumnType(column, context) == ReportColumnType.date)
|
||||||
DataCell(AppDropdownButton<DateRange>(
|
DataCell(AppDropdownButton<DateRange>(
|
||||||
labelText: null,
|
labelText: null,
|
||||||
showBlank: true,
|
showBlank: true,
|
||||||
blankValue: null,
|
blankValue: null,
|
||||||
value: (textEditingControllers[column].text ?? '').isNotEmpty &&
|
value: (textEditingControllers[column].text ?? '')
|
||||||
|
.isNotEmpty &&
|
||||||
textEditingControllers[column].text != 'null'
|
textEditingControllers[column].text != 'null'
|
||||||
? DateRange.valueOf(textEditingControllers[column].text)
|
? DateRange.valueOf(textEditingControllers[column].text)
|
||||||
: null,
|
: null,
|
||||||
|
|
@ -777,14 +798,40 @@ class ReportResult {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
items: DateRange.values
|
items: DateRange.values
|
||||||
.map((dateRange) => DropdownMenuItem<DateRange>(
|
.map((dateRange) =>
|
||||||
|
DropdownMenuItem<DateRange>(
|
||||||
child: Text(localization.lookup(dateRange.toString())),
|
child: Text(localization.lookup(dateRange.toString())),
|
||||||
value: dateRange,
|
value: dateRange,
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
))
|
))
|
||||||
|
// TODO remove DEMO_MODE check
|
||||||
else
|
else
|
||||||
DataCell(TypeAheadFormField(
|
if (Config.DEMO_MODE)
|
||||||
|
DataCell(TextFormField(
|
||||||
|
controller: textEditingControllers != null
|
||||||
|
? textEditingControllers[column]
|
||||||
|
: null,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
suffixIcon: textEditingControllers == null
|
||||||
|
? null
|
||||||
|
: (textEditingControllers[column]?.text ?? '')
|
||||||
|
.isEmpty
|
||||||
|
? null
|
||||||
|
: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.clear,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
textEditingControllers[column].text = '';
|
||||||
|
onFilterChanged(column, '');
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
else
|
||||||
|
DataCell(
|
||||||
|
TypeAheadFormField(
|
||||||
noItemsFoundBuilder: (context) => SizedBox(),
|
noItemsFoundBuilder: (context) => SizedBox(),
|
||||||
suggestionsBoxDecoration: SuggestionsBoxDecoration(
|
suggestionsBoxDecoration: SuggestionsBoxDecoration(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
|
|
@ -800,8 +847,12 @@ class ReportResult {
|
||||||
.renderText(context, column)
|
.renderText(context, column)
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.contains(filter) &&
|
.contains(filter) &&
|
||||||
row[index].renderText(context, column).trim().isNotEmpty)
|
row[index]
|
||||||
.map((row) => row[index].renderText(context, column))
|
.renderText(context, column)
|
||||||
|
.trim()
|
||||||
|
.isNotEmpty)
|
||||||
|
.map((row) =>
|
||||||
|
row[index].renderText(context, column))
|
||||||
.toSet()
|
.toSet()
|
||||||
.toList();
|
.toList();
|
||||||
},
|
},
|
||||||
|
|
@ -822,7 +873,8 @@ class ReportResult {
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
suffixIcon: textEditingControllers == null
|
suffixIcon: textEditingControllers == null
|
||||||
? null
|
? null
|
||||||
: (textEditingControllers[column]?.text ?? '').isEmpty
|
: (textEditingControllers[column]?.text ?? '')
|
||||||
|
.isEmpty
|
||||||
? null
|
? null
|
||||||
: IconButton(
|
: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
|
@ -838,7 +890,8 @@ class ReportResult {
|
||||||
autoFlipDirection: true,
|
autoFlipDirection: true,
|
||||||
animationStart: 1,
|
animationStart: 1,
|
||||||
debounceDuration: Duration(seconds: 0),
|
debounceDuration: Duration(seconds: 0),
|
||||||
))
|
),
|
||||||
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -875,7 +928,9 @@ class ReportResult {
|
||||||
String value = '';
|
String value = '';
|
||||||
if (column == groupBy) {
|
if (column == groupBy) {
|
||||||
if (group.isEmpty) {
|
if (group.isEmpty) {
|
||||||
value = AppLocalization.of(context).blank;
|
value = AppLocalization
|
||||||
|
.of(context)
|
||||||
|
.blank;
|
||||||
} else if (getReportColumnType(column, context) ==
|
} else if (getReportColumnType(column, context) ==
|
||||||
ReportColumnType.dateTime ||
|
ReportColumnType.dateTime ||
|
||||||
getReportColumnType(column, context) == ReportColumnType.date) {
|
getReportColumnType(column, context) == ReportColumnType.date) {
|
||||||
|
|
@ -911,9 +966,13 @@ class ReportResult {
|
||||||
}
|
}
|
||||||
} else if (getReportColumnType(column, context) ==
|
} else if (getReportColumnType(column, context) ==
|
||||||
ReportColumnType.bool) {
|
ReportColumnType.bool) {
|
||||||
filter = filter == AppLocalization.of(context).yes
|
filter = filter == AppLocalization
|
||||||
|
.of(context)
|
||||||
|
.yes
|
||||||
? 'true'
|
? 'true'
|
||||||
: filter == AppLocalization.of(context).no ? 'false' : '';
|
: filter == AppLocalization
|
||||||
|
.of(context)
|
||||||
|
.no ? 'false' : '';
|
||||||
}
|
}
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
UpdateReportSettings(
|
UpdateReportSettings(
|
||||||
|
|
@ -933,8 +992,8 @@ class ReportResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DataColumn> totalColumns(
|
List<DataColumn> totalColumns(BuildContext context,
|
||||||
BuildContext context, Function(int, bool) onSortCallback) {
|
Function(int, bool) onSortCallback) {
|
||||||
final localization = AppLocalization.of(context);
|
final localization = AppLocalization.of(context);
|
||||||
columns.toList().sort((String str1, String str2) => str1.compareTo(str2));
|
columns.toList().sort((String str1, String str2) => str1.compareTo(str2));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue