Default to localization settings when clicking client settings

This commit is contained in:
Hillel Coren 2021-07-25 15:28:53 +03:00
parent febbd69265
commit 9c4f18a58c
9 changed files with 82 additions and 17 deletions

View File

@ -139,6 +139,7 @@ const int kMillisecondsToRefreshActivities = 1000 * 60 * 60 * 24; // 1 day
const int kMillisecondsToRefreshStaticData = 1000 * 60 * 60 * 24; // 1 day const int kMillisecondsToRefreshStaticData = 1000 * 60 * 60 * 24; // 1 day
const int kMillisecondsToDebounceUpdate = 500; // .5 second const int kMillisecondsToDebounceUpdate = 500; // .5 second
const int kMillisecondsToDebounceSave = 1500; // 1.5 seconds const int kMillisecondsToDebounceSave = 1500; // 1.5 seconds
const int kMillisecondsToDebouncePDF = 3000; // 3 seconds
const String kLanguageEnglish = '1'; const String kLanguageEnglish = '1';

View File

@ -128,7 +128,11 @@ void main({bool isTesting = false}) async {
Future<AppState> _initialState(bool isTesting) async { Future<AppState> _initialState(bool isTesting) async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
final prefString = prefs?.getString(kSharedPrefs); final prefString = prefs?.getString(kSharedPrefs);
final url = WebUtils.browserUrl ?? prefs.getString(kSharedPrefUrl) ?? '';
String url = WebUtils.browserUrl ?? prefs.getString(kSharedPrefUrl) ?? '';
if (!kReleaseMode) {
url = kAppStagingUrl;
}
//url = kAppProductionUrl; //url = kAppProductionUrl;
//url = kAppDemoUrl; //url = kAppDemoUrl;

View File

@ -11,7 +11,6 @@ import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart'; import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.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';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class ViewClientList implements PersistUI, StopLoading { class ViewClientList implements PersistUI, StopLoading {
@ -295,7 +294,7 @@ void handleClientAction(
case EntityAction.settings: case EntityAction.settings:
store.dispatch(ViewSettings( store.dispatch(ViewSettings(
client: client, client: client,
section: isMobile(context) ? null : kSettingsCompanyDetails, section: kSettingsLocalization,
)); ));
break; break;
case EntityAction.newTask: case EntityAction.newTask:

View File

@ -28,7 +28,6 @@ class EntityDropdown extends StatefulWidget {
this.entityId, this.entityId,
this.onAddPressed, this.onAddPressed,
this.autofocus = false, this.autofocus = false,
this.showUseDefault = false,
this.onFieldSubmitted, this.onFieldSubmitted,
this.overrideSuggestedAmount, this.overrideSuggestedAmount,
this.overrideSuggestedLabel, this.overrideSuggestedLabel,
@ -48,7 +47,6 @@ class EntityDropdown extends StatefulWidget {
final Function(Completer<SelectableEntity> completer) onAddPressed; final Function(Completer<SelectableEntity> completer) onAddPressed;
final Function(BaseEntity) overrideSuggestedAmount; final Function(BaseEntity) overrideSuggestedAmount;
final Function(BaseEntity) overrideSuggestedLabel; final Function(BaseEntity) overrideSuggestedLabel;
final bool showUseDefault;
@override @override
_EntityDropdownState createState() => _EntityDropdownState(); _EntityDropdownState createState() => _EntityDropdownState();
@ -78,7 +76,6 @@ class _EntityDropdownState extends State<EntityDropdown> {
@override @override
void didChangeDependencies() { void didChangeDependencies() {
final localization = AppLocalization.of(context);
final state = StoreProvider.of<AppState>(context).state; final state = StoreProvider.of<AppState>(context).state;
_entityMap = widget.entityMap ?? state.getEntityMap(widget.entityType); _entityMap = widget.entityMap ?? state.getEntityMap(widget.entityType);
@ -89,8 +86,7 @@ class _EntityDropdownState extends State<EntityDropdown> {
if (widget.overrideSuggestedLabel != null) { if (widget.overrideSuggestedLabel != null) {
_textController.text = widget.overrideSuggestedLabel(entity); _textController.text = widget.overrideSuggestedLabel(entity);
} else { } else {
_textController.text = entity?.listDisplayName ?? _textController.text = entity?.listDisplayName ?? '';
(widget.showUseDefault ? localization.useDefault : '');
} }
} }

View File

@ -55,7 +55,7 @@ class BoolDropdownButton extends StatelessWidget {
border: _showBlank ? null : InputBorder.none, border: _showBlank ? null : InputBorder.none,
labelText: label, labelText: label,
), ),
isEmpty: '${value ?? ''}'.isEmpty && !state.settingsUIState.isFiltered, isEmpty: '${value ?? ''}'.isEmpty,
child: _showBlank child: _showBlank
? DropdownButtonHideUnderline( ? DropdownButtonHideUnderline(
child: DropdownButton<bool>( child: DropdownButton<bool>(

View File

@ -1,7 +1,13 @@
import 'dart:convert';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:invoiceninja_flutter/data/models/serializers.dart';
import 'package:native_pdf_view/native_pdf_view.dart';
import 'package:invoiceninja_flutter/utils/web_stub.dart'
if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart';
import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/web_client.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/invoice_model.dart'; import 'package:invoiceninja_flutter/data/models/invoice_model.dart';
import 'package:invoiceninja_flutter/data/models/settings_model.dart'; import 'package:invoiceninja_flutter/data/models/settings_model.dart';
@ -73,6 +79,11 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
List<TextEditingController> _controllers = []; List<TextEditingController> _controllers = [];
final _debouncer = Debouncer(); final _debouncer = Debouncer();
final _pdfDebouncer = Debouncer(milliseconds: kMillisecondsToDebouncePDF);
bool _isLoading = true;
String _pdfString;
PdfController _pdfController;
@override @override
void initState() { void initState() {
@ -150,6 +161,7 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
controller.removeListener(_onChanged); controller.removeListener(_onChanged);
controller.dispose(); controller.dispose();
}); });
_pdfController?.dispose();
super.dispose(); super.dispose();
} }
@ -175,10 +187,50 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
if (invoice != widget.viewModel.invoice) { if (invoice != widget.viewModel.invoice) {
_debouncer.run(() { _debouncer.run(() {
widget.viewModel.onChanged(invoice); widget.viewModel.onChanged(invoice);
_pdfDebouncer.run(() {
loadPdf();
});
}); });
} }
} }
void loadPdf() async {
setState(() {
_isLoading = true;
});
final viewModel = widget.viewModel;
final credentials = viewModel.state.credentials;
final webClient = WebClient();
final url =
'${credentials.url}/live_preview?entity=${viewModel.invoice.entityType.snakeCase}';
final data =
serializers.serializeWith(InvoiceEntity.serializer, viewModel.invoice);
webClient
.post(url, credentials.token,
data: json.encode(data), rawResponse: true)
.then((dynamic response) {
setState(() {
_isLoading = false;
if (kIsWeb) {
_pdfString =
'data:application/pdf;base64,' + base64Encode(response.bodyBytes);
WebUtils.registerWebView(_pdfString);
} else {
final document = PdfDocument.openData(response.bodyBytes);
_pdfController?.dispose();
_pdfController = PdfController(document: document);
}
});
}).catchError((dynamic error) {
setState(() {
_isLoading = false;
});
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
@ -808,6 +860,27 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
], ],
), ),
SizedBox(height: 16), SizedBox(height: 16),
/*
Stack(
children: [
if (_isLoading) LinearProgressIndicator(),
if (_pdfString != null)
kIsWeb
? HtmlElementView(viewType: _pdfString)
: Padding(
padding: const EdgeInsets.all(8),
child: PdfView(controller: _pdfController),
)
],
)*/
if (_pdfString != null)
Expanded(
child: kIsWeb
? HtmlElementView(viewType: _pdfString)
: Padding(
padding: const EdgeInsets.all(8),
child: PdfView(controller: _pdfController),
))
], ],
); );
} }

View File

@ -336,7 +336,6 @@ class _CompanyDetailsState extends State<CompanyDetails>
company company
.rebuild((b) => b..industryId = industry?.id ?? ''), .rebuild((b) => b..industryId = industry?.id ?? ''),
), ),
showUseDefault: state.settingsUIState.isFiltered,
), ),
], ],
), ),
@ -387,7 +386,6 @@ class _CompanyDetailsState extends State<CompanyDetails>
onSelected: (SelectableEntity country) => onSelected: (SelectableEntity country) =>
viewModel.onSettingsChanged(settings viewModel.onSettingsChanged(settings
.rebuild((b) => b..countryId = country?.id)), .rebuild((b) => b..countryId = country?.id)),
showUseDefault: state.settingsUIState.isFiltered,
), ),
], ],
) )
@ -481,7 +479,6 @@ class _CompanyDetailsState extends State<CompanyDetails>
onSelected: (paymentType) => viewModel.onSettingsChanged( onSelected: (paymentType) => viewModel.onSettingsChanged(
settings.rebuild( settings.rebuild(
(b) => b..defaultPaymentTypeId = paymentType?.id)), (b) => b..defaultPaymentTypeId = paymentType?.id)),
showUseDefault: state.settingsUIState.isFiltered,
), ),
if (company.isModuleEnabled(EntityType.invoice)) if (company.isModuleEnabled(EntityType.invoice))
AppDropdownButton<String>( AppDropdownButton<String>(

View File

@ -209,7 +209,6 @@ class _InvoiceDesignState extends State<InvoiceDesign>
onSelected: (font) => viewModel.onSettingsChanged( onSelected: (font) => viewModel.onSettingsChanged(
settings.rebuild((b) => b..primaryFont = font?.id)), settings.rebuild((b) => b..primaryFont = font?.id)),
allowClearing: state.settingsUIState.isFiltered, allowClearing: state.settingsUIState.isFiltered,
showUseDefault: state.settingsUIState.isFiltered,
), ),
), ),
EntityDropdown( EntityDropdown(
@ -222,7 +221,6 @@ class _InvoiceDesignState extends State<InvoiceDesign>
onSelected: (font) => viewModel.onSettingsChanged( onSelected: (font) => viewModel.onSettingsChanged(
settings.rebuild((b) => b..secondaryFont = font?.id)), settings.rebuild((b) => b..secondaryFont = font?.id)),
allowClearing: state.settingsUIState.isFiltered, allowClearing: state.settingsUIState.isFiltered,
showUseDefault: state.settingsUIState.isFiltered,
), ),
FormColorPicker( FormColorPicker(
labelText: localization.primaryColor, labelText: localization.primaryColor,

View File

@ -163,7 +163,6 @@ class _LocalizationSettingsState extends State<LocalizationSettings>
label: localization.helpTranslate, label: localization.helpTranslate,
child: EntityDropdown( child: EntityDropdown(
key: ValueKey('__language_${settings.languageId}__'), key: ValueKey('__language_${settings.languageId}__'),
showUseDefault: state.settingsUIState.isFiltered,
entityType: EntityType.language, entityType: EntityType.language,
entityList: entityList:
memoizedLanguageList(state.staticState.languageMap), memoizedLanguageList(state.staticState.languageMap),
@ -176,7 +175,6 @@ class _LocalizationSettingsState extends State<LocalizationSettings>
), ),
EntityDropdown( EntityDropdown(
key: ValueKey('__timezone_${settings.timezoneId}__'), key: ValueKey('__timezone_${settings.timezoneId}__'),
showUseDefault: state.settingsUIState.isFiltered,
entityType: EntityType.timezone, entityType: EntityType.timezone,
entityList: entityList:
memoizedTimezoneList(state.staticState.timezoneMap), memoizedTimezoneList(state.staticState.timezoneMap),
@ -188,7 +186,6 @@ class _LocalizationSettingsState extends State<LocalizationSettings>
), ),
EntityDropdown( EntityDropdown(
key: ValueKey('__date_format_${settings.dateFormatId}__'), key: ValueKey('__date_format_${settings.dateFormatId}__'),
showUseDefault: state.settingsUIState.isFiltered,
entityType: EntityType.dateFormat, entityType: EntityType.dateFormat,
entityList: entityList:
memoizedDateFormatList(state.staticState.dateFormatMap), memoizedDateFormatList(state.staticState.dateFormatMap),