Recurring schedule

This commit is contained in:
Hillel Coren 2021-09-29 17:54:44 +03:00
parent 2bb05d1919
commit 1e529ab283
3 changed files with 74 additions and 6 deletions

View File

@ -277,8 +277,9 @@ RecurringExpenseState _addRecurringExpense(
RecurringExpenseState _updateRecurringExpense( RecurringExpenseState _updateRecurringExpense(
RecurringExpenseState recurringExpenseState, RecurringExpenseState recurringExpenseState,
SaveRecurringExpenseSuccess action) { SaveRecurringExpenseSuccess action) {
return recurringExpenseState.rebuild( return recurringExpenseState.rebuild((b) => b
(b) => b..map[action.recurringExpense.id] = action.recurringExpense); ..map[action.recurringExpense.id] = action.recurringExpense
.rebuild((b) => b..loadedAt = DateTime.now().millisecondsSinceEpoch));
} }
RecurringExpenseState _startRecurringExpensesSuccess( RecurringExpenseState _startRecurringExpensesSuccess(

View File

@ -9,10 +9,12 @@ import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/bottom_buttons.dart'; import 'package:invoiceninja_flutter/ui/app/buttons/bottom_buttons.dart';
import 'package:invoiceninja_flutter/ui/app/view_scaffold.dart'; import 'package:invoiceninja_flutter/ui/app/view_scaffold.dart';
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_documents.dart'; import 'package:invoiceninja_flutter/ui/expense/view/expense_view_documents.dart';
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_schedule.dart';
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_vm.dart'; import 'package:invoiceninja_flutter/ui/expense/view/expense_view_vm.dart';
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_overview.dart'; import 'package:invoiceninja_flutter/ui/expense/view/expense_view_overview.dart';
import 'package:invoiceninja_flutter/utils/files.dart'; import 'package:invoiceninja_flutter/utils/files.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
class ExpenseView extends StatefulWidget { class ExpenseView extends StatefulWidget {
@ -39,10 +41,11 @@ class _ExpenseViewState extends State<ExpenseView>
void initState() { void initState() {
super.initState(); super.initState();
final state = widget.viewModel.state; final viewModel = widget.viewModel;
final state = viewModel.state;
_controller = TabController( _controller = TabController(
vsync: this, vsync: this,
length: 2, length: viewModel.expense.isRecurring ? 3 : 2,
initialIndex: widget.isFilter ? 0 : state.expenseUIState.tabIndex); initialIndex: widget.isFilter ? 0 : state.expenseUIState.tabIndex);
_controller.addListener(_onTabChanged); _controller.addListener(_onTabChanged);
} }
@ -83,6 +86,7 @@ class _ExpenseViewState extends State<ExpenseView>
entity: expense, entity: expense,
appBarBottom: TabBar( appBarBottom: TabBar(
controller: _controller, controller: _controller,
isScrollable: isMobile(context),
tabs: [ tabs: [
Tab( Tab(
text: localization.overview, text: localization.overview,
@ -120,8 +124,7 @@ class _ExpenseViewState extends State<ExpenseView>
if (expense.isRecurring) if (expense.isRecurring)
RefreshIndicator( RefreshIndicator(
onRefresh: () => viewModel.onRefreshed(context), onRefresh: () => viewModel.onRefreshed(context),
child: ExpenseViewDocuments( child: ExpenseViewSchedule(viewModel: viewModel),
viewModel: viewModel, expense: viewModel.expense),
), ),
], ],
), ),

View File

@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/ui/app/scrollable_listview.dart';
import 'package:invoiceninja_flutter/ui/expense/view/expense_view_vm.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class ExpenseViewSchedule extends StatefulWidget {
const ExpenseViewSchedule({Key key, @required this.viewModel})
: super(key: key);
final AbstractExpenseViewVM viewModel;
@override
_ExpenseViewScheduleState createState() => _ExpenseViewScheduleState();
}
class _ExpenseViewScheduleState extends State<ExpenseViewSchedule> {
@override
void didChangeDependencies() {
if (widget.viewModel.expense.isStale) {
widget.viewModel.onRefreshed(context);
}
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
final expense = widget.viewModel.expense;
final localization = AppLocalization.of(context);
return ScrollableListView(
padding: const EdgeInsets.all(16),
children: [
Row(
children: [
Expanded(
child: Text(
localization.sendDate,
style: TextStyle(fontWeight: FontWeight.w600),
),
),
],
),
if (expense.isStale && expense.recurringDates.isEmpty)
LoadingIndicator(
height: 300,
),
...expense.recurringDates
.map((schedule) => Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
children: [
Expanded(
child: Text(formatDate(schedule.sendDate, context)),
),
],
),
))
.toList(),
],
);
}
}