import 'package:built_collection/built_collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/redux/static/static_selectors.dart'; import 'package:invoiceninja_flutter/ui/app/dialogs/multiselect_dialog.dart'; import 'package:invoiceninja_flutter/ui/app/entity_dropdown.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/forms/app_dropdown_button.dart'; import 'package:invoiceninja_flutter/ui/app/forms/app_form.dart'; import 'package:invoiceninja_flutter/ui/app/forms/bool_dropdown_button.dart'; import 'package:invoiceninja_flutter/ui/app/forms/color_picker.dart'; import 'package:invoiceninja_flutter/ui/app/forms/design_picker.dart'; import 'package:invoiceninja_flutter/ui/app/forms/learn_more.dart'; import 'package:invoiceninja_flutter/ui/settings/invoice_design_vm.dart'; import 'package:invoiceninja_flutter/ui/app/edit_scaffold.dart'; import 'package:invoiceninja_flutter/utils/fonts.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; class InvoiceDesign extends StatefulWidget { const InvoiceDesign({ Key key, @required this.viewModel, }) : super(key: key); final InvoiceDesignVM viewModel; @override _InvoiceDesignState createState() => _InvoiceDesignState(); } class _InvoiceDesignState extends State with SingleTickerProviderStateMixin { static final GlobalKey _formKey = GlobalKey(debugLabel: '_invoiceDesign'); TabController _controller; FocusScopeNode _focusNode; @override void initState() { super.initState(); _focusNode = FocusScopeNode(); _controller = TabController(vsync: this, length: 10); } @override void dispose() { _controller.dispose(); _focusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final localization = AppLocalization.of(context); final viewModel = widget.viewModel; final state = viewModel.state; final settings = viewModel.settings; final company = viewModel.company; return EditScaffold( title: localization.invoiceDesign, onSavePressed: viewModel.onSavePressed, appBarBottom: TabBar( key: ValueKey(state.settingsUIState.updatedAt), controller: _controller, isScrollable: true, tabs: [ Tab( text: localization.generalSettings, ), Tab( text: localization.invoiceOptions, ), Tab( text: localization.clientDetails, ), Tab( text: localization.companyDetails, ), Tab( text: localization.companyAddress, ), Tab( text: localization.invoiceDetails, ), Tab( text: localization.quoteDetails, ), Tab( text: localization.creditDetails, ), Tab(text: localization.productColumns), Tab(text: localization.taskColumns), ], ), body: AppTabForm( tabController: _controller, formKey: _formKey, focusNode: _focusNode, children: [ ListView(children: [ FormCard( children: [ DesignPicker( label: localization.invoiceDesign, initialValue: settings.defaultInvoiceDesignId, onSelected: (value) => viewModel.onSettingsChanged(settings .rebuild((b) => b..defaultInvoiceDesignId = value.id)), ), if (company.isModuleEnabled(EntityType.quote)) DesignPicker( label: localization.quoteDesign, initialValue: settings.defaultQuoteDesignId, onSelected: (value) => viewModel.onSettingsChanged(settings .rebuild((b) => b..defaultQuoteDesignId = value.id)), ), if (company.isModuleEnabled(EntityType.credit)) DesignPicker( label: localization.creditDesign, initialValue: settings.defaultCreditDesignId, onSelected: (value) => viewModel.onSettingsChanged(settings .rebuild((b) => b..defaultCreditDesignId = value.id)), ), AppDropdownButton( labelText: localization.pageSize, value: settings.pageSize, onChanged: (dynamic value) => viewModel.onSettingsChanged( settings.rebuild((b) => b..pageSize = value)), items: kPageSizes .map((pageSize) => DropdownMenuItem( value: pageSize, child: Text(pageSize), )) .toList(), ), AppDropdownButton( labelText: localization.fontSize, value: settings.fontSize == null ? '' : '${settings.fontSize}', // TODO remove this and 0 from options showBlank: true, onChanged: (dynamic value) => viewModel.onSettingsChanged( settings.rebuild((b) => b..fontSize = int.parse(value))), items: [0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] .map((fontSize) => DropdownMenuItem( value: '$fontSize', child: fontSize == 0 ? SizedBox() : Text('$fontSize'), )) .toList(), ), ], ), FormCard( crossAxisAlignment: CrossAxisAlignment.start, children: [ LearnMore( url: 'https://fonts.google.com', child: EntityDropdown( key: ValueKey('__primary_font_${settings.primaryFont}__'), entityType: EntityType.font, labelText: localization.primaryFont, entityId: settings.primaryFont, entityMap: memoizedFontMap(kGoogleFonts), onSelected: (font) => viewModel.onSettingsChanged( settings.rebuild((b) => b..primaryFont = font?.id)), allowClearing: state.settingsUIState.isFiltered, ), ), EntityDropdown( key: ValueKey('__secondary_font_${settings.secondaryFont}__'), entityType: EntityType.font, labelText: localization.secondaryFont, entityId: settings.secondaryFont, entityMap: memoizedFontMap(kGoogleFonts), onSelected: (font) => viewModel.onSettingsChanged( settings.rebuild((b) => b..secondaryFont = font?.id)), allowClearing: state.settingsUIState.isFiltered, ), FormColorPicker( labelText: localization.primaryColor, onSelected: (value) => viewModel.onSettingsChanged( settings.rebuild((b) => b..primaryColor = value)), initialValue: settings.primaryColor, ), FormColorPicker( labelText: localization.secondaryColor, onSelected: (value) => viewModel.onSettingsChanged( settings.rebuild((b) => b..secondaryColor = value)), initialValue: settings.secondaryColor, ), ], ), ]), ListView( padding: const EdgeInsets.all(10), children: [ FormCard( children: [ BoolDropdownButton( label: localization.allPagesHeader, value: settings.allPagesHeader, iconData: FontAwesomeIcons.fileInvoice, onChanged: (value) => viewModel.onSettingsChanged( settings.rebuild((b) => b..allPagesHeader = value)), enabledLabel: localization.allPages, disabledLabel: localization.firstPage, ), BoolDropdownButton( label: localization.allPagesFooter, value: settings.allPagesFooter, iconData: FontAwesomeIcons.fileInvoice, onChanged: (value) => viewModel.onSettingsChanged( settings.rebuild((b) => b..allPagesFooter = value)), enabledLabel: localization.allPages, disabledLabel: localization.lastPage, ), ], ), FormCard( children: [ BoolDropdownButton( label: localization.hidePaidToDate, helpLabel: localization.hidePaidToDateHelp, value: settings.hidePaidToDate, iconData: FontAwesomeIcons.fileInvoiceDollar, onChanged: (value) => viewModel.onSettingsChanged( settings.rebuild((b) => b..hidePaidToDate = value)), ), BoolDropdownButton( label: localization.invoiceEmbedDocuments, helpLabel: localization.invoiceEmbedDocumentsHelp, value: settings.embedDocuments, iconData: FontAwesomeIcons.image, onChanged: (value) => viewModel.onSettingsChanged( settings.rebuild((b) => b..embedDocuments = value)), ), ], ), ], ), FormCard( child: MultiSelectList( //selected: settings.pdfVariables[kPdfFieldsClientDetails].toList(), options: settings.pdfVariables[kPdfFieldsClientDetails].toList(), defaultSelected: settings.pdfVariables[kPdfFieldsClientDetails].toList(), selected: settings.pdfVariables[kPdfFieldsClientDetails].toList(), onSelected: (values) { viewModel.onSettingsChanged(settings.rebuild((b) => b ..pdfVariables[kPdfFieldsClientDetails] = BuiltList(values))); }, addTitle: localization.addField, liveChanges: true, ), ), FormCard( child: MultiSelectList( options: [], defaultSelected: [], //selected: settings.pdfVariables[kPdfFieldsCompanyDetails].toList(), selected: [], onSelected: (values) { viewModel.onSettingsChanged(settings.rebuild((b) => b ..pdfVariables[kPdfFieldsCompanyDetails] = BuiltList(values))); }, addTitle: localization.addField, liveChanges: true, ), ), FormCard( child: MultiSelectList( options: [], defaultSelected: [], //selected: settings.pdfVariables[kPdfFieldsCompanyAddress].toList(), selected: [], onSelected: (values) { viewModel.onSettingsChanged(settings.rebuild((b) => b ..pdfVariables[kPdfFieldsCompanyAddress] = BuiltList(values))); }, addTitle: localization.addField, liveChanges: true, ), ), FormCard( child: MultiSelectList( options: [], defaultSelected: [], //selected: settings.pdfVariables[kPdfFieldsInvoiceDetails].toList(), selected: [], onSelected: (values) { viewModel.onSettingsChanged(settings.rebuild((b) => b ..pdfVariables[kPdfFieldsInvoiceDetails] = BuiltList(values))); }, addTitle: localization.addField, liveChanges: true, ), ), FormCard( child: MultiSelectList( options: [], defaultSelected: [], //selected: settings.pdfVariables[kPdfFieldsQuoteDetails].toList(), selected: [], onSelected: (values) { viewModel.onSettingsChanged(settings.rebuild((b) => b ..pdfVariables[kPdfFieldsQuoteDetails] = BuiltList(values))); }, addTitle: localization.addField, liveChanges: true, ), ), FormCard( child: MultiSelectList( options: [], defaultSelected: [], //selected: settings.pdfVariables[kPdfFieldsCreditDetails].toList(), selected: [], onSelected: (values) { viewModel.onSettingsChanged(settings.rebuild((b) => b ..pdfVariables[kPdfFieldsCreditDetails] = BuiltList(values))); }, addTitle: localization.addField, liveChanges: true, ), ), FormCard( child: MultiSelectList( options: [], defaultSelected: [], //selected: settings.pdfVariables[kPdfFieldsProductColumns].toList(), selected: [], onSelected: (values) { viewModel.onSettingsChanged(settings.rebuild((b) => b ..pdfVariables[kPdfFieldsProductColumns] = BuiltList(values))); }, addTitle: localization.addField, liveChanges: true, ), ), FormCard( child: MultiSelectList( options: [], defaultSelected: [], //selected: settings.pdfVariables[kPdfFieldsTaskColumns].toList(), selected: [], onSelected: (values) { viewModel.onSettingsChanged(settings.rebuild((b) => b ..pdfVariables[kPdfFieldsTaskColumns] = BuiltList(values))); }, addTitle: localization.addField, liveChanges: true, ), ), ], ), ); } }