This commit is contained in:
Hillel Coren 2019-10-24 10:45:03 +03:00
parent 43e55110f5
commit 5175c272cd
6 changed files with 123 additions and 41 deletions

View File

@ -109,6 +109,10 @@ const String kGatewayTypeCustom3 = '12';
const String kGatewayStripe = 'd14dd26a37cecc30fdd65700bfb55b23'; const String kGatewayStripe = 'd14dd26a37cecc30fdd65700bfb55b23';
const String kClientPortalModeSubdomain = 'subdomain';
const String kClientPortalModeDomain = 'domain';
const String kClientPortalModeIFrame = 'iframe';
const String kEmailDesignPlain = 'plain'; const String kEmailDesignPlain = 'plain';
const String kEmailDesignLight = 'light'; const String kEmailDesignLight = 'light';
const String kEmailDesignDark = 'dark'; const String kEmailDesignDark = 'dark';

View File

@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart'; import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart'; import 'package:built_value/serializer.dart';
import 'package:flutter/foundation.dart';
import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart'; import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart';
@ -50,6 +51,10 @@ abstract class CompanyEntity extends Object
@BuiltValueField(wireName: 'industry_id') @BuiltValueField(wireName: 'industry_id')
String get industryId; String get industryId;
@nullable
@BuiltValueField(wireName: 'portal_mode')
String get portalMode;
// TODO remove this // TODO remove this
@nullable @nullable
String get plan; String get plan;
@ -174,8 +179,13 @@ abstract class CompanyEntity extends Object
} }
} }
bool get isSelfHost => bool get isSelfHost {
appUrl != null && appUrl.isNotEmpty && appUrl != kAppUrl; if (!kReleaseMode) {
return true;
}
return appUrl != null && appUrl.isNotEmpty && appUrl != kAppUrl;
}
bool get isHosted => !isSelfHost; bool get isHosted => !isSelfHost;

View File

@ -62,6 +62,12 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
..add(serializers.serialize(object.industryId, ..add(serializers.serialize(object.industryId,
specifiedType: const FullType(String))); specifiedType: const FullType(String)));
} }
if (object.portalMode != null) {
result
..add('portal_mode')
..add(serializers.serialize(object.portalMode,
specifiedType: const FullType(String)));
}
if (object.plan != null) { if (object.plan != null) {
result result
..add('plan') ..add('plan')
@ -215,6 +221,10 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
result.industryId = serializers.deserialize(value, result.industryId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String; specifiedType: const FullType(String)) as String;
break; break;
case 'portal_mode':
result.portalMode = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'plan': case 'plan':
result.plan = serializers.deserialize(value, result.plan = serializers.deserialize(value,
specifiedType: const FullType(String)) as String; specifiedType: const FullType(String)) as String;
@ -1422,6 +1432,8 @@ class _$CompanyEntity extends CompanyEntity {
@override @override
final String industryId; final String industryId;
@override @override
final String portalMode;
@override
final String plan; final String plan;
@override @override
final String companyKey; final String companyKey;
@ -1476,6 +1488,7 @@ class _$CompanyEntity extends CompanyEntity {
_$CompanyEntity._( _$CompanyEntity._(
{this.sizeId, {this.sizeId,
this.industryId, this.industryId,
this.portalMode,
this.plan, this.plan,
this.companyKey, this.companyKey,
this.appUrl, this.appUrl,
@ -1528,6 +1541,7 @@ class _$CompanyEntity extends CompanyEntity {
return other is CompanyEntity && return other is CompanyEntity &&
sizeId == other.sizeId && sizeId == other.sizeId &&
industryId == other.industryId && industryId == other.industryId &&
portalMode == other.portalMode &&
plan == other.plan && plan == other.plan &&
companyKey == other.companyKey && companyKey == other.companyKey &&
appUrl == other.appUrl && appUrl == other.appUrl &&
@ -1574,7 +1588,7 @@ class _$CompanyEntity extends CompanyEntity {
$jc( $jc(
$jc( $jc(
$jc( $jc(
$jc($jc($jc($jc($jc($jc($jc($jc(0, sizeId.hashCode), industryId.hashCode), plan.hashCode), companyKey.hashCode), appUrl.hashCode), startOfWeek.hashCode), financialYearStart.hashCode), $jc($jc($jc($jc($jc($jc($jc($jc($jc(0, sizeId.hashCode), industryId.hashCode), portalMode.hashCode), plan.hashCode), companyKey.hashCode), appUrl.hashCode), startOfWeek.hashCode), financialYearStart.hashCode),
groups.hashCode), groups.hashCode),
taxRates.hashCode), taxRates.hashCode),
taskStatuses.hashCode), taskStatuses.hashCode),
@ -1601,6 +1615,7 @@ class _$CompanyEntity extends CompanyEntity {
return (newBuiltValueToStringHelper('CompanyEntity') return (newBuiltValueToStringHelper('CompanyEntity')
..add('sizeId', sizeId) ..add('sizeId', sizeId)
..add('industryId', industryId) ..add('industryId', industryId)
..add('portalMode', portalMode)
..add('plan', plan) ..add('plan', plan)
..add('companyKey', companyKey) ..add('companyKey', companyKey)
..add('appUrl', appUrl) ..add('appUrl', appUrl)
@ -1641,6 +1656,10 @@ class CompanyEntityBuilder
String get industryId => _$this._industryId; String get industryId => _$this._industryId;
set industryId(String industryId) => _$this._industryId = industryId; set industryId(String industryId) => _$this._industryId = industryId;
String _portalMode;
String get portalMode => _$this._portalMode;
set portalMode(String portalMode) => _$this._portalMode = portalMode;
String _plan; String _plan;
String get plan => _$this._plan; String get plan => _$this._plan;
set plan(String plan) => _$this._plan = plan; set plan(String plan) => _$this._plan = plan;
@ -1766,6 +1785,7 @@ class CompanyEntityBuilder
if (_$v != null) { if (_$v != null) {
_sizeId = _$v.sizeId; _sizeId = _$v.sizeId;
_industryId = _$v.industryId; _industryId = _$v.industryId;
_portalMode = _$v.portalMode;
_plan = _$v.plan; _plan = _$v.plan;
_companyKey = _$v.companyKey; _companyKey = _$v.companyKey;
_appUrl = _$v.appUrl; _appUrl = _$v.appUrl;
@ -1816,6 +1836,7 @@ class CompanyEntityBuilder
new _$CompanyEntity._( new _$CompanyEntity._(
sizeId: sizeId, sizeId: sizeId,
industryId: industryId, industryId: industryId,
portalMode: portalMode,
plan: plan, plan: plan,
companyKey: companyKey, companyKey: companyKey,
appUrl: appUrl, appUrl: appUrl,

View File

@ -1,10 +1,15 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.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/ui/app/form_card.dart'; import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/forms/app_form.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/decorated_form_field.dart'; import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
import 'package:invoiceninja_flutter/ui/settings/client_portal_vm.dart'; import 'package:invoiceninja_flutter/ui/settings/client_portal_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/settings_scaffold.dart'; import 'package:invoiceninja_flutter/ui/settings/settings_scaffold.dart';
import 'package:invoiceninja_flutter/utils/icons.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class ClientPortal extends StatefulWidget { class ClientPortal extends StatefulWidget {
@ -86,6 +91,8 @@ class _ClientPortalState extends State<ClientPortal>
final localization = AppLocalization.of(context); final localization = AppLocalization.of(context);
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final state = viewModel.state; final state = viewModel.state;
final company = viewModel.company;
final settings = viewModel.settings;
return SettingsScaffold( return SettingsScaffold(
title: localization.clientPortal, title: localization.clientPortal,
@ -112,38 +119,84 @@ class _ClientPortalState extends State<ClientPortal>
children: <Widget>[ children: <Widget>[
ListView( ListView(
children: <Widget>[ children: <Widget>[
if (!state.settingsUIState.isFiltered)
FormCard( FormCard(
children: <Widget>[ children: <Widget>[
InputDecorator( InputDecorator(
decoration: InputDecoration( decoration: InputDecoration(
labelText: localization.linkType, labelText: localization.portalMode,
), ),
//isEmpty: false, //isEmpty: false,
child: DropdownButtonHideUnderline( child: DropdownButtonHideUnderline(
child: DropdownButton<String>( child: DropdownButton<String>(
//value: companyGateway.gatewayTypeId, value: viewModel.company.portalMode,
isExpanded: true, isExpanded: true,
isDense: true, isDense: true,
//onChanged: (value) => viewModel.onChanged(companyGateway.rebuild((b) => b..gatewayTypeId = value)), onChanged: (value) => viewModel.onCompanyChanged(
items: []), viewModel.company
.rebuild((b) => b..portalMode = value)),
items: [
DropdownMenuItem(
child: Text(localization.subdomain),
value: kClientPortalModeSubdomain,
),
if (company.isEnterprisePlan)
DropdownMenuItem(
child: Text(localization.domain),
value: kClientPortalModeDomain,
),
DropdownMenuItem(
child: Text('iFrame'),
value: kClientPortalModeIFrame,
),
]),
), ),
), ),
DecoratedFormField( DecoratedFormField(
label: localization.subdomain, label: localization.subdomain,
controller: _subdomainController, controller: _subdomainController,
), ),
if (company.portalMode == kClientPortalModeDomain &&
company.isEnterprisePlan)
DecoratedFormField( DecoratedFormField(
label: localization.domain, label: localization.domain,
controller: _domainController, controller: _domainController,
keyboardType: TextInputType.url, keyboardType: TextInputType.url,
), ),
if (company.portalMode == kClientPortalModeIFrame)
DecoratedFormField( DecoratedFormField(
label: 'iFrame', label: 'iFrame',
controller: _iFrameController, controller: _iFrameController,
keyboardType: TextInputType.url, keyboardType: TextInputType.url,
), ),
], ],
) ),
FormCard(
children: <Widget>[
BoolDropdownButton(
label: localization.clientPortal,
value: false,
showBlank: state.settingsUIState.isFiltered,
iconData: FontAwesomeIcons.cloud,
onChanged: (value) => null,
),
BoolDropdownButton(
label: localization.dashboard,
value: false,
showBlank: state.settingsUIState.isFiltered,
iconData: FontAwesomeIcons.tachometerAlt,
onChanged: (value) => null,
),
BoolDropdownButton(
label: localization.tasks,
value: settings.showTasksInPortal,
showBlank: state.settingsUIState.isFiltered,
iconData: getEntityIcon(EntityType.task),
onChanged: (value) => viewModel.onSettingsChanged(
settings.rebuild((b) => b..showTasksInPortal = value)),
),
],
),
], ],
), ),
ListView(), ListView(),

View File

@ -13,7 +13,6 @@ import 'package:invoiceninja_flutter/ui/settings/email_settings_vm.dart';
import 'package:invoiceninja_flutter/ui/settings/settings_scaffold.dart'; import 'package:invoiceninja_flutter/ui/settings/settings_scaffold.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:zefyr/zefyr.dart'; import 'package:zefyr/zefyr.dart';
import 'package:quill_delta/quill_delta.dart';
class EmailSettings extends StatefulWidget { class EmailSettings extends StatefulWidget {
const EmailSettings({ const EmailSettings({
@ -76,10 +75,10 @@ class _EmailSettingsState extends State<EmailSettings>
.forEach((dynamic controller) => controller.removeListener(_onChanged)); .forEach((dynamic controller) => controller.removeListener(_onChanged));
final settings = widget.viewModel.settings; final settings = widget.viewModel.settings;
final signature = settings.emailFooter ?? ''; final signature = settings.emailFooter;
// return NotusDocument.fromJson(jsonDecode(contents)); // return NotusDocument.fromJson(jsonDecode(contents));
final doc = NotusDocument.fromJson(jsonDecode(signature)); final doc = signature != null ? NotusDocument.fromJson(jsonDecode(signature)) : NotusDocument();
_zefyrController = ZefyrController(doc)..addListener(_onZefyrChanged); _zefyrController = ZefyrController(doc)..addListener(_onZefyrChanged);
//_zefyrController.compose(Delta()..insert(signature)); //_zefyrController.compose(Delta()..insert(signature));
@ -219,7 +218,7 @@ class _EmailSettingsState extends State<EmailSettings>
], ],
), ),
Container( Container(
color: Colors.white, color: Colors.grey.shade100,
child: _zefyrController == null child: _zefyrController == null
? LoadingIndicator() ? LoadingIndicator()
: ZefyrScaffold( : ZefyrScaffold(
@ -227,6 +226,7 @@ class _EmailSettingsState extends State<EmailSettings>
padding: EdgeInsets.all(16), padding: EdgeInsets.all(16),
controller: _zefyrController, controller: _zefyrController,
focusNode: _zefyrNode, focusNode: _zefyrNode,
autofocus: false,
), ),
), ),
), ),

View File

@ -16,9 +16,7 @@ mixin LocalizationsProvider on LocaleCodeAware {
'en': { 'en': {
'subdomain': 'Subdomain', 'subdomain': 'Subdomain',
'domain': 'Domain', 'domain': 'Domain',
'link_type': 'Link Type', 'portal_mode': 'Portal Mode',
'custom_subdomain': 'Custom Subdomain',
'custom_domain': 'Custom Domain',
'email_signature': 'Email Signature', 'email_signature': 'Email Signature',
'enable_email_markup_help': 'enable_email_markup_help':
'Make it easier for your clients to pay you by adding schema.org markup to your emails.', 'Make it easier for your clients to pay you by adding schema.org markup to your emails.',
@ -15056,11 +15054,7 @@ mixin LocalizationsProvider on LocaleCodeAware {
String get emailSignature => _localizedValues[localeCode]['email_signature']; String get emailSignature => _localizedValues[localeCode]['email_signature'];
String get linkType => _localizedValues[localeCode]['link_type']; String get portalMode => _localizedValues[localeCode]['portal_mode'];
String get customSubdomain => _localizedValues[localeCode]['custom_subdomain'];
String get customDomain => _localizedValues[localeCode]['custom_domain'];
String get domain => _localizedValues[localeCode]['domain']; String get domain => _localizedValues[localeCode]['domain'];