diff --git a/lib/data/models/product_model.dart b/lib/data/models/product_model.dart index 91ab526736..09501633e6 100644 --- a/lib/data/models/product_model.dart +++ b/lib/data/models/product_model.dart @@ -343,7 +343,7 @@ abstract class ProductEntity extends Object actions.add(EntityAction.newInvoice); } - if (userCompany!.canCreate(EntityType.quote) && !isDeleted!) { + if (userCompany.canCreate(EntityType.quote) && !isDeleted!) { actions.add(EntityAction.newQuote); } diff --git a/lib/redux/app/app_actions.dart b/lib/redux/app/app_actions.dart index 8e0619b185..056f911c63 100644 --- a/lib/redux/app/app_actions.dart +++ b/lib/redux/app/app_actions.dart @@ -115,6 +115,8 @@ class DismissTwoYearReviewAppPermanently implements PersistUI, PersistPrefs {} class DismissTaskExtensionBanner implements PersistUI, PersistPrefs {} +class DismissFlutterWebWarning implements PersistUI {} + class ViewMainScreen { ViewMainScreen({this.addDelay = false}); diff --git a/lib/redux/ui/ui_reducer.dart b/lib/redux/ui/ui_reducer.dart index 4a0d1d1552..920bd71114 100644 --- a/lib/redux/ui/ui_reducer.dart +++ b/lib/redux/ui/ui_reducer.dart @@ -97,6 +97,8 @@ UIState uiReducer(UIState state, dynamic action) { ..filter = filterReducer(state.filter, action) ..filterClearedAt = filterClearedAtReducer(state.filterClearedAt, action) ..lastActivityAt = lastActivityReducer(state.lastActivityAt, action) + ..dismissedFlutterWebWarning = dismissedFlutterWebWarningReducer( + state.dismissedFlutterWebWarning, action) ..selectedCompanyIndex = selectedCompanyIndexReducer(state.selectedCompanyIndex, action) ..previousRoute = state.currentRoute == currentRoute @@ -192,6 +194,12 @@ Reducer lastActivityReducer = combineReducers([ }), ]); +Reducer dismissedFlutterWebWarningReducer = combineReducers([ + TypedReducer((state, action) { + return true; + }), +]); + Reducer filterReducer = combineReducers([ TypedReducer((filter, action) { return action.filter; diff --git a/lib/redux/ui/ui_state.dart b/lib/redux/ui/ui_state.dart index 5aaa2ef733..7f1477aa87 100644 --- a/lib/redux/ui/ui_state.dart +++ b/lib/redux/ui/ui_state.dart @@ -61,6 +61,7 @@ abstract class UIState implements Built { lastActivityAt: 0, currentRoute: currentRoute ?? LoginScreen.route, previousRoute: '', + dismissedFlutterWebWarning: false, previewStack: BuiltList(), filterStack: BuiltList(), dashboardUIState: DashboardUIState(), @@ -126,6 +127,8 @@ abstract class UIState implements Built { String get previousRoute; + bool get dismissedFlutterWebWarning; + EntityType? get loadingEntityType; BuiltList get previewStack; @@ -295,6 +298,7 @@ abstract class UIState implements Built { // ignore: unused_element static void _initializeBuilder(UIStateBuilder builder) => builder ..lastActivityAt = 0 + ..dismissedFlutterWebWarning = false ..filterStack.replace(BuiltList()); static Serializer get serializer => _$uIStateSerializer; diff --git a/lib/redux/ui/ui_state.g.dart b/lib/redux/ui/ui_state.g.dart index b5c831e352..608122bb0f 100644 --- a/lib/redux/ui/ui_state.g.dart +++ b/lib/redux/ui/ui_state.g.dart @@ -27,6 +27,9 @@ class _$UIStateSerializer implements StructuredSerializer { 'previousRoute', serializers.serialize(object.previousRoute, specifiedType: const FullType(String)), + 'dismissedFlutterWebWarning', + serializers.serialize(object.dismissedFlutterWebWarning, + specifiedType: const FullType(bool)), 'previewStack', serializers.serialize(object.previewStack, specifiedType: @@ -179,6 +182,10 @@ class _$UIStateSerializer implements StructuredSerializer { result.previousRoute = serializers.deserialize(value, specifiedType: const FullType(String))! as String; break; + case 'dismissedFlutterWebWarning': + result.dismissedFlutterWebWarning = serializers.deserialize(value, + specifiedType: const FullType(bool))! as bool; + break; case 'loadingEntityType': result.loadingEntityType = serializers.deserialize(value, specifiedType: const FullType(EntityType)) as EntityType?; @@ -373,6 +380,8 @@ class _$UIState extends UIState { @override final String previousRoute; @override + final bool dismissedFlutterWebWarning; + @override final EntityType? loadingEntityType; @override final BuiltList previewStack; @@ -456,6 +465,7 @@ class _$UIState extends UIState { {required this.selectedCompanyIndex, required this.currentRoute, required this.previousRoute, + required this.dismissedFlutterWebWarning, this.loadingEntityType, required this.previewStack, required this.filterStack, @@ -501,6 +511,8 @@ class _$UIState extends UIState { currentRoute, r'UIState', 'currentRoute'); BuiltValueNullFieldError.checkNotNull( previousRoute, r'UIState', 'previousRoute'); + BuiltValueNullFieldError.checkNotNull( + dismissedFlutterWebWarning, r'UIState', 'dismissedFlutterWebWarning'); BuiltValueNullFieldError.checkNotNull( previewStack, r'UIState', 'previewStack'); BuiltValueNullFieldError.checkNotNull( @@ -589,6 +601,7 @@ class _$UIState extends UIState { selectedCompanyIndex == other.selectedCompanyIndex && currentRoute == other.currentRoute && previousRoute == other.previousRoute && + dismissedFlutterWebWarning == other.dismissedFlutterWebWarning && loadingEntityType == other.loadingEntityType && previewStack == other.previewStack && filterStack == other.filterStack && @@ -637,6 +650,7 @@ class _$UIState extends UIState { _$hash = $jc(_$hash, selectedCompanyIndex.hashCode); _$hash = $jc(_$hash, currentRoute.hashCode); _$hash = $jc(_$hash, previousRoute.hashCode); + _$hash = $jc(_$hash, dismissedFlutterWebWarning.hashCode); _$hash = $jc(_$hash, loadingEntityType.hashCode); _$hash = $jc(_$hash, previewStack.hashCode); _$hash = $jc(_$hash, filterStack.hashCode); @@ -685,6 +699,7 @@ class _$UIState extends UIState { ..add('selectedCompanyIndex', selectedCompanyIndex) ..add('currentRoute', currentRoute) ..add('previousRoute', previousRoute) + ..add('dismissedFlutterWebWarning', dismissedFlutterWebWarning) ..add('loadingEntityType', loadingEntityType) ..add('previewStack', previewStack) ..add('filterStack', filterStack) @@ -744,6 +759,11 @@ class UIStateBuilder implements Builder { set previousRoute(String? previousRoute) => _$this._previousRoute = previousRoute; + bool? _dismissedFlutterWebWarning; + bool? get dismissedFlutterWebWarning => _$this._dismissedFlutterWebWarning; + set dismissedFlutterWebWarning(bool? dismissedFlutterWebWarning) => + _$this._dismissedFlutterWebWarning = dismissedFlutterWebWarning; + EntityType? _loadingEntityType; EntityType? get loadingEntityType => _$this._loadingEntityType; set loadingEntityType(EntityType? loadingEntityType) => @@ -982,6 +1002,7 @@ class UIStateBuilder implements Builder { _selectedCompanyIndex = $v.selectedCompanyIndex; _currentRoute = $v.currentRoute; _previousRoute = $v.previousRoute; + _dismissedFlutterWebWarning = $v.dismissedFlutterWebWarning; _loadingEntityType = $v.loadingEntityType; _previewStack = $v.previewStack.toBuilder(); _filterStack = $v.filterStack.toBuilder(); @@ -1050,6 +1071,10 @@ class UIStateBuilder implements Builder { currentRoute, r'UIState', 'currentRoute'), previousRoute: BuiltValueNullFieldError.checkNotNull( previousRoute, r'UIState', 'previousRoute'), + dismissedFlutterWebWarning: BuiltValueNullFieldError.checkNotNull( + dismissedFlutterWebWarning, + r'UIState', + 'dismissedFlutterWebWarning'), loadingEntityType: loadingEntityType, previewStack: previewStack.build(), filterStack: filterStack.build(), diff --git a/lib/ui/app/dialogs/health_check_dialog.dart b/lib/ui/app/dialogs/health_check_dialog.dart index 53d90414cd..57fff70e77 100644 --- a/lib/ui/app/dialogs/health_check_dialog.dart +++ b/lib/ui/app/dialogs/health_check_dialog.dart @@ -110,6 +110,7 @@ class _HealthCheckDialogState extends State { Widget build(BuildContext context) { final store = StoreProvider.of(context); final state = store.state; + final account = state.account; final localization = AppLocalization.of(context); final webPhpVersion = _parseVersion(_response?.phpVersion.currentPHPVersion ?? ''); @@ -173,7 +174,8 @@ class _HealthCheckDialogState extends State { ), */ if (_response!.filePermissions != 'Ok' && - !state.account.disableAutoUpdate) + !account.disableAutoUpdate && + !account.isDocker) _HealthListTile( title: 'Invalid File Permissions', isValid: false, @@ -181,7 +183,7 @@ class _HealthCheckDialogState extends State { url: '$kDocsUrl/self-host-installation/#file-permissions', ), /* - if (!state.account.isDocker) ...[ + if (!account.isDocker) ...[ if (!_response.openBasedir) _HealthListTile( title: 'Open Basedir', @@ -197,7 +199,7 @@ class _HealthCheckDialogState extends State { ), ], */ - if (!state.account.isDocker && + if (!account.isDocker && phpMemoryLimitDouble! > 100 && phpMemoryLimitDouble < 1024) _HealthListTile( diff --git a/lib/ui/app/important_message_banner.dart b/lib/ui/app/important_message_banner.dart index 817df635af..2a4c868c1a 100644 --- a/lib/ui/app/important_message_banner.dart +++ b/lib/ui/app/important_message_banner.dart @@ -61,6 +61,7 @@ class _ImportantMessageBannerState extends State { if (kIsWeb && !_dismissedMessage.containsKey(MESSAGE_TYPE_FLUTTER_WEB) && + !state.uiState.dismissedFlutterWebWarning && !state.isDemo) { message = localization.flutterWebWarning; messageType = MESSAGE_TYPE_FLUTTER_WEB; @@ -180,6 +181,9 @@ class _ImportantMessageBannerState extends State { color: Colors.white, onPressed: () { setState(() => _dismissedMessage[messageType!] = true); + if (messageType == MESSAGE_TYPE_FLUTTER_WEB) { + store.dispatch(DismissFlutterWebWarning()); + } }, ), ],