Improve edit page actions

This commit is contained in:
Hillel Coren 2022-03-15 14:52:13 +02:00
parent c4cc156918
commit da7ac8ebf4
18 changed files with 97 additions and 179 deletions

View File

@ -351,20 +351,19 @@ abstract class ExpenseEntity extends Object
} }
} }
if (userCompany.canCreate(EntityType.expense) && if (!multiselect && isOld) {
!multiselect && if (userCompany.canCreate(EntityType.expense) && !isRecurring) {
!isRecurring) {
actions.add(EntityAction.cloneToExpense); actions.add(EntityAction.cloneToExpense);
} }
if (userCompany.canCreate(EntityType.recurringExpense) && !multiselect) { if (userCompany.canCreate(EntityType.recurringExpense)) {
actions.add(EntityAction.cloneToRecurring); actions.add(EntityAction.cloneToRecurring);
} }
if (userCompany.canCreate(EntityType.expense) &&
!multiselect && if (userCompany.canCreate(EntityType.expense) && isRecurring) {
isRecurring) {
actions.add(EntityAction.cloneToExpense); actions.add(EntityAction.cloneToExpense);
} }
}
if (actions.isNotEmpty && actions.last != null) { if (actions.isNotEmpty && actions.last != null) {
actions.add(null); actions.add(null);

View File

@ -955,7 +955,7 @@ abstract class InvoiceEntity extends Object
actions.add(null); actions.add(null);
} }
if (!multiselect) { if (!multiselect && isOld) {
int countOtherTypes = 0; int countOtherTypes = 0;
if (userCompany.canCreate(EntityType.invoice)) { if (userCompany.canCreate(EntityType.invoice)) {
countOtherTypes++; countOtherTypes++;

View File

@ -115,6 +115,17 @@ class EntityAction extends EnumClass {
bool get isEmail => toString().startsWith('email'); bool get isEmail => toString().startsWith('email');
bool get isServerSide => [
EntityAction.start,
EntityAction.stop,
EntityAction.markPaid,
EntityAction.markSent,
EntityAction.convertToInvoice,
EntityAction.approve,
].contains(this);
bool get isClientSide => !isServerSide;
String toApiParam() { String toApiParam() {
final value = toString(); final value = toString();

View File

@ -606,7 +606,7 @@ abstract class TaskEntity extends Object
} }
} }
if (!multiselect) { if (!multiselect && isOld) {
if (userCompany.canCreate(EntityType.task)) { if (userCompany.canCreate(EntityType.task)) {
actions.add(EntityAction.clone); actions.add(EntityAction.clone);
} }

View File

@ -179,14 +179,19 @@ class EditScaffold extends StatelessWidget {
//size: iconSize, //size: iconSize,
//color: color, //color: color,
), ),
itemBuilder: (BuildContext context) => actions itemBuilder: (BuildContext context) =>
.map((action) => PopupMenuItem<EntityAction>( <PopupMenuEntry<EntityAction>>[
...actions
.map((action) => action == null
? PopupMenuDivider()
: PopupMenuItem<EntityAction>(
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Icon( Icon(
getEntityActionIcon(action), getEntityActionIcon(action),
color: color: Theme.of(context)
Theme.of(context).colorScheme.secondary, .colorScheme
.secondary,
), ),
SizedBox(width: 16.0), SizedBox(width: 16.0),
Text(AppLocalization.of(context) Text(AppLocalization.of(context)
@ -195,7 +200,8 @@ class EditScaffold extends StatelessWidget {
), ),
value: action, value: action,
)) ))
.toList(), .toList()
],
onSelected: (action) => onActionPressed(context, action), onSelected: (action) => onActionPressed(context, action),
enabled: isEnabled, enabled: isEnabled,
) )

View File

@ -88,6 +88,7 @@ class _CreditEditState extends State<CreditEdit>
final state = viewModel.state; final state = viewModel.state;
final prefState = state.prefState; final prefState = state.prefState;
final isFullscreen = prefState.isEditorFullScreen(EntityType.invoice); final isFullscreen = prefState.isEditorFullScreen(EntityType.invoice);
final client = state.clientState.get(invoice.clientId);
return EditScaffold( return EditScaffold(
isFullscreen: isFullscreen, isFullscreen: isFullscreen,
@ -95,13 +96,10 @@ class _CreditEditState extends State<CreditEdit>
title: invoice.isNew ? localization.newCredit : localization.editCredit, title: invoice.isNew ? localization.newCredit : localization.editCredit,
onCancelPressed: (context) => viewModel.onCancelPressed(context), onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context) => _onSavePressed(context), onSavePressed: (context) => _onSavePressed(context),
actions: [ actions: invoice.getActions(
EntityAction.viewPdf, userCompany: state.userCompany,
EntityAction.download, client: client,
EntityAction.emailCredit, ),
if (!invoice.isSent) EntityAction.markSent,
if (invoice.isOld) EntityAction.clone,
],
onActionPressed: (context, action) => _onSavePressed(context, action), onActionPressed: (context, action) => _onSavePressed(context, action),
appBarBottom: TabBar( appBarBottom: TabBar(
controller: _controller, controller: _controller,

View File

@ -94,12 +94,8 @@ class CreditEditVM extends AbstractInvoiceEditVM {
if (credit.isOld && if (credit.isOld &&
!hasCreditChanges(credit, state.creditState.map) && !hasCreditChanges(credit, state.creditState.map) &&
[ action != null &&
EntityAction.emailCredit, action.isClientSide) {
EntityAction.viewPdf,
EntityAction.download,
EntityAction.clone,
].contains(action)) {
handleEntityAction(credit, action); handleEntityAction(credit, action);
} else { } else {
final Completer<InvoiceEntity> completer = final Completer<InvoiceEntity> completer =
@ -131,12 +127,7 @@ class CreditEditVM extends AbstractInvoiceEditVM {
} }
} }
if ([ if (action != null && action.isClientSide) {
EntityAction.emailCredit,
EntityAction.viewPdf,
EntityAction.download,
EntityAction.clone,
].contains(action)) {
handleEntityAction(savedCredit, action); handleEntityAction(savedCredit, action);
} }
}).catchError((Object error) { }).catchError((Object error) {

View File

@ -77,6 +77,7 @@ class _ExpenseEditState extends State<ExpenseEdit>
final expense = viewModel.expense; final expense = viewModel.expense;
final state = viewModel.state; final state = viewModel.state;
final store = StoreProvider.of<AppState>(context); final store = StoreProvider.of<AppState>(context);
final client = state.clientState.get(expense.clientId);
final prefState = state.prefState; final prefState = state.prefState;
final isFullscreen = prefState.isEditorFullScreen(EntityType.expense); final isFullscreen = prefState.isEditorFullScreen(EntityType.expense);
final footer = localization.expenseTotal + final footer = localization.expenseTotal +
@ -96,13 +97,10 @@ class _ExpenseEditState extends State<ExpenseEdit>
: localization.editExpense), : localization.editExpense),
onCancelPressed: (context) => viewModel.onCancelPressed(context), onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context) => _onSavePressed(context), onSavePressed: (context) => _onSavePressed(context),
actions: [ actions: expense.getActions(
if (expense.isRecurring) userCompany: state.userCompany,
if (expense.isRunning) EntityAction.stop else EntityAction.start, client: client,
if (expense.isOld) EntityAction.clone, ),
if (!expense.isRecurring && !expense.isInvoiced)
EntityAction.invoiceExpense,
],
onActionPressed: (context, action) => _onSavePressed(context, action), onActionPressed: (context, action) => _onSavePressed(context, action),
appBarBottom: TabBar( appBarBottom: TabBar(
controller: _controller, controller: _controller,

View File

@ -144,10 +144,8 @@ class ExpenseEditVM extends AbstractExpenseEditVM {
if (expense.isOld && if (expense.isOld &&
!hasExpenseChanges(expense, state.expenseState.map) && !hasExpenseChanges(expense, state.expenseState.map) &&
[ action != null &&
EntityAction.invoiceExpense, action.isClientSide) {
EntityAction.clone,
].contains(action)) {
handleEntityAction(expense, action); handleEntityAction(expense, action);
} else { } else {
final Completer<ExpenseEntity> completer = final Completer<ExpenseEntity> completer =
@ -176,10 +174,7 @@ class ExpenseEditVM extends AbstractExpenseEditVM {
} }
} }
if ([ if (action != null && action.isClientSide) {
EntityAction.invoiceExpense,
EntityAction.clone,
].contains(action)) {
handleEntityAction(savedExpense, action); handleEntityAction(savedExpense, action);
} }
}).catchError((Object error) { }).catchError((Object error) {

View File

@ -110,6 +110,7 @@ class _InvoiceEditState extends State<InvoiceEdit>
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final invoice = viewModel.invoice; final invoice = viewModel.invoice;
final state = viewModel.state; final state = viewModel.state;
final client = state.clientState.get(invoice.clientId);
final prefState = state.prefState; final prefState = state.prefState;
final isFullscreen = prefState.isEditorFullScreen(EntityType.invoice); final isFullscreen = prefState.isEditorFullScreen(EntityType.invoice);
@ -119,15 +120,10 @@ class _InvoiceEditState extends State<InvoiceEdit>
title: invoice.isNew ? localization.newInvoice : localization.editInvoice, title: invoice.isNew ? localization.newInvoice : localization.editInvoice,
onCancelPressed: (context) => viewModel.onCancelPressed(context), onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context) => _onSavePressed(context), onSavePressed: (context) => _onSavePressed(context),
actions: [ actions: invoice.getActions(
EntityAction.viewPdf, userCompany: state.userCompany,
EntityAction.download, client: client,
EntityAction.emailInvoice, ),
if (!invoice.isSent) EntityAction.markSent,
if (!invoice.isPaid) EntityAction.markPaid,
if (!invoice.isPaid) EntityAction.newPayment,
if (invoice.isOld) EntityAction.clone,
],
onActionPressed: (context, action) => _onSavePressed(context, action), onActionPressed: (context, action) => _onSavePressed(context, action),
appBarBottom: TabBar( appBarBottom: TabBar(
controller: _controller, controller: _controller,

View File

@ -143,13 +143,8 @@ class InvoiceEditVM extends AbstractInvoiceEditVM {
if (invoice.isOld && if (invoice.isOld &&
!hasInvoiceChanges(invoice, state.invoiceState.map) && !hasInvoiceChanges(invoice, state.invoiceState.map) &&
[ action != null &&
EntityAction.newPayment, action.isClientSide) {
EntityAction.emailInvoice,
EntityAction.viewPdf,
EntityAction.download,
EntityAction.clone,
].contains(action)) {
handleEntityAction(invoice, action); handleEntityAction(invoice, action);
} else { } else {
final Completer<InvoiceEntity> completer = final Completer<InvoiceEntity> completer =
@ -181,13 +176,7 @@ class InvoiceEditVM extends AbstractInvoiceEditVM {
} }
} }
if ([ if (action != null && action.isClientSide) {
EntityAction.newPayment,
EntityAction.emailInvoice,
EntityAction.viewPdf,
EntityAction.download,
EntityAction.clone,
].contains(action)) {
handleEntityAction(savedInvoice, action); handleEntityAction(savedInvoice, action);
} }
}).catchError((Object error) { }).catchError((Object error) {

View File

@ -93,13 +93,8 @@ class QuoteEditVM extends AbstractInvoiceEditVM {
} }
if (quote.isOld && if (quote.isOld &&
!hasQuoteChanges(quote, state.quoteState.map) && !hasQuoteChanges(quote, state.quoteState.map) &&
[ action != null &&
EntityAction.emailQuote, action.isClientSide) {
EntityAction.viewPdf,
EntityAction.download,
EntityAction.viewInvoice,
EntityAction.clone,
].contains(action)) {
handleEntityAction(quote, action); handleEntityAction(quote, action);
} else { } else {
final Completer<InvoiceEntity> completer = final Completer<InvoiceEntity> completer =
@ -130,13 +125,7 @@ class QuoteEditVM extends AbstractInvoiceEditVM {
} }
} }
if ([ if (action != null && action.isClientSide) {
EntityAction.emailQuote,
EntityAction.viewPdf,
EntityAction.download,
EntityAction.viewInvoice,
EntityAction.clone,
].contains(action)) {
handleEntityAction(savedQuote, action); handleEntityAction(savedQuote, action);
} }
}).catchError((Object error) { }).catchError((Object error) {

View File

@ -87,6 +87,7 @@ class _QuoteEditState extends State<QuoteEdit>
final invoice = viewModel.invoice; final invoice = viewModel.invoice;
final state = viewModel.state; final state = viewModel.state;
final prefState = state.prefState; final prefState = state.prefState;
final client = state.clientState.get(invoice.clientId);
final isFullscreen = prefState.isEditorFullScreen(EntityType.invoice); final isFullscreen = prefState.isEditorFullScreen(EntityType.invoice);
return EditScaffold( return EditScaffold(
@ -95,16 +96,10 @@ class _QuoteEditState extends State<QuoteEdit>
title: invoice.isNew ? localization.newQuote : localization.editQuote, title: invoice.isNew ? localization.newQuote : localization.editQuote,
onCancelPressed: (context) => viewModel.onCancelPressed(context), onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context) => _onSavePressed(context), onSavePressed: (context) => _onSavePressed(context),
actions: [ actions: invoice.getActions(
EntityAction.viewPdf, userCompany: state.userCompany,
EntityAction.download, client: client,
EntityAction.emailQuote, ),
if (!invoice.isSent) EntityAction.markSent,
invoice.invoiceId.isEmpty
? EntityAction.convertToInvoice
: EntityAction.viewInvoice,
if (invoice.isOld) EntityAction.clone,
],
onActionPressed: (context, action) => _onSavePressed(context, action), onActionPressed: (context, action) => _onSavePressed(context, action),
appBarBottom: TabBar( appBarBottom: TabBar(
controller: _controller, controller: _controller,

View File

@ -130,15 +130,9 @@ class RecurringExpenseEditVM extends AbstractExpenseEditVM {
if (recurringExpense.isOld && if (recurringExpense.isOld &&
!hasRecurringExpenseChanges( !hasRecurringExpenseChanges(
recurringExpense, state.recurringExpenseState.map) && recurringExpense, state.recurringExpenseState.map) &&
[ action != null &&
EntityAction.start, action.isClientSide) {
EntityAction.stop,
EntityAction.clone,
].contains(action)) {
handleEntityAction(recurringExpense, action); handleEntityAction(recurringExpense, action);
if ([EntityAction.start, EntityAction.stop].contains(action)) {
viewEntity(entity: recurringExpense, force: true);
}
} else { } else {
final Completer<ExpenseEntity> completer = final Completer<ExpenseEntity> completer =
new Completer<ExpenseEntity>(); new Completer<ExpenseEntity>();
@ -167,16 +161,8 @@ class RecurringExpenseEditVM extends AbstractExpenseEditVM {
} }
} }
if ([ if (action != null && action.isClientSide) {
EntityAction.start,
EntityAction.stop,
EntityAction.clone,
EntityAction.viewPdf,
].contains(action)) {
handleEntityAction(savedRecurringExpense, action); handleEntityAction(savedRecurringExpense, action);
if ([EntityAction.start, EntityAction.stop].contains(action)) {
viewEntity(entity: savedRecurringExpense, force: true);
}
} }
}).catchError((Object error) { }).catchError((Object error) {
showDialog<ErrorDialog>( showDialog<ErrorDialog>(

View File

@ -87,6 +87,7 @@ class _RecurringInvoiceEditState extends State<RecurringInvoiceEdit>
final state = viewModel.state; final state = viewModel.state;
final invoice = viewModel.invoice; final invoice = viewModel.invoice;
final prefState = state.prefState; final prefState = state.prefState;
final client = state.clientState.get(invoice.clientId);
final isFullscreen = prefState.isEditorFullScreen(EntityType.invoice); final isFullscreen = prefState.isEditorFullScreen(EntityType.invoice);
return EditScaffold( return EditScaffold(
@ -97,14 +98,10 @@ class _RecurringInvoiceEditState extends State<RecurringInvoiceEdit>
: localization.editRecurringInvoice, : localization.editRecurringInvoice,
onCancelPressed: (context) => viewModel.onCancelPressed(context), onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context) => _onSavePressed(context), onSavePressed: (context) => _onSavePressed(context),
actions: [ actions: invoice.getActions(
if (!recurringInvoice.isRunning) userCompany: state.userCompany,
EntityAction.start client: client,
else ),
EntityAction.stop,
EntityAction.viewPdf,
if (invoice.isOld) EntityAction.clone,
],
onActionPressed: (context, action) => _onSavePressed(context, action), onActionPressed: (context, action) => _onSavePressed(context, action),
appBarBottom: TabBar( appBarBottom: TabBar(
controller: _controller, controller: _controller,

View File

@ -95,16 +95,9 @@ class RecurringInvoiceEditVM extends AbstractInvoiceEditVM {
if (recurringInvoice.isOld && if (recurringInvoice.isOld &&
!hasRecurringInvoiceChanges( !hasRecurringInvoiceChanges(
recurringInvoice, state.recurringInvoiceState.map) && recurringInvoice, state.recurringInvoiceState.map) &&
[ action != null &&
EntityAction.start, action.isClientSide) {
EntityAction.stop,
EntityAction.viewPdf,
EntityAction.clone,
].contains(action)) {
handleEntityAction(recurringInvoice, action); handleEntityAction(recurringInvoice, action);
if ([EntityAction.start, EntityAction.stop].contains(action)) {
viewEntity(entity: recurringInvoice, force: true);
}
} else { } else {
final Completer<InvoiceEntity> completer = final Completer<InvoiceEntity> completer =
Completer<InvoiceEntity>(); Completer<InvoiceEntity>();
@ -136,16 +129,8 @@ class RecurringInvoiceEditVM extends AbstractInvoiceEditVM {
} }
} }
if ([ if (action != null && action.isClientSide) {
EntityAction.start,
EntityAction.stop,
EntityAction.viewPdf,
EntityAction.clone,
].contains(action)) {
handleEntityAction(savedRecurringInvoice, action); handleEntityAction(savedRecurringInvoice, action);
if ([EntityAction.start, EntityAction.stop].contains(action)) {
viewEntity(entity: savedRecurringInvoice, force: true);
}
} }
}).catchError((Object error) { }).catchError((Object error) {
showDialog<ErrorDialog>( showDialog<ErrorDialog>(

View File

@ -93,6 +93,7 @@ class _TaskEditState extends State<TaskEdit>
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final task = viewModel.task; final task = viewModel.task;
final state = viewModel.state; final state = viewModel.state;
final client = state.clientState.get(task.clientId);
final isFullscreen = state.prefState.isEditorFullScreen(EntityType.task); final isFullscreen = state.prefState.isEditorFullScreen(EntityType.task);
return EditScaffold( return EditScaffold(
@ -102,13 +103,10 @@ class _TaskEditState extends State<TaskEdit>
onCancelPressed: (context) => viewModel.onCancelPressed(context), onCancelPressed: (context) => viewModel.onCancelPressed(context),
onSavePressed: (context, [EntityAction action]) => onSavePressed: (context, [EntityAction action]) =>
_onSavePressed(context, action), _onSavePressed(context, action),
actions: [ actions: task.getActions(
if (!task.isInvoiced) ...[ userCompany: state.userCompany,
task.isRunning ? EntityAction.stop : EntityAction.start, client: client,
EntityAction.invoiceTask, ),
],
if (task.isOld) EntityAction.clone,
],
onActionPressed: (context, action) => _onSavePressed(context, action), onActionPressed: (context, action) => _onSavePressed(context, action),
appBarBottom: TabBar( appBarBottom: TabBar(
controller: _controller, controller: _controller,

View File

@ -98,16 +98,9 @@ class TaskEditVM {
if (task.isOld && if (task.isOld &&
!hasTaskChanges(task, state.taskState.map) && !hasTaskChanges(task, state.taskState.map) &&
[ action != null &&
EntityAction.start, action.isClientSide) {
EntityAction.stop,
EntityAction.invoiceTask,
EntityAction.clone,
].contains(action)) {
handleEntityAction(task, action); handleEntityAction(task, action);
if ([EntityAction.start, EntityAction.stop].contains(action)) {
viewEntity(entity: task, force: true);
}
} else { } else {
final Completer<TaskEntity> completer = new Completer<TaskEntity>(); final Completer<TaskEntity> completer = new Completer<TaskEntity>();
store.dispatch(SaveTaskRequest(completer: completer, task: task)); store.dispatch(SaveTaskRequest(completer: completer, task: task));
@ -132,16 +125,8 @@ class TaskEditVM {
} }
} }
if ([ if (action != null && action.isClientSide) {
EntityAction.start,
EntityAction.stop,
EntityAction.invoiceTask,
EntityAction.clone,
].contains(action)) {
handleEntityAction(savedTask, action); handleEntityAction(savedTask, action);
if ([EntityAction.start, EntityAction.stop].contains(action)) {
viewEntity(entity: task, force: true);
}
} }
}).catchError((Object error) { }).catchError((Object error) {
showDialog<ErrorDialog>( showDialog<ErrorDialog>(