Add designs templates

This commit is contained in:
Hillel Coren 2023-11-09 15:13:43 +02:00
parent 2490e21207
commit 4a3c5a1e0b
2 changed files with 128 additions and 111 deletions

View File

@ -4,6 +4,7 @@ import 'dart:convert';
// Flutter imports: // Flutter imports:
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// Package imports: // Package imports:
@ -19,6 +20,7 @@ import 'package:invoiceninja_flutter/ui/app/buttons/elevated_button.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart'; import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/forms/date_picker.dart'; import 'package:invoiceninja_flutter/ui/app/forms/date_picker.dart';
import 'package:invoiceninja_flutter/ui/app/multiselect.dart'; import 'package:invoiceninja_flutter/ui/app/multiselect.dart';
import 'package:invoiceninja_flutter/ui/app/presenters/entity_presenter.dart';
import 'package:invoiceninja_flutter/utils/files.dart'; import 'package:invoiceninja_flutter/utils/files.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:printing/printing.dart'; import 'package:printing/printing.dart';
@ -37,6 +39,9 @@ import 'package:invoiceninja_flutter/utils/dialogs.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/web_stub.dart'
if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart';
class ClientPdfView extends StatefulWidget { class ClientPdfView extends StatefulWidget {
const ClientPdfView({ const ClientPdfView({
Key? key, Key? key,
@ -62,6 +67,7 @@ class _ClientPdfViewState extends State<ClientPdfView> {
convertDateTimeToSqlDate(DateTime.now().subtract(Duration(days: 365))); convertDateTimeToSqlDate(DateTime.now().subtract(Duration(days: 365)));
String? _endDate = convertDateTimeToSqlDate(); String? _endDate = convertDateTimeToSqlDate();
String _status = kStatementStatusAll; String _status = kStatementStatusAll;
String? _pdfString;
@override @override
void initState() { void initState() {
@ -85,6 +91,7 @@ class _ClientPdfViewState extends State<ClientPdfView> {
} }
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
final state = widget.viewModel.state;
setState(() { setState(() {
_isLoading = true; _isLoading = true;
@ -98,6 +105,12 @@ class _ClientPdfViewState extends State<ClientPdfView> {
} }
} else { } else {
_response = response; _response = response;
if (kIsWeb && state.prefState.enableNativeBrowser) {
_pdfString = 'data:application/pdf;base64,' +
base64Encode(response!.bodyBytes);
WebUtils.registerWebView(_pdfString);
}
} }
_isLoading = false; _isLoading = false;
@ -172,8 +185,88 @@ class _ClientPdfViewState extends State<ClientPdfView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final state = store.state; final state = store.state;
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context)!;
final client = widget.viewModel.client; final client = widget.viewModel.client!;
final datePicker = Flexible(
child: Theme(
data: state.prefState.enableDarkMode || state.hasAccentColor
? ThemeData.dark()
: ThemeData.light(),
child: AppDropdownButton<DateRange>(
labelText: localization.dateRange,
blankValue: null,
//showBlank: true,
value: _dateRange,
onChanged: (dynamic value) {
setState(() {
_dateRange = value;
});
if (value != DateRange.custom) {
loadPDF();
}
},
items: DateRange.values
.where((value) => value != DateRange.allTime)
.map((dateRange) => DropdownMenuItem<DateRange>(
child: Text(localization.lookup(dateRange.toString())),
value: dateRange,
))
.toList(),
),
),
);
final statusPicker = Flexible(
child: Theme(
data: state.prefState.enableDarkMode || state.hasAccentColor
? ThemeData.dark()
: ThemeData.light(),
child: AppDropdownButton<String>(
labelText: localization.status,
blankValue: null,
value: _status,
onChanged: (dynamic value) {
setState(() {
_status = value;
});
loadPDF();
},
items: [
kStatementStatusAll,
kStatementStatusPaid,
kStatementStatusUnpaid,
]
.map((value) => DropdownMenuItem<String>(
child: Text(localization.lookup(value)),
value: value,
))
.toList()),
),
);
final sectionPicker = Flexible(
child: DropDownMultiSelect(
onChanged: (List<dynamic> selected) {
//_selectedOptions = selected;
store.dispatch(UpdateUserPreferences(
statementIncludes: BuiltList<String>(selected)));
loadPDF();
},
selectedValues: state.prefState.statementIncludes.toList(),
menuItembuilder: (dynamic option) => Text(
localization.lookup(option),
style: TextStyle(fontSize: 14),
),
isDense: true,
options: <String>[
kStatementIncludePayments,
kStatementIncludeCredits,
kStatementIncludeAging,
],
whenEmpty: '',
));
/* /*
final pageSelector = _pageCount == 1 final pageSelector = _pageCount == 1
@ -218,104 +311,11 @@ class _ClientPdfViewState extends State<ClientPdfView> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
/*
Expanded( Expanded(
child: Text( child: Text(
EntityPresenter().initialize(client, context).title(), EntityPresenter().initialize(client, context).title()!,
), ),
), ),
*/
Flexible(
child: Theme(
data:
state.prefState.enableDarkMode || state.hasAccentColor
? ThemeData.dark()
: ThemeData.light(),
child: AppDropdownButton<DateRange>(
labelText: localization!.dateRange,
blankValue: null,
//showBlank: true,
value: _dateRange,
onChanged: (dynamic value) {
setState(() {
_dateRange = value;
});
if (value != DateRange.custom) {
loadPDF();
}
},
items: DateRange.values
.where((value) => value != DateRange.allTime)
.map((dateRange) => DropdownMenuItem<DateRange>(
child: Text(localization
.lookup(dateRange.toString())),
value: dateRange,
))
.toList(),
),
),
),
SizedBox(width: 16),
Flexible(
child: Theme(
data:
state.prefState.enableDarkMode || state.hasAccentColor
? ThemeData.dark()
: ThemeData.light(),
child: AppDropdownButton<String>(
labelText: localization.status,
blankValue: null,
value: _status,
onChanged: (dynamic value) {
setState(() {
_status = value;
});
loadPDF();
},
items: [
kStatementStatusAll,
kStatementStatusPaid,
kStatementStatusUnpaid,
]
.map((value) => DropdownMenuItem<String>(
child: Text(localization.lookup(value)),
value: value,
))
.toList()),
),
),
if (isDesktop(context)) ...[
Theme(
data: ThemeData(
appBarTheme: AppBarTheme(
titleTextStyle: TextStyle(fontSize: 60),
)),
child: Flexible(
child: DropDownMultiSelect(
onChanged: (List<dynamic> selected) {
//_selectedOptions = selected;
store.dispatch(UpdateUserPreferences(
statementIncludes: BuiltList<String>(selected)));
loadPDF();
},
selectedValues:
state.prefState.statementIncludes.toList(),
menuItembuilder: (dynamic option) => Text(
localization.lookup(option),
style: TextStyle(fontSize: 14),
),
isDense: true,
options: <String>[
kStatementIncludePayments,
kStatementIncludeCredits,
kStatementIncludeAging,
],
whenEmpty: '',
)),
)
//...pageSelector,
]
], ],
), ),
actions: <Widget>[ actions: <Widget>[
@ -327,7 +327,7 @@ class _ClientPdfViewState extends State<ClientPdfView> {
: () async { : () async {
final fileName = localization.statement + final fileName = localization.statement +
'_' + '_' +
(client!.number) + (client.number) +
'.pdf'; '.pdf';
saveDownloadedFile(_response!.bodyBytes, fileName); saveDownloadedFile(_response!.bodyBytes, fileName);
}, },
@ -338,7 +338,7 @@ class _ClientPdfViewState extends State<ClientPdfView> {
onPressed: _response == null onPressed: _response == null
? null ? null
: () async { : () async {
if (!client!.hasEmailAddress) { if (!client.hasEmailAddress) {
showMessageDialog( showMessageDialog(
message: localization.clientEmailNotSet, message: localization.clientEmailNotSet,
secondaryActions: [ secondaryActions: [
@ -384,7 +384,7 @@ class _ClientPdfViewState extends State<ClientPdfView> {
entity: ScheduleEntity( entity: ScheduleEntity(
ScheduleEntity.TEMPLATE_EMAIL_STATEMENT) ScheduleEntity.TEMPLATE_EMAIL_STATEMENT)
.rebuild((b) => b .rebuild((b) => b
..parameters.clients.add(client!.id) ..parameters.clients.add(client.id)
..parameters.showAgingTable = ..parameters.showAgingTable =
includes.contains(localization.aging) includes.contains(localization.aging)
..parameters.showPaymentsTable = ..parameters.showPaymentsTable =
@ -401,7 +401,7 @@ class _ClientPdfViewState extends State<ClientPdfView> {
child: Text(localization.close, child: Text(localization.close,
style: TextStyle(color: state.headerTextColor)), style: TextStyle(color: state.headerTextColor)),
onPressed: () { onPressed: () {
viewEntity(entity: client!); viewEntity(entity: client);
}, },
), ),
], ],
@ -409,6 +409,20 @@ class _ClientPdfViewState extends State<ClientPdfView> {
: null, : null,
body: Column( body: Column(
children: [ children: [
Material(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: isDesktop(context)
? Row(
children: [
datePicker,
statusPicker,
sectionPicker,
],
)
: Placeholder(),
),
),
if (_dateRange == DateRange.custom) if (_dateRange == DateRange.custom)
Container( Container(
width: double.infinity, width: double.infinity,
@ -421,7 +435,7 @@ class _ClientPdfViewState extends State<ClientPdfView> {
padding: padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 8), const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: DatePicker( child: DatePicker(
labelText: localization!.startDate, labelText: localization.startDate,
onSelected: (value, _) { onSelected: (value, _) {
setState(() { setState(() {
_startDate = value; _startDate = value;
@ -457,15 +471,19 @@ class _ClientPdfViewState extends State<ClientPdfView> {
Expanded( Expanded(
child: _isLoading || _response == null child: _isLoading || _response == null
? LoadingIndicator() ? LoadingIndicator()
: PdfPreview( : (kIsWeb && state.prefState.enableNativeBrowser)
build: (format) => _response!.bodyBytes, ? HtmlElementView(viewType: _pdfString!)
canChangeOrientation: false, : PdfPreview(
canChangePageFormat: false, build: (format) => _response!.bodyBytes,
canDebug: false, canChangeOrientation: false,
maxPageWidth: 600, canChangePageFormat: false,
pdfFileName: canDebug: false,
localization!.statement + '_' + client!.number + '.pdf', maxPageWidth: 600,
), pdfFileName: localization.statement +
'_' +
client.number +
'.pdf',
),
), ),
], ],
), ),

View File

@ -275,7 +275,6 @@ class _InvoicePdfViewState extends State<InvoicePdfView> {
) )
: null, : null,
body: Column( body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Material( Material(
child: Row( child: Row(