Add CTA to add a gateway (for admins w/o gateways)

This commit is contained in:
Hillel Coren 2022-05-27 12:32:03 +03:00
parent 225742d92a
commit 5ede246086
6 changed files with 105 additions and 16 deletions

View File

@ -89,6 +89,8 @@ class DismissNativeWarning implements PersistUI {}
class DismissNativeWarningPermanently implements PersistUI, PersistPrefs {} class DismissNativeWarningPermanently implements PersistUI, PersistPrefs {}
class DismissGatewayWarningPermanently implements PersistUI, PersistPrefs {}
class ViewMainScreen { class ViewMainScreen {
ViewMainScreen({this.addDelay = false}); ViewMainScreen({this.addDelay = false});

View File

@ -57,6 +57,8 @@ PrefState prefReducer(
historySidebarReducer(state.historySidebarMode, action) historySidebarReducer(state.historySidebarMode, action)
..hideDesktopWarning = ..hideDesktopWarning =
hideDesktopWarningReducer(state.hideDesktopWarning, action) hideDesktopWarningReducer(state.hideDesktopWarning, action)
..hideGatewayWarning =
hideGatewayWarningReducer(state.hideGatewayWarning, action)
..textScaleFactor = textScaleFactorReducer(state.textScaleFactor, action) ..textScaleFactor = textScaleFactorReducer(state.textScaleFactor, action)
..isMenuVisible = menuVisibleReducer(state.isMenuVisible, action) ..isMenuVisible = menuVisibleReducer(state.isMenuVisible, action)
..isHistoryVisible = historyVisibleReducer(state.isHistoryVisible, action) ..isHistoryVisible = historyVisibleReducer(state.isHistoryVisible, action)
@ -218,6 +220,12 @@ Reducer<bool> hideDesktopWarningReducer = combineReducers([
}), }),
]); ]);
Reducer<bool> hideGatewayWarningReducer = combineReducers([
TypedReducer<bool, DismissGatewayWarningPermanently>((filter, action) {
return true;
}),
]);
Reducer<int> filterClearedAtReducer = combineReducers([ Reducer<int> filterClearedAtReducer = combineReducers([
TypedReducer<int, FilterCompany>((filterClearedAt, action) { TypedReducer<int, FilterCompany>((filterClearedAt, action) {
return action.filter == null return action.filter == null

View File

@ -37,6 +37,7 @@ abstract class PrefState implements Built<PrefState, PrefStateBuilder> {
longPressSelectionIsDefault: true, longPressSelectionIsDefault: true,
tapSelectedToEdit: false, tapSelectedToEdit: false,
hideDesktopWarning: false, hideDesktopWarning: false,
hideGatewayWarning: false,
showKanban: false, showKanban: false,
showPdfPreview: true, showPdfPreview: true,
persistData: false, persistData: false,
@ -139,6 +140,8 @@ abstract class PrefState implements Built<PrefState, PrefStateBuilder> {
bool get hideDesktopWarning; bool get hideDesktopWarning;
bool get hideGatewayWarning;
bool get editAfterSaving; bool get editAfterSaving;
double get textScaleFactor; double get textScaleFactor;
@ -206,6 +209,7 @@ abstract class PrefState implements Built<PrefState, PrefStateBuilder> {
..isPreviewVisible = false ..isPreviewVisible = false
..isFilterVisible = false ..isFilterVisible = false
..hideDesktopWarning = false ..hideDesktopWarning = false
..hideGatewayWarning = false
..tapSelectedToEdit = false ..tapSelectedToEdit = false
..persistData = false ..persistData = false
..persistUI = true ..persistUI = true

View File

@ -187,6 +187,9 @@ class _$PrefStateSerializer implements StructuredSerializer<PrefState> {
'hideDesktopWarning', 'hideDesktopWarning',
serializers.serialize(object.hideDesktopWarning, serializers.serialize(object.hideDesktopWarning,
specifiedType: const FullType(bool)), specifiedType: const FullType(bool)),
'hideGatewayWarning',
serializers.serialize(object.hideGatewayWarning,
specifiedType: const FullType(bool)),
'editAfterSaving', 'editAfterSaving',
serializers.serialize(object.editAfterSaving, serializers.serialize(object.editAfterSaving,
specifiedType: const FullType(bool)), specifiedType: const FullType(bool)),
@ -319,6 +322,10 @@ class _$PrefStateSerializer implements StructuredSerializer<PrefState> {
result.hideDesktopWarning = serializers.deserialize(value, result.hideDesktopWarning = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool; specifiedType: const FullType(bool)) as bool;
break; break;
case 'hideGatewayWarning':
result.hideGatewayWarning = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'editAfterSaving': case 'editAfterSaving':
result.editAfterSaving = serializers.deserialize(value, result.editAfterSaving = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool; specifiedType: const FullType(bool)) as bool;
@ -620,6 +627,8 @@ class _$PrefState extends PrefState {
@override @override
final bool hideDesktopWarning; final bool hideDesktopWarning;
@override @override
final bool hideGatewayWarning;
@override
final bool editAfterSaving; final bool editAfterSaving;
@override @override
final double textScaleFactor; final double textScaleFactor;
@ -656,6 +665,7 @@ class _$PrefState extends PrefState {
this.enableTooltips, this.enableTooltips,
this.colorTheme, this.colorTheme,
this.hideDesktopWarning, this.hideDesktopWarning,
this.hideGatewayWarning,
this.editAfterSaving, this.editAfterSaving,
this.textScaleFactor, this.textScaleFactor,
this.sortFields, this.sortFields,
@ -707,6 +717,8 @@ class _$PrefState extends PrefState {
colorTheme, 'PrefState', 'colorTheme'); colorTheme, 'PrefState', 'colorTheme');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
hideDesktopWarning, 'PrefState', 'hideDesktopWarning'); hideDesktopWarning, 'PrefState', 'hideDesktopWarning');
BuiltValueNullFieldError.checkNotNull(
hideGatewayWarning, 'PrefState', 'hideGatewayWarning');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
editAfterSaving, 'PrefState', 'editAfterSaving'); editAfterSaving, 'PrefState', 'editAfterSaving');
BuiltValueNullFieldError.checkNotNull( BuiltValueNullFieldError.checkNotNull(
@ -752,6 +764,7 @@ class _$PrefState extends PrefState {
enableTooltips == other.enableTooltips && enableTooltips == other.enableTooltips &&
colorTheme == other.colorTheme && colorTheme == other.colorTheme &&
hideDesktopWarning == other.hideDesktopWarning && hideDesktopWarning == other.hideDesktopWarning &&
hideGatewayWarning == other.hideGatewayWarning &&
editAfterSaving == other.editAfterSaving && editAfterSaving == other.editAfterSaving &&
textScaleFactor == other.textScaleFactor && textScaleFactor == other.textScaleFactor &&
sortFields == other.sortFields && sortFields == other.sortFields &&
@ -779,22 +792,22 @@ class _$PrefState extends PrefState {
$jc( $jc(
$jc( $jc(
$jc( $jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, appLayout.hashCode), moduleLayout.hashCode), menuSidebarMode.hashCode), historySidebarMode.hashCode), useSidebarEditor.hashCode), customColors.hashCode), isPreviewVisible.hashCode), isMenuVisible.hashCode), showKanban.hashCode), $jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, appLayout.hashCode), moduleLayout.hashCode), menuSidebarMode.hashCode), historySidebarMode.hashCode), useSidebarEditor.hashCode), customColors.hashCode), isPreviewVisible.hashCode), isMenuVisible.hashCode), showKanban.hashCode), showPdfPreview.hashCode),
showPdfPreview.hashCode), enableTouchEvents.hashCode),
enableTouchEvents.hashCode), isHistoryVisible.hashCode),
isHistoryVisible.hashCode), enableDarkMode.hashCode),
enableDarkMode.hashCode), isFilterVisible.hashCode),
isFilterVisible.hashCode), persistData.hashCode),
persistData.hashCode), persistUI.hashCode),
persistUI.hashCode), longPressSelectionIsDefault.hashCode),
longPressSelectionIsDefault.hashCode), requireAuthentication.hashCode),
requireAuthentication.hashCode), tapSelectedToEdit.hashCode),
tapSelectedToEdit.hashCode), enableJSPDF.hashCode),
enableJSPDF.hashCode), rowsPerPage.hashCode),
rowsPerPage.hashCode), enableTooltips.hashCode),
enableTooltips.hashCode), colorTheme.hashCode),
colorTheme.hashCode), hideDesktopWarning.hashCode),
hideDesktopWarning.hashCode), hideGatewayWarning.hashCode),
editAfterSaving.hashCode), editAfterSaving.hashCode),
textScaleFactor.hashCode), textScaleFactor.hashCode),
sortFields.hashCode), sortFields.hashCode),
@ -828,6 +841,7 @@ class _$PrefState extends PrefState {
..add('enableTooltips', enableTooltips) ..add('enableTooltips', enableTooltips)
..add('colorTheme', colorTheme) ..add('colorTheme', colorTheme)
..add('hideDesktopWarning', hideDesktopWarning) ..add('hideDesktopWarning', hideDesktopWarning)
..add('hideGatewayWarning', hideGatewayWarning)
..add('editAfterSaving', editAfterSaving) ..add('editAfterSaving', editAfterSaving)
..add('textScaleFactor', textScaleFactor) ..add('textScaleFactor', textScaleFactor)
..add('sortFields', sortFields) ..add('sortFields', sortFields)
@ -954,6 +968,11 @@ class PrefStateBuilder implements Builder<PrefState, PrefStateBuilder> {
set hideDesktopWarning(bool hideDesktopWarning) => set hideDesktopWarning(bool hideDesktopWarning) =>
_$this._hideDesktopWarning = hideDesktopWarning; _$this._hideDesktopWarning = hideDesktopWarning;
bool _hideGatewayWarning;
bool get hideGatewayWarning => _$this._hideGatewayWarning;
set hideGatewayWarning(bool hideGatewayWarning) =>
_$this._hideGatewayWarning = hideGatewayWarning;
bool _editAfterSaving; bool _editAfterSaving;
bool get editAfterSaving => _$this._editAfterSaving; bool get editAfterSaving => _$this._editAfterSaving;
set editAfterSaving(bool editAfterSaving) => set editAfterSaving(bool editAfterSaving) =>
@ -1007,6 +1026,7 @@ class PrefStateBuilder implements Builder<PrefState, PrefStateBuilder> {
_enableTooltips = $v.enableTooltips; _enableTooltips = $v.enableTooltips;
_colorTheme = $v.colorTheme; _colorTheme = $v.colorTheme;
_hideDesktopWarning = $v.hideDesktopWarning; _hideDesktopWarning = $v.hideDesktopWarning;
_hideGatewayWarning = $v.hideGatewayWarning;
_editAfterSaving = $v.editAfterSaving; _editAfterSaving = $v.editAfterSaving;
_textScaleFactor = $v.textScaleFactor; _textScaleFactor = $v.textScaleFactor;
_sortFields = $v.sortFields.toBuilder(); _sortFields = $v.sortFields.toBuilder();
@ -1065,6 +1085,7 @@ class PrefStateBuilder implements Builder<PrefState, PrefStateBuilder> {
enableTooltips: BuiltValueNullFieldError.checkNotNull(enableTooltips, 'PrefState', 'enableTooltips'), enableTooltips: BuiltValueNullFieldError.checkNotNull(enableTooltips, 'PrefState', 'enableTooltips'),
colorTheme: BuiltValueNullFieldError.checkNotNull(colorTheme, 'PrefState', 'colorTheme'), colorTheme: BuiltValueNullFieldError.checkNotNull(colorTheme, 'PrefState', 'colorTheme'),
hideDesktopWarning: BuiltValueNullFieldError.checkNotNull(hideDesktopWarning, 'PrefState', 'hideDesktopWarning'), hideDesktopWarning: BuiltValueNullFieldError.checkNotNull(hideDesktopWarning, 'PrefState', 'hideDesktopWarning'),
hideGatewayWarning: BuiltValueNullFieldError.checkNotNull(hideGatewayWarning, 'PrefState', 'hideGatewayWarning'),
editAfterSaving: BuiltValueNullFieldError.checkNotNull(editAfterSaving, 'PrefState', 'editAfterSaving'), editAfterSaving: BuiltValueNullFieldError.checkNotNull(editAfterSaving, 'PrefState', 'editAfterSaving'),
textScaleFactor: BuiltValueNullFieldError.checkNotNull(textScaleFactor, 'PrefState', 'textScaleFactor'), textScaleFactor: BuiltValueNullFieldError.checkNotNull(textScaleFactor, 'PrefState', 'textScaleFactor'),
sortFields: sortFields.build(), sortFields: sortFields.build(),

View File

@ -7,10 +7,13 @@ import 'package:flutter/material.dart';
// Package imports: // Package imports:
import 'package:charts_common/common.dart'; import 'package:charts_common/common.dart';
import 'package:charts_flutter/flutter.dart' as charts; import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/task/task_actions.dart'; import 'package:invoiceninja_flutter/redux/task/task_actions.dart';
import 'package:invoiceninja_flutter/ui/app/actions_menu_button.dart'; import 'package:invoiceninja_flutter/ui/app/actions_menu_button.dart';
import 'package:invoiceninja_flutter/ui/app/app_border.dart'; import 'package:invoiceninja_flutter/ui/app/app_border.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/live_text.dart'; import 'package:invoiceninja_flutter/ui/app/live_text.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
@ -407,6 +410,7 @@ class DashboardPanels extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final state = viewModel.state; final state = viewModel.state;
final company = state.company; final company = state.company;
final localization = AppLocalization.of(context);
if (!state.staticState.isLoaded) { if (!state.staticState.isLoaded) {
return LoadingIndicator(); return LoadingIndicator();
@ -466,6 +470,7 @@ class DashboardPanels extends StatelessWidget {
} }
final entityTypes = [ final entityTypes = [
EntityType.dashboard,
if (company.isModuleEnabled(EntityType.task) && runningTasks.isNotEmpty) if (company.isModuleEnabled(EntityType.task) && runningTasks.isNotEmpty)
EntityType.taskStatus, EntityType.taskStatus,
if (company.isModuleEnabled(EntityType.invoice)) EntityType.invoice, if (company.isModuleEnabled(EntityType.invoice)) EntityType.invoice,
@ -490,6 +495,42 @@ class DashboardPanels extends StatelessWidget {
} }
switch (entityTypes[index]) { switch (entityTypes[index]) {
case EntityType.dashboard:
if (!state.userCompany.isAdmin ||
state.prefState.hideGatewayWarning ||
state.companyGatewayState.list.isNotEmpty) {
return SizedBox();
}
return Padding(
padding: const EdgeInsets.only(top: 8),
child: FormCard(
child: Row(
children: [
Expanded(
child: Text(localization.addGatewayHelpMessage),
),
TextButton(
onPressed: () {
createEntityByType(
context: context,
entityType: EntityType.companyGateway,
);
},
child: Text(localization.addGateway)),
IconButton(
onPressed: () {
final store = StoreProvider.of<AppState>(context);
store
.dispatch(DismissGatewayWarningPermanently());
},
icon: Icon(
Icons.clear,
color: Colors.grey,
))
],
)),
);
case EntityType.invoice: case EntityType.invoice:
return _InvoiceChart( return _InvoiceChart(
viewModel: viewModel, viewModel: viewModel,

View File

@ -16,6 +16,9 @@ mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = { static final Map<String, Map<String, String>> _localizedValues = {
'en': { 'en': {
// STARTER: lang key - do not remove comment // STARTER: lang key - do not remove comment
'add_gateway': 'Add Gateway',
'add_gateway_help_message':
'Add a payment gateway (ie. Stripe, WePay or PayPal) to accept online payments',
'left': 'Left', 'left': 'Left',
'right': 'Right', 'right': 'Right',
'center': 'Center', 'center': 'Center',
@ -70508,12 +70511,22 @@ mixin LocalizationsProvider on LocaleCodeAware {
String get left => String get left =>
_localizedValues[localeCode]['left'] ?? _localizedValues['en']['left']; _localizedValues[localeCode]['left'] ?? _localizedValues['en']['left'];
String get right => String get right =>
_localizedValues[localeCode]['right'] ?? _localizedValues['en']['right']; _localizedValues[localeCode]['right'] ?? _localizedValues['en']['right'];
String get center => String get center =>
_localizedValues[localeCode]['center'] ?? _localizedValues[localeCode]['center'] ??
_localizedValues['en']['center']; _localizedValues['en']['center'];
String get addGateway =>
_localizedValues[localeCode]['add_gateway'] ??
_localizedValues['en']['add_gateway'];
String get addGatewayHelpMessage =>
_localizedValues[localeCode]['add_gateway_help_message'] ??
_localizedValues['en']['add_gateway_help_message'];
// STARTER: lang field - do not remove comment // STARTER: lang field - do not remove comment
String lookup(String key) { String lookup(String key) {