This commit is contained in:
Hillel Coren 2018-12-13 22:44:16 +02:00
parent 753e0e8590
commit 4763b8cba7
12 changed files with 106 additions and 178 deletions

View File

@ -367,7 +367,7 @@ abstract class ClientEntity extends Object
actions.add(null); actions.add(null);
} }
return actions..addAll(getEntityBaseActions(user: user)); return actions..addAll(getBaseActions(user: user));
} }
@override @override

View File

@ -136,7 +136,7 @@ abstract class BaseEntity implements SelectableEntity {
bool get isArchived => archivedAt != null && !isDeleted; bool get isArchived => archivedAt != null && !isDeleted;
List<EntityAction> getEntityBaseActions({UserEntity user}) { List<EntityAction> getBaseActions({UserEntity user}) {
final actions = <EntityAction>[]; final actions = <EntityAction>[];
if (user.canEditEntity(this) && (isArchived || isDeleted)) { if (user.canEditEntity(this) && (isArchived || isDeleted)) {

View File

@ -420,7 +420,7 @@ abstract class InvoiceEntity extends Object
actions.add(null); actions.add(null);
} }
return actions..addAll(getEntityBaseActions(user: user)); return actions..addAll(getBaseActions(user: user));
} }
InvoiceEntity applyTax(TaxRateEntity taxRate) { InvoiceEntity applyTax(TaxRateEntity taxRate) {

View File

@ -186,7 +186,7 @@ abstract class PaymentEntity extends Object
actions.add(null); actions.add(null);
} }
return actions..addAll(getEntityBaseActions(user: user)); return actions..addAll(getBaseActions(user: user));
} }
@override @override

View File

@ -205,7 +205,7 @@ abstract class ProductEntity extends Object
actions.add(null); actions.add(null);
} }
return actions..addAll(getEntityBaseActions(user: user)); return actions..addAll(getBaseActions(user: user));
} }
static Serializer<ProductEntity> get serializer => _$productEntitySerializer; static Serializer<ProductEntity> get serializer => _$productEntitySerializer;

View File

@ -2,6 +2,7 @@ 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:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart'; import 'package:invoiceninja_flutter/utils/formatting.dart';
part 'project_model.g.dart'; part 'project_model.g.dart';
@ -101,6 +102,12 @@ abstract class ProjectEntity extends Object
@BuiltValueField(wireName: 'custom_value2') @BuiltValueField(wireName: 'custom_value2')
String get customValue2; String get customValue2;
List<EntityAction> getEntityActions({UserEntity user, ClientEntity client}) {
final actions = <EntityAction>[];
return actions..addAll(getBaseActions(user: user));
}
int compareTo(ProjectEntity project, String sortField, bool sortAscending) { int compareTo(ProjectEntity project, String sortField, bool sortAscending) {
int response = 0; int response = 0;
final ProjectEntity projectA = sortAscending ? this : project; final ProjectEntity projectA = sortAscending ? this : project;

View File

@ -132,7 +132,7 @@ class _ProjectEditState extends State<ProjectEdit> {
entityList: memoizedDropdownClientList( entityList: memoizedDropdownClientList(
state.clientState.map, state.clientState.list), state.clientState.map, state.clientState.list),
validator: (String val) => val.trim().isEmpty validator: (String val) => val.trim().isEmpty
? AppLocalization.of(context).pleaseSelectAClient ? localization.pleaseSelectAClient
: null, : null,
onSelected: (clientId) { onSelected: (clientId) {
viewModel.onChanged( viewModel.onChanged(
@ -146,7 +146,7 @@ class _ProjectEditState extends State<ProjectEdit> {
autocorrect: false, autocorrect: false,
controller: _nameController, controller: _nameController,
validator: (String val) => val.trim().isEmpty validator: (String val) => val.trim().isEmpty
? AppLocalization.of(context).pleaseEnterAName ? localization.pleaseEnterAName
: null, : null,
decoration: InputDecoration( decoration: InputDecoration(
labelText: localization.name, labelText: localization.name,

View File

@ -9,7 +9,6 @@ import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart'; import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:invoiceninja_flutter/ui/project/project_screen.dart'; import 'package:invoiceninja_flutter/ui/project/project_screen.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/project/project_actions.dart'; import 'package:invoiceninja_flutter/redux/project/project_actions.dart';

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:invoiceninja_flutter/ui/project/project_list_item.dart'; import 'package:invoiceninja_flutter/ui/project/project_list_item.dart';
import 'package:invoiceninja_flutter/ui/project/project_list_vm.dart'; import 'package:invoiceninja_flutter/ui/project/project_list_vm.dart';
import 'package:invoiceninja_flutter/utils/icons.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class ProjectList extends StatelessWidget { class ProjectList extends StatelessWidget {
@ -34,48 +35,34 @@ class ProjectList extends StatelessWidget {
return _buildListView(context); return _buildListView(context);
} }
void _showMenu(BuildContext context, ProjectEntity project) async { void _showMenu(
BuildContext context, ProjectEntity project) async {
if (project == null) { if (project == null) {
return; return;
} }
final user = viewModel.user; final user = viewModel.user;
final message = await showDialog<String>( final message = await showDialog<String>(
context: context, context: context,
builder: (BuildContext context) => SimpleDialog(children: <Widget>[ builder: (BuildContext dialogContext) => SimpleDialog(
user.canCreate(EntityType.project) children: project
? ListTile( .getEntityActions(user: user)
leading: Icon(Icons.control_point_duplicate), .map((entityAction) {
title: Text(AppLocalization.of(context).clone), if (entityAction == null) {
onTap: () => viewModel.onEntityAction( return Divider();
context, project, EntityAction.clone), } else {
) return ListTile(
: Container(), leading: Icon(getEntityActionIcon(entityAction)),
Divider(), title: Text(AppLocalization.of(context)
user.canEditEntity(project) && !project.isActive .lookup(entityAction.toString())),
? ListTile( onTap: () {
leading: Icon(Icons.restore), Navigator.of(dialogContext).pop();
title: Text(AppLocalization.of(context).restore), viewModel.onEntityAction(context, project, entityAction);
onTap: () => viewModel.onEntityAction( },
context, project, EntityAction.restore), );
) }
: Container(), }).toList()));
user.canEditEntity(project) && project.isActive
? ListTile(
leading: Icon(Icons.archive),
title: Text(AppLocalization.of(context).archive),
onTap: () => viewModel.onEntityAction(
context, project, EntityAction.archive),
)
: Container(),
user.canEditEntity(project) && !project.isDeleted
? ListTile(
leading: Icon(Icons.delete),
title: Text(AppLocalization.of(context).delete),
onTap: () => viewModel.onEntityAction(
context, project, EntityAction.delete),
)
: Container(),
]));
if (message != null) { if (message != null) {
Scaffold.of(context).showSnackBar(SnackBar( Scaffold.of(context).showSnackBar(SnackBar(
content: SnackBarRow( content: SnackBarRow(

View File

@ -38,7 +38,6 @@ class ProjectListVM {
@required this.isLoading, @required this.isLoading,
@required this.isLoaded, @required this.isLoaded,
@required this.onProjectTap, @required this.onProjectTap,
@required this.onDismissed,
@required this.onRefreshed, @required this.onRefreshed,
@required this.onEntityAction, @required this.onEntityAction,
}); });
@ -76,50 +75,26 @@ class ProjectListVM {
break; break;
case EntityAction.restore: case EntityAction.restore:
store.dispatch(RestoreProjectRequest( store.dispatch(RestoreProjectRequest(
popCompleter( snackBarCompleter(
context, AppLocalization.of(context).restoredProject), context, AppLocalization.of(context).restoredProject),
project.id)); project.id));
break; break;
case EntityAction.archive: case EntityAction.archive:
store.dispatch(ArchiveProjectRequest( store.dispatch(ArchiveProjectRequest(
popCompleter( snackBarCompleter(
context, AppLocalization.of(context).archivedProject), context, AppLocalization.of(context).archivedProject),
project.id)); project.id));
break; break;
case EntityAction.delete: case EntityAction.delete:
store.dispatch(DeleteProjectRequest( store.dispatch(DeleteProjectRequest(
popCompleter( snackBarCompleter(
context, AppLocalization.of(context).deletedProject), context, AppLocalization.of(context).deletedProject),
project.id)); project.id));
break; break;
} }
}, },
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
onDismissed: (BuildContext context, ProjectEntity project, );
DismissDirection direction) {
final localization = AppLocalization.of(context);
if (direction == DismissDirection.endToStart) {
if (project.isDeleted || project.isArchived) {
store.dispatch(RestoreProjectRequest(
snackBarCompleter(context, localization.restoredProject),
project.id));
} else {
store.dispatch(ArchiveProjectRequest(
snackBarCompleter(context, localization.archivedProject),
project.id));
}
} else if (direction == DismissDirection.startToEnd) {
if (project.isDeleted) {
store.dispatch(RestoreProjectRequest(
snackBarCompleter(context, localization.restoredProject),
project.id));
} else {
store.dispatch(DeleteProjectRequest(
snackBarCompleter(context, localization.deletedProject),
project.id));
}
}
});
} }
final UserEntity user; final UserEntity user;
@ -129,7 +104,6 @@ class ProjectListVM {
final bool isLoading; final bool isLoading;
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, ProjectEntity) onProjectTap; final Function(BuildContext, ProjectEntity) onProjectTap;
final Function(BuildContext, ProjectEntity, DismissDirection) onDismissed;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, ProjectEntity, EntityAction) onEntityAction; final Function(BuildContext, ProjectEntity, EntityAction) onEntityAction;
} }

View File

@ -5,6 +5,7 @@ import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart'; import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:invoiceninja_flutter/ui/stub/stub_list_item.dart'; import 'package:invoiceninja_flutter/ui/stub/stub_list_item.dart';
import 'package:invoiceninja_flutter/ui/stub/stub_list_vm.dart'; import 'package:invoiceninja_flutter/ui/stub/stub_list_vm.dart';
import 'package:invoiceninja_flutter/utils/icons.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
class StubList extends StatelessWidget { class StubList extends StatelessWidget {
@ -34,48 +35,34 @@ class StubList extends StatelessWidget {
return _buildListView(context); return _buildListView(context);
} }
void _showMenu(BuildContext context, StubEntity stub) async { void _showMenu(
BuildContext context, StubEntity stub) async {
if (stub == null) { if (stub == null) {
return; return;
} }
final user = viewModel.user; final user = viewModel.user;
final message = await showDialog<String>( final message = await showDialog<String>(
context: context, context: context,
builder: (BuildContext context) => SimpleDialog(children: <Widget>[ builder: (BuildContext dialogContext) => SimpleDialog(
user.canCreate(EntityType.stub) children: stub
? ListTile( .getEntityActions(user: user)
leading: Icon(Icons.control_point_duplicate), .map((entityAction) {
title: Text(AppLocalization.of(context).clone), if (entityAction == null) {
onTap: () => viewModel.onEntityAction( return Divider();
context, stub, EntityAction.clone), } else {
) return ListTile(
: Container(), leading: Icon(getEntityActionIcon(entityAction)),
Divider(), title: Text(AppLocalization.of(context)
user.canEditEntity(stub) && !stub.isActive .lookup(entityAction.toString())),
? ListTile( onTap: () {
leading: Icon(Icons.restore), Navigator.of(dialogContext).pop();
title: Text(AppLocalization.of(context).restore), viewModel.onEntityAction(context, stub, entityAction);
onTap: () => viewModel.onEntityAction( },
context, stub, EntityAction.restore), );
) }
: Container(), }).toList()));
user.canEditEntity(stub) && stub.isActive
? ListTile(
leading: Icon(Icons.archive),
title: Text(AppLocalization.of(context).archive),
onTap: () => viewModel.onEntityAction(
context, stub, EntityAction.archive),
)
: Container(),
user.canEditEntity(stub) && !stub.isDeleted
? ListTile(
leading: Icon(Icons.delete),
title: Text(AppLocalization.of(context).delete),
onTap: () => viewModel.onEntityAction(
context, stub, EntityAction.delete),
)
: Container(),
]));
if (message != null) { if (message != null) {
Scaffold.of(context).showSnackBar(SnackBar( Scaffold.of(context).showSnackBar(SnackBar(
content: SnackBarRow( content: SnackBarRow(

View File

@ -38,7 +38,6 @@ class StubListVM {
@required this.isLoading, @required this.isLoading,
@required this.isLoaded, @required this.isLoaded,
@required this.onStubTap, @required this.onStubTap,
@required this.onDismissed,
@required this.onRefreshed, @required this.onRefreshed,
@required this.onEntityAction, @required this.onEntityAction,
}); });
@ -95,31 +94,7 @@ class StubListVM {
} }
}, },
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
onDismissed: (BuildContext context, StubEntity stub, );
DismissDirection direction) {
final localization = AppLocalization.of(context);
if (direction == DismissDirection.endToStart) {
if (stub.isDeleted || stub.isArchived) {
store.dispatch(RestoreStubRequest(
snackBarCompleter(context, localization.restoredStub),
stub.id));
} else {
store.dispatch(ArchiveStubRequest(
snackBarCompleter(context, localization.archivedStub),
stub.id));
}
} else if (direction == DismissDirection.startToEnd) {
if (stub.isDeleted) {
store.dispatch(RestoreStubRequest(
snackBarCompleter(context, localization.restoredStub),
stub.id));
} else {
store.dispatch(DeleteStubRequest(
snackBarCompleter(context, localization.deletedStub),
stub.id));
}
}
});
} }
final UserEntity user; final UserEntity user;
@ -129,7 +104,6 @@ class StubListVM {
final bool isLoading; final bool isLoading;
final bool isLoaded; final bool isLoaded;
final Function(BuildContext, StubEntity) onStubTap; final Function(BuildContext, StubEntity) onStubTap;
final Function(BuildContext, StubEntity, DismissDirection) onDismissed;
final Function(BuildContext) onRefreshed; final Function(BuildContext) onRefreshed;
final Function(BuildContext, StubEntity, EntityAction) onEntityAction; final Function(BuildContext, StubEntity, EntityAction) onEntityAction;
} }