User permissions

This commit is contained in:
Hillel Coren 2018-08-16 22:17:04 -07:00
parent 34fa7e00ad
commit c02586d6f6
13 changed files with 275 additions and 82 deletions

View File

@ -1102,6 +1102,55 @@ class _$ClientEntity extends ClientEntity {
isDeleted.hashCode),
id.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('ClientEntity')
..add('lastUpdatedActivities', lastUpdatedActivities)
..add('name', name)
..add('displayName', displayName)
..add('balance', balance)
..add('paidToDate', paidToDate)
..add('address1', address1)
..add('address2', address2)
..add('city', city)
..add('state', state)
..add('postalCode', postalCode)
..add('countryId', countryId)
..add('workPhone', workPhone)
..add('privateNotes', privateNotes)
..add('publicNotes', publicNotes)
..add('website', website)
..add('industryId', industryId)
..add('sizeId', sizeId)
..add('paymentTerms', paymentTerms)
..add('vatNumber', vatNumber)
..add('idNumber', idNumber)
..add('languageId', languageId)
..add('currencyId', currencyId)
..add('invoiceNumberCounter', invoiceNumberCounter)
..add('quoteNumberCounter', quoteNumberCounter)
..add('taskRate', taskRate)
..add('shippingAddress1', shippingAddress1)
..add('shippingAddress2', shippingAddress2)
..add('shippingCity', shippingCity)
..add('shippingState', shippingState)
..add('shippingPostalCode', shippingPostalCode)
..add('shippingCountryId', shippingCountryId)
..add('showTasksInPortal', showTasksInPortal)
..add('sendReminders', sendReminders)
..add('creditNumberCounter', creditNumberCounter)
..add('customValue1', customValue1)
..add('customValue2', customValue2)
..add('contacts', contacts)
..add('activities', activities)
..add('createdAt', createdAt)
..add('updatedAt', updatedAt)
..add('archivedAt', archivedAt)
..add('isDeleted', isDeleted)
..add('id', id))
.toString();
}
}
class ClientEntityBuilder

View File

@ -46,6 +46,7 @@ abstract class CompanyEntity
timezoneId: 1,
customPaymentTerms: BuiltList<PaymentTermEntity>(),
taxRates: BuiltList<TaxRateEntity>(),
userId: 0,
users: BuiltList<UserEntity>(),
userMap: BuiltMap<int, UserEntity>(),
customFields: BuiltMap<String, String>(),
@ -174,6 +175,9 @@ abstract class CompanyEntity
@BuiltValueField(wireName: 'tax_rates')
BuiltList<TaxRateEntity> get taxRates;
@BuiltValueField(wireName: 'user_id')
int get userId;
@BuiltValueField(wireName: 'users')
BuiltList<UserEntity> get users;
@ -227,7 +231,6 @@ abstract class CompanyEntity
@BuiltValueField(wireName: 'email_template_reminder3')
String get emailBodyReminder3;
//@BuiltValueField(wireName: 'custom_messages')
//@BuiltValueField(wireName: 'invoice_labels')
@ -344,5 +347,24 @@ abstract class UserEntity implements Built<UserEntity, UserEntityBuilder> {
String get fullName => (firstName + ' ' + lastName).trim();
@BuiltValueField(wireName: 'is_admin')
bool get isAdmin;
@BuiltValueField(wireName: 'permissions')
BuiltMap<String, bool> get permissionsMap;
bool can(UserPermission permission, EntityType entityType) =>
isAdmin || permissionsMap.containsKey('${permission}_$entityType');
bool canView(EntityType entityType) => can(UserPermission.view, entityType);
bool canEdit(EntityType entityType) => can(UserPermission.edit, entityType);
bool canCreate(EntityType entityType) =>
can(UserPermission.create, entityType);
bool canViewOrCreate(EntityType entityType) =>
canView(entityType) || canCreate(entityType);
static Serializer<UserEntity> get serializer => _$userEntitySerializer;
}

View File

@ -141,6 +141,8 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
serializers.serialize(object.taxRates,
specifiedType:
const FullType(BuiltList, const [const FullType(TaxRateEntity)])),
'user_id',
serializers.serialize(object.userId, specifiedType: const FullType(int)),
'users',
serializers.serialize(object.users,
specifiedType:
@ -361,6 +363,10 @@ class _$CompanyEntitySerializer implements StructuredSerializer<CompanyEntity> {
BuiltList, const [const FullType(TaxRateEntity)]))
as BuiltList);
break;
case 'user_id':
result.userId = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'users':
result.users.replace(serializers.deserialize(value,
specifiedType: const FullType(
@ -602,6 +608,13 @@ class _$UserEntitySerializer implements StructuredSerializer<UserEntity> {
'last_name',
serializers.serialize(object.lastName,
specifiedType: const FullType(String)),
'is_admin',
serializers.serialize(object.isAdmin,
specifiedType: const FullType(bool)),
'permissions',
serializers.serialize(object.permissionsMap,
specifiedType: const FullType(
BuiltMap, const [const FullType(String), const FullType(bool)])),
];
return result;
@ -630,6 +643,17 @@ class _$UserEntitySerializer implements StructuredSerializer<UserEntity> {
result.lastName = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
case 'is_admin':
result.isAdmin = serializers.deserialize(value,
specifiedType: const FullType(bool)) as bool;
break;
case 'permissions':
result.permissionsMap.replace(serializers.deserialize(value,
specifiedType: const FullType(BuiltMap, const [
const FullType(String),
const FullType(bool)
])) as BuiltMap);
break;
}
}
@ -711,6 +735,8 @@ class _$CompanyEntity extends CompanyEntity {
@override
final BuiltList<TaxRateEntity> taxRates;
@override
final int userId;
@override
final BuiltList<UserEntity> users;
@override
final BuiltMap<int, UserEntity> userMap;
@ -787,6 +813,7 @@ class _$CompanyEntity extends CompanyEntity {
this.enableCustomInvoiceTaxes1,
this.enableCustomInvoiceTaxes2,
this.taxRates,
this.userId,
this.users,
this.userMap,
this.customFields,
@ -891,6 +918,8 @@ class _$CompanyEntity extends CompanyEntity {
'CompanyEntity', 'enableCustomInvoiceTaxes2');
if (taxRates == null)
throw new BuiltValueNullFieldError('CompanyEntity', 'taxRates');
if (userId == null)
throw new BuiltValueNullFieldError('CompanyEntity', 'userId');
if (users == null)
throw new BuiltValueNullFieldError('CompanyEntity', 'users');
if (userMap == null)
@ -981,6 +1010,7 @@ class _$CompanyEntity extends CompanyEntity {
enableCustomInvoiceTaxes1 == other.enableCustomInvoiceTaxes1 &&
enableCustomInvoiceTaxes2 == other.enableCustomInvoiceTaxes2 &&
taxRates == other.taxRates &&
userId == other.userId &&
users == other.users &&
userMap == other.userMap &&
customFields == other.customFields &&
@ -1021,8 +1051,8 @@ class _$CompanyEntity extends CompanyEntity {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, name.hashCode), token.hashCode), plan.hashCode), logoUrl.hashCode), currencyId.hashCode), timezoneId.hashCode), countryId.hashCode), dateFormatId.hashCode), datetimeFormatId.hashCode), defaultInvoiceTerms.hashCode), enableInvoiceTaxes.hashCode), enableInvoiceItemTaxes.hashCode), defaultInvoiceDesignId.hashCode), defaultQuoteDesignId.hashCode), languageId.hashCode), defaultInvoiceFooter.hashCode), showInvoiceItemTaxes.hashCode), enableMilitaryTime.hashCode), defaultTaxName1.hashCode), defaultTaxRate1.hashCode), defaultTaxName2.hashCode), defaultTaxRate2.hashCode), defaultQuoteTerms.hashCode), showCurrencyCode.hashCode), enableSecondTaxRate.hashCode), startOfWeek.hashCode), financialYearStart.hashCode), enabledModules.hashCode), defaultPaymentTerms.hashCode), defaultPaymentTypeId.hashCode), defaultTaskRate.hashCode), enableInclusiveTaxes.hashCode), convertProductExchangeRate.hashCode), enableCustomInvoiceTaxes1.hashCode), enableCustomInvoiceTaxes2.hashCode),
taxRates.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, name.hashCode), token.hashCode), plan.hashCode), logoUrl.hashCode), currencyId.hashCode), timezoneId.hashCode), countryId.hashCode), dateFormatId.hashCode), datetimeFormatId.hashCode), defaultInvoiceTerms.hashCode), enableInvoiceTaxes.hashCode), enableInvoiceItemTaxes.hashCode), defaultInvoiceDesignId.hashCode), defaultQuoteDesignId.hashCode), languageId.hashCode), defaultInvoiceFooter.hashCode), showInvoiceItemTaxes.hashCode), enableMilitaryTime.hashCode), defaultTaxName1.hashCode), defaultTaxRate1.hashCode), defaultTaxName2.hashCode), defaultTaxRate2.hashCode), defaultQuoteTerms.hashCode), showCurrencyCode.hashCode), enableSecondTaxRate.hashCode), startOfWeek.hashCode), financialYearStart.hashCode), enabledModules.hashCode), defaultPaymentTerms.hashCode), defaultPaymentTypeId.hashCode), defaultTaskRate.hashCode), enableInclusiveTaxes.hashCode), convertProductExchangeRate.hashCode), enableCustomInvoiceTaxes1.hashCode), enableCustomInvoiceTaxes2.hashCode), taxRates.hashCode),
userId.hashCode),
users.hashCode),
userMap.hashCode),
customFields.hashCode),
@ -1082,6 +1112,7 @@ class _$CompanyEntity extends CompanyEntity {
..add('enableCustomInvoiceTaxes1', enableCustomInvoiceTaxes1)
..add('enableCustomInvoiceTaxes2', enableCustomInvoiceTaxes2)
..add('taxRates', taxRates)
..add('userId', userId)
..add('users', users)
..add('userMap', userMap)
..add('customFields', customFields)
@ -1279,6 +1310,10 @@ class CompanyEntityBuilder
set taxRates(ListBuilder<TaxRateEntity> taxRates) =>
_$this._taxRates = taxRates;
int _userId;
int get userId => _$this._userId;
set userId(int userId) => _$this._userId = userId;
ListBuilder<UserEntity> _users;
ListBuilder<UserEntity> get users =>
_$this._users ??= new ListBuilder<UserEntity>();
@ -1410,6 +1445,7 @@ class CompanyEntityBuilder
_enableCustomInvoiceTaxes1 = _$v.enableCustomInvoiceTaxes1;
_enableCustomInvoiceTaxes2 = _$v.enableCustomInvoiceTaxes2;
_taxRates = _$v.taxRates?.toBuilder();
_userId = _$v.userId;
_users = _$v.users?.toBuilder();
_userMap = _$v.userMap?.toBuilder();
_customFields = _$v.customFields?.toBuilder();
@ -1486,6 +1522,7 @@ class CompanyEntityBuilder
enableCustomInvoiceTaxes1: enableCustomInvoiceTaxes1,
enableCustomInvoiceTaxes2: enableCustomInvoiceTaxes2,
taxRates: taxRates.build(),
userId: userId,
users: users.build(),
userMap: userMap.build(),
customFields: customFields.build(),
@ -1509,6 +1546,7 @@ class CompanyEntityBuilder
try {
_$failedField = 'taxRates';
taxRates.build();
_$failedField = 'users';
users.build();
_$failedField = 'userMap';
@ -1759,16 +1797,30 @@ class _$UserEntity extends UserEntity {
final String firstName;
@override
final String lastName;
@override
final bool isAdmin;
@override
final BuiltMap<String, bool> permissionsMap;
factory _$UserEntity([void updates(UserEntityBuilder b)]) =>
(new UserEntityBuilder()..update(updates)).build();
_$UserEntity._({this.id, this.firstName, this.lastName}) : super._() {
_$UserEntity._(
{this.id,
this.firstName,
this.lastName,
this.isAdmin,
this.permissionsMap})
: super._() {
if (id == null) throw new BuiltValueNullFieldError('UserEntity', 'id');
if (firstName == null)
throw new BuiltValueNullFieldError('UserEntity', 'firstName');
if (lastName == null)
throw new BuiltValueNullFieldError('UserEntity', 'lastName');
if (isAdmin == null)
throw new BuiltValueNullFieldError('UserEntity', 'isAdmin');
if (permissionsMap == null)
throw new BuiltValueNullFieldError('UserEntity', 'permissionsMap');
}
@override
@ -1784,13 +1836,19 @@ class _$UserEntity extends UserEntity {
if (other is! UserEntity) return false;
return id == other.id &&
firstName == other.firstName &&
lastName == other.lastName;
lastName == other.lastName &&
isAdmin == other.isAdmin &&
permissionsMap == other.permissionsMap;
}
@override
int get hashCode {
return $jf(
$jc($jc($jc(0, id.hashCode), firstName.hashCode), lastName.hashCode));
return $jf($jc(
$jc(
$jc($jc($jc(0, id.hashCode), firstName.hashCode),
lastName.hashCode),
isAdmin.hashCode),
permissionsMap.hashCode));
}
@override
@ -1798,7 +1856,9 @@ class _$UserEntity extends UserEntity {
return (newBuiltValueToStringHelper('UserEntity')
..add('id', id)
..add('firstName', firstName)
..add('lastName', lastName))
..add('lastName', lastName)
..add('isAdmin', isAdmin)
..add('permissionsMap', permissionsMap))
.toString();
}
}
@ -1818,6 +1878,16 @@ class UserEntityBuilder implements Builder<UserEntity, UserEntityBuilder> {
String get lastName => _$this._lastName;
set lastName(String lastName) => _$this._lastName = lastName;
bool _isAdmin;
bool get isAdmin => _$this._isAdmin;
set isAdmin(bool isAdmin) => _$this._isAdmin = isAdmin;
MapBuilder<String, bool> _permissionsMap;
MapBuilder<String, bool> get permissionsMap =>
_$this._permissionsMap ??= new MapBuilder<String, bool>();
set permissionsMap(MapBuilder<String, bool> permissionsMap) =>
_$this._permissionsMap = permissionsMap;
UserEntityBuilder();
UserEntityBuilder get _$this {
@ -1825,6 +1895,8 @@ class UserEntityBuilder implements Builder<UserEntity, UserEntityBuilder> {
_id = _$v.id;
_firstName = _$v.firstName;
_lastName = _$v.lastName;
_isAdmin = _$v.isAdmin;
_permissionsMap = _$v.permissionsMap?.toBuilder();
_$v = null;
}
return this;
@ -1843,8 +1915,26 @@ class UserEntityBuilder implements Builder<UserEntity, UserEntityBuilder> {
@override
_$UserEntity build() {
final _$result = _$v ??
new _$UserEntity._(id: id, firstName: firstName, lastName: lastName);
_$UserEntity _$result;
try {
_$result = _$v ??
new _$UserEntity._(
id: id,
firstName: firstName,
lastName: lastName,
isAdmin: isAdmin,
permissionsMap: permissionsMap.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'permissionsMap';
permissionsMap.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'UserEntity', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}

View File

@ -69,6 +69,22 @@ class EmailTemplate extends EnumClass {
static EmailTemplate valueOf(String name) => _$templateValueOf(name);
}
class UserPermission extends EnumClass {
const UserPermission._(String name) : super(name);
static Serializer<UserPermission> get serializer => _$userPermissionSerializer;
static const UserPermission create = _$create;
static const UserPermission edit = _$edit;
static const UserPermission view = _$view;
static BuiltSet<UserPermission> get values => _$permissionValues;
static UserPermission valueOf(String name) => _$permissionValueOf(name);
}
abstract class EntityStatus {
int get id;
String get name;

View File

@ -148,10 +148,36 @@ final BuiltSet<EmailTemplate> _$templateValues =
_$reminder3,
]);
const UserPermission _$create = const UserPermission._('create');
const UserPermission _$edit = const UserPermission._('edit');
const UserPermission _$view = const UserPermission._('view');
UserPermission _$permissionValueOf(String name) {
switch (name) {
case 'create':
return _$create;
case 'edit':
return _$edit;
case 'view':
return _$view;
default:
throw new ArgumentError(name);
}
}
final BuiltSet<UserPermission> _$permissionValues =
new BuiltSet<UserPermission>(const <UserPermission>[
_$create,
_$edit,
_$view,
]);
Serializer<EntityType> _$entityTypeSerializer = new _$EntityTypeSerializer();
Serializer<EntityState> _$entityStateSerializer = new _$EntityStateSerializer();
Serializer<EmailTemplate> _$emailTemplateSerializer =
new _$EmailTemplateSerializer();
Serializer<UserPermission> _$userPermissionSerializer =
new _$UserPermissionSerializer();
Serializer<ErrorMessage> _$errorMessageSerializer =
new _$ErrorMessageSerializer();
Serializer<LoginResponse> _$loginResponseSerializer =
@ -217,6 +243,24 @@ class _$EmailTemplateSerializer implements PrimitiveSerializer<EmailTemplate> {
EmailTemplate.valueOf(serialized as String);
}
class _$UserPermissionSerializer
implements PrimitiveSerializer<UserPermission> {
@override
final Iterable<Type> types = const <Type>[UserPermission];
@override
final String wireName = 'UserPermission';
@override
Object serialize(Serializers serializers, UserPermission object,
{FullType specifiedType = FullType.unspecified}) =>
object.name;
@override
UserPermission deserialize(Serializers serializers, Object serialized,
{FullType specifiedType = FullType.unspecified}) =>
UserPermission.valueOf(serialized as String);
}
class _$ErrorMessageSerializer implements StructuredSerializer<ErrorMessage> {
@override
final Iterable<Type> types = const [ErrorMessage, _$ErrorMessage];

View File

@ -296,6 +296,10 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltList, const [const FullType(VendorEntity)]),
() => new ListBuilder<VendorEntity>())
..addBuilderFactory(
const FullType(
BuiltMap, const [const FullType(String), const FullType(bool)]),
() => new MapBuilder<String, bool>())
..addBuilderFactory(
const FullType(BuiltMap,
const [const FullType(int), const FullType(ClientEntity)]),
@ -320,11 +324,8 @@ Serializers _$serializers = (new Serializers().toBuilder()
const [const FullType(int), const FullType(TimezoneEntity)]),
() => new MapBuilder<int, TimezoneEntity>())
..addBuilderFactory(
const FullType(BuiltMap,
const [const FullType(int), const FullType(DateFormatEntity)]),
() => new MapBuilder<int, DateFormatEntity>())
..addBuilderFactory(
const FullType(BuiltMap, const [const FullType(int), const FullType(DatetimeFormatEntity)]), () => new MapBuilder<int, DatetimeFormatEntity>())
const FullType(BuiltMap, const [const FullType(int), const FullType(DateFormatEntity)]), () => new MapBuilder<int, DateFormatEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(DatetimeFormatEntity)]), () => new MapBuilder<int, DatetimeFormatEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(LanguageEntity)]), () => new MapBuilder<int, LanguageEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(PaymentTypeEntity)]), () => new MapBuilder<int, PaymentTypeEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(int), const FullType(CountryEntity)]), () => new MapBuilder<int, CountryEntity>())

View File

@ -63,7 +63,7 @@ class WebClient {
'X-Ninja-Token': token,
'Content-Type': 'application/json',
},
).timeout(const Duration(seconds: 10));
).timeout(const Duration(seconds: 30));
if (response.statusCode >= 400) {
throw _parseError(response.body);

View File

@ -13,7 +13,6 @@ import 'package:invoiceninja_flutter/redux/static/static_state.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_state.dart';
import 'package:invoiceninja_flutter/ui/app/app_builder.dart';
import 'package:invoiceninja_flutter/ui/auth/login_vm.dart';
import 'package:path/path.dart';
import 'package:redux/redux.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

View File

@ -71,6 +71,7 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
CompanyEntity get selectedCompany => selectedCompanyState.company;
DashboardState get dashboardState => selectedCompanyState.dashboardState;
UserEntity get user => selectedCompany.userMap[selectedCompany.userId];
EntityUIState getUIState(EntityType type) {
switch (type) {
@ -105,6 +106,6 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
String toString() {
//return 'Is Loading: ${this.isLoading}, Invoice: ${this.invoiceUIState.selected}';
//return 'Date Formats: ${staticState.dateFormatMap}';
return 'Route: ${uiState.currentRoute}, Invoice Update: ${invoiceState.lastUpdated}';
return 'Route: ${uiState.currentRoute}, Permissions: ${selectedCompany?.userMap}';
}
}

View File

@ -60,6 +60,7 @@ class AppDrawer extends StatelessWidget {
final Store<AppState> store = StoreProvider.of<AppState>(context);
final NavigatorState navigator = Navigator.of(context);
final user = store.state.user;
final ThemeData themeData = Theme.of(context);
final TextStyle aboutTextStyle = themeData.textTheme.body2;
@ -105,15 +106,20 @@ class AppDrawer extends StatelessWidget {
)),
color: Colors.white10,
),
user.isAdmin
? DrawerTile(
user: user,
icon: FontAwesomeIcons.tachometerAlt,
title: AppLocalization.of(context).dashboard,
onTap: () {
navigator.pop();
store.dispatch(ViewDashboard(context));
},
)
: Container(),
DrawerTile(
icon: FontAwesomeIcons.tachometerAlt,
title: AppLocalization.of(context).dashboard,
onTap: () {
navigator.pop();
store.dispatch(ViewDashboard(context));
},
),
DrawerTile(
user: user,
entityType: EntityType.client,
icon: FontAwesomeIcons.users,
title: AppLocalization.of(context).clients,
onTap: () => store.dispatch(ViewClientList(context)),
@ -124,6 +130,8 @@ class AppDrawer extends StatelessWidget {
},
),
DrawerTile(
user: user,
entityType: EntityType.product,
icon: FontAwesomeIcons.cube,
title: AppLocalization.of(context).products,
onTap: () => store.dispatch(ViewProductList(context)),
@ -134,6 +142,8 @@ class AppDrawer extends StatelessWidget {
},
),
DrawerTile(
user: user,
entityType: EntityType.invoice,
icon: FontAwesomeIcons.filePdfO,
title: AppLocalization.of(context).invoices,
onTap: () => store.dispatch(ViewInvoiceList(context)),
@ -144,6 +154,7 @@ class AppDrawer extends StatelessWidget {
},
),
DrawerTile(
user: user,
icon: FontAwesomeIcons.cog,
title: AppLocalization.of(context).settings,
onTap: () {
@ -195,12 +206,16 @@ class AppDrawer extends StatelessWidget {
class DrawerTile extends StatelessWidget {
const DrawerTile({
this.icon,
this.title,
this.onTap,
@required this.user,
@required this.icon,
@required this.title,
@required this.onTap,
this.onCreateTap,
this.entityType,
});
final UserEntity user;
final EntityType entityType;
final IconData icon;
final String title;
final Function onTap;
@ -208,12 +223,16 @@ class DrawerTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (entityType != null && !user.canViewOrCreate(entityType)) {
return Container();
}
return ListTile(
dense: true,
leading: Icon(icon, size: 22.0),
title: Text(title),
onTap: () => onTap(),
trailing: onCreateTap == null
trailing: onCreateTap == null || !user.canCreate(entityType)
? null
: IconButton(
icon: Icon(Icons.add_circle_outline),

View File

@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/lists/activity_list_tile.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:flutter_html_view/flutter_html_view.dart';
import 'package:invoiceninja_flutter/utils/templates.dart';
class InvoiceEmailView extends StatefulWidget {
@ -172,12 +171,14 @@ class _InvoiceEmailViewState extends State<InvoiceEmailView> {
),
),
),
/*
Container(
//color: Colors.white,
child: HtmlView(
data: emailBody,
),
),
*/
],
),
),

View File

@ -92,13 +92,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "5.5.5"
cached_network_image:
dependency: transitive
description:
name: cached_network_image
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.1+1"
charcode:
dependency: transitive
description:
@ -181,32 +174,11 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_cache_manager:
dependency: transitive
description:
name: flutter_cache_manager
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1"
flutter_custom_tabs:
dependency: transitive
description:
name: flutter_custom_tabs
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
flutter_driver:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_html_view:
dependency: "direct main"
description:
name: flutter_html_view
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.4"
flutter_localizations:
dependency: "direct main"
description: flutter
@ -572,13 +544,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
synchronized:
dependency: transitive
description:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1+1"
term_glyph:
dependency: transitive
description:
@ -614,13 +579,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.0+5"
uuid:
dependency: transitive
description:
name: uuid
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.3"
vector_math:
dependency: transitive
description:
@ -628,13 +586,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
video_player:
dependency: transitive
description:
name: video_player
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
vm_service_client:
dependency: transitive
description:
@ -665,4 +616,4 @@ packages:
version: "2.1.15"
sdks:
dart: ">=2.0.0-dev.65 <=2.0.0-dev.69.5.flutter-eab492385c"
flutter: ">=0.2.5 <2.0.0"
flutter: ">=0.1.4 <2.0.0"

View File

@ -24,7 +24,7 @@ dependencies:
share: ^0.5.2
intl: ^0.15.6
flutter_pdf_viewer: ^0.0.2
flutter_html_view: ^0.5.2
#flutter_html_view: ^0.5.2
google_sign_in: ^3.0.4
firebase_auth: ^0.5.14