This commit is contained in:
Hillel Coren 2019-10-11 13:47:25 +03:00
parent fefc3a1108
commit a37699a285
26 changed files with 2366 additions and 24 deletions

View File

@ -31,6 +31,9 @@ import 'package:invoiceninja_flutter/redux/project/project_state.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_state.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_state.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_state.dart';
import 'package:invoiceninja_flutter/redux/group/group_state.dart';
import 'package:invoiceninja_flutter/redux/document/document_state.dart';
@ -100,6 +103,8 @@ part 'serializers.g.dart';
DocumentListResponse,
DocumentItemResponse,
// STARTER: serializers - do not remove comment
CompanyGatewayEntity,
])
final Serializers serializers =
(_$serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();

View File

@ -17,6 +17,9 @@ Serializers _$serializers = (new Serializers().toBuilder()
..add(ClientState.serializer)
..add(ClientUIState.serializer)
..add(CompanyEntity.serializer)
..add(CompanyGatewayEntity.serializer)
..add(CompanyGatewayState.serializer)
..add(CompanyGatewayUIState.serializer)
..add(CompanyItemResponse.serializer)
..add(ContactEntity.serializer)
..add(CountryEntity.serializer)
@ -312,6 +315,8 @@ Serializers _$serializers = (new Serializers().toBuilder()
..addBuilderFactory(
const FullType(BuiltMap, const [const FullType(String), const FullType(ClientEntity)]), () => new MapBuilder<String, ClientEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder<String>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(CompanyGatewayEntity)]), () => new MapBuilder<String, CompanyGatewayEntity>())
..addBuilderFactory(const FullType(BuiltList, const [const FullType(String)]), () => new ListBuilder<String>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(CurrencyEntity)]), () => new MapBuilder<String, CurrencyEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(SizeEntity)]), () => new MapBuilder<String, SizeEntity>())
..addBuilderFactory(const FullType(BuiltMap, const [const FullType(String), const FullType(IndustryEntity)]), () => new MapBuilder<String, IndustryEntity>())

View File

@ -0,0 +1,70 @@
import 'dart:async';
import 'dart:convert';
import 'dart:core';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/serializers.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/data/web_client.dart';
class CompanyGatewayRepository {
const CompanyGatewayRepository({
this.webClient = const WebClient(),
});
final WebClient webClient;
Future<CompanyGatewayEntity> loadItem(
Credentials credentials, String entityId) async {
final dynamic response = await webClient.get(
'${credentials.url}/company_gateways/$entityId', credentials.token);
final CompanyGatewayItemResponse companyGatewayResponse =
serializers.deserializeWith(CompanyGatewayItemResponse.serializer, response);
return companyGatewayResponse.data;
}
Future<BuiltList<CompanyGatewayEntity>> loadList(
Credentials credentials, int updatedAt) async {
String url = credentials.url + '/company_gateways?';
if (updatedAt > 0) {
url += '&updated_at=${updatedAt - kUpdatedAtBufferSeconds}';
}
final dynamic response = await webClient.get(url, credentials.token);
final CompanyGatewayListResponse companyGatewayResponse =
serializers.deserializeWith(CompanyGatewayListResponse.serializer, response);
return companyGatewayResponse.data;
}
Future<CompanyGatewayEntity> saveData(
Credentials credentials, CompanyGatewayEntity companyGateway,
[EntityAction action]) async {
final data = serializers.serializeWith(CompanyGatewayEntity.serializer, companyGateway);
dynamic response;
if (companyGateway.isNew) {
response = await webClient.post(
credentials.url + '/company_gateways',
credentials.token,
data: json.encode(data));
} else {
var url = credentials.url + '/company_gateways/' + companyGateway.id.toString();
if (action != null) {
url += '?action=' + action.toString();
}
response = await webClient.put(url, credentials.token, data: json.encode(data));
}
final CompanyGatewayItemResponse companyGatewayResponse =
serializers.deserializeWith(CompanyGatewayItemResponse.serializer, response);
return companyGatewayResponse.data;
}
}

View File

@ -60,6 +60,12 @@ import 'package:redux_logging/redux_logging.dart';
import 'package:sentry/sentry.dart';
import 'package:shared_preferences/shared_preferences.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_screen.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/edit/company_gateway_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/view/company_gateway_view_vm.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_middleware.dart';
void main({bool isTesting = false}) async {
final SentryClient _sentry = Config.SENTRY_DNS.isEmpty
@ -102,6 +108,8 @@ void main({bool isTesting = false}) async {
..addAll(createStoreQuotesMiddleware())
..addAll(createStoreSettingsMiddleware())
// STARTER: middleware - do not remove comment
..addAll(createStoreCompanyGatewaysMiddleware())
..addAll(createStoreGroupsMiddleware())
..addAll(isTesting
? []
@ -317,6 +325,10 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
QuoteEditScreen.route: (context) => QuoteEditScreen(),
QuoteEmailScreen.route: (context) => QuoteEmailScreen(),
// STARTER: routes - do not remove comment
CompanyGatewayScreen.route: (context) => CompanyGatewayScreen(),
CompanyGatewayViewScreen.route: (context) => CompanyGatewayViewScreen(),
CompanyGatewayEditScreen.route: (context) => CompanyGatewayEditScreen(),
GroupSettingsScreen.route: (context) => GroupSettingsScreen(),
GroupViewScreen.route: (context) => GroupViewScreen(),
GroupEditScreen.route: (context) => GroupEditScreen(),

View File

@ -33,6 +33,8 @@ import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/group/edit/group_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/product/edit/product_edit_vm.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_state.dart';
import 'package:invoiceninja_flutter/redux/group/group_state.dart';
part 'app_state.g.dart';
@ -143,6 +145,9 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
case EntityType.invoice:
return invoiceUIState;
// STARTER: states switch - do not remove comment
case EntityType.companyGateway:
return companyGatewayUIState;
case EntityType.group:
return groupUIState;
@ -188,6 +193,11 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
ListUIState get invoiceListState => uiState.invoiceUIState.listUIState;
// STARTER: state getters - do not remove comment
CompanyGatewayState get companyGatewayState => selectedCompanyState.companyGatewayState;
ListUIState get companyGatewayListState => uiState.companyGatewayUIState.listUIState;
CompanyGatewayUIState get companyGatewayUIState => uiState.companyGatewayUIState;
GroupState get groupState => selectedCompanyState.groupState;
ListUIState get groupListState => uiState.groupUIState.listUIState;

View File

@ -17,6 +17,8 @@ import 'package:invoiceninja_flutter/redux/project/project_reducer.dart';
import 'package:invoiceninja_flutter/redux/payment/payment_reducer.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_reducer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_reducer.dart';
import 'package:invoiceninja_flutter/redux/group/group_reducer.dart';
UserCompanyState companyReducer(UserCompanyState state, dynamic action) {
@ -35,6 +37,8 @@ UserCompanyState companyReducer(UserCompanyState state, dynamic action) {
..vendorState.replace(vendorsReducer(state.vendorState, action))
..taskState.replace(tasksReducer(state.taskState, action))
// STARTER: reducer - do not remove comment
..companyGatewayState.replace(companyGatewaysReducer(state.companyGatewayState, action))
..projectState.replace(projectsReducer(state.projectState, action))
..paymentState.replace(paymentsReducer(state.paymentState, action))
..quoteState.replace(quotesReducer(state.quoteState, action))

View File

@ -9,6 +9,8 @@ import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_state.dart';
import 'package:invoiceninja_flutter/redux/group/group_state.dart';
import 'package:invoiceninja_flutter/redux/document/document_state.dart';
@ -44,6 +46,8 @@ abstract class UserCompanyState
paymentState: PaymentState(),
quoteState: QuoteState(),
// STARTER: constructor - do not remove comment
companyGatewayState: CompanyGatewayState(),
groupState: GroupState(),
);
}
@ -76,6 +80,8 @@ abstract class UserCompanyState
QuoteState get quoteState;
// STARTER: fields - do not remove comment
CompanyGatewayState get companyGatewayState;
GroupState get groupState;
CompanyEntity get company => userCompany.company;

View File

@ -55,6 +55,9 @@ class _$UserCompanyStateSerializer
'quoteState',
serializers.serialize(object.quoteState,
specifiedType: const FullType(QuoteState)),
'companyGatewayState',
serializers.serialize(object.companyGatewayState,
specifiedType: const FullType(CompanyGatewayState)),
'groupState',
serializers.serialize(object.groupState,
specifiedType: const FullType(GroupState)),
@ -129,6 +132,11 @@ class _$UserCompanyStateSerializer
result.quoteState.replace(serializers.deserialize(value,
specifiedType: const FullType(QuoteState)) as QuoteState);
break;
case 'companyGatewayState':
result.companyGatewayState.replace(serializers.deserialize(value,
specifiedType: const FullType(CompanyGatewayState))
as CompanyGatewayState);
break;
case 'groupState':
result.groupState.replace(serializers.deserialize(value,
specifiedType: const FullType(GroupState)) as GroupState);
@ -273,6 +281,8 @@ class _$UserCompanyState extends UserCompanyState {
@override
final QuoteState quoteState;
@override
final CompanyGatewayState companyGatewayState;
@override
final GroupState groupState;
factory _$UserCompanyState(
@ -292,6 +302,7 @@ class _$UserCompanyState extends UserCompanyState {
this.projectState,
this.paymentState,
this.quoteState,
this.companyGatewayState,
this.groupState})
: super._() {
if (documentState == null) {
@ -327,6 +338,10 @@ class _$UserCompanyState extends UserCompanyState {
if (quoteState == null) {
throw new BuiltValueNullFieldError('UserCompanyState', 'quoteState');
}
if (companyGatewayState == null) {
throw new BuiltValueNullFieldError(
'UserCompanyState', 'companyGatewayState');
}
if (groupState == null) {
throw new BuiltValueNullFieldError('UserCompanyState', 'groupState');
}
@ -356,6 +371,7 @@ class _$UserCompanyState extends UserCompanyState {
projectState == other.projectState &&
paymentState == other.paymentState &&
quoteState == other.quoteState &&
companyGatewayState == other.companyGatewayState &&
groupState == other.groupState;
}
@ -373,19 +389,23 @@ class _$UserCompanyState extends UserCompanyState {
$jc(
$jc(
$jc(
$jc(0,
userCompany.hashCode),
documentState.hashCode),
dashboardState.hashCode),
productState.hashCode),
clientState.hashCode),
invoiceState.hashCode),
expenseState.hashCode),
vendorState.hashCode),
taskState.hashCode),
projectState.hashCode),
paymentState.hashCode),
quoteState.hashCode),
$jc(
$jc(
0,
userCompany
.hashCode),
documentState.hashCode),
dashboardState.hashCode),
productState.hashCode),
clientState.hashCode),
invoiceState.hashCode),
expenseState.hashCode),
vendorState.hashCode),
taskState.hashCode),
projectState.hashCode),
paymentState.hashCode),
quoteState.hashCode),
companyGatewayState.hashCode),
groupState.hashCode));
}
@ -404,6 +424,7 @@ class _$UserCompanyState extends UserCompanyState {
..add('projectState', projectState)
..add('paymentState', paymentState)
..add('quoteState', quoteState)
..add('companyGatewayState', companyGatewayState)
..add('groupState', groupState))
.toString();
}
@ -484,6 +505,12 @@ class UserCompanyStateBuilder
set quoteState(QuoteStateBuilder quoteState) =>
_$this._quoteState = quoteState;
CompanyGatewayStateBuilder _companyGatewayState;
CompanyGatewayStateBuilder get companyGatewayState =>
_$this._companyGatewayState ??= new CompanyGatewayStateBuilder();
set companyGatewayState(CompanyGatewayStateBuilder companyGatewayState) =>
_$this._companyGatewayState = companyGatewayState;
GroupStateBuilder _groupState;
GroupStateBuilder get groupState =>
_$this._groupState ??= new GroupStateBuilder();
@ -506,6 +533,7 @@ class UserCompanyStateBuilder
_projectState = _$v.projectState?.toBuilder();
_paymentState = _$v.paymentState?.toBuilder();
_quoteState = _$v.quoteState?.toBuilder();
_companyGatewayState = _$v.companyGatewayState?.toBuilder();
_groupState = _$v.groupState?.toBuilder();
_$v = null;
}
@ -543,6 +571,7 @@ class UserCompanyStateBuilder
projectState: projectState.build(),
paymentState: paymentState.build(),
quoteState: quoteState.build(),
companyGatewayState: companyGatewayState.build(),
groupState: groupState.build());
} catch (_) {
String _$failedField;
@ -571,6 +600,8 @@ class UserCompanyStateBuilder
paymentState.build();
_$failedField = 'quoteState';
quoteState.build();
_$failedField = 'companyGatewayState';
companyGatewayState.build();
_$failedField = 'groupState';
groupState.build();
} catch (e) {

View File

@ -0,0 +1,268 @@
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
class ViewCompanyGatewayList implements PersistUI {
ViewCompanyGatewayList({@required this.context, this.force = false});
final BuildContext context;
final bool force;
}
class ViewCompanyGateway implements PersistUI {
ViewCompanyGateway({
@required this.companyGatewayId,
@required this.context,
this.force = false,
});
final String companyGatewayId;
final BuildContext context;
final bool force;
}
class EditCompanyGateway implements PersistUI {
EditCompanyGateway(
{@required this.companyGateway,
@required this.context,
this.completer,
this.force = false});
final CompanyGatewayEntity companyGateway;
final BuildContext context;
final Completer completer;
final bool force;
}
class UpdateCompanyGateway implements PersistUI {
UpdateCompanyGateway(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class LoadCompanyGateway {
LoadCompanyGateway({this.completer, this.companyGatewayId, this.loadActivities = false});
final Completer completer;
final String companyGatewayId;
final bool loadActivities;
}
class LoadCompanyGatewayActivity {
LoadCompanyGatewayActivity({this.completer, this.companyGatewayId});
final Completer completer;
final String companyGatewayId;
}
class LoadCompanyGateways {
LoadCompanyGateways({this.completer, this.force = false});
final Completer completer;
final bool force;
}
class LoadCompanyGatewayRequest implements StartLoading {}
class LoadCompanyGatewayFailure implements StopLoading {
LoadCompanyGatewayFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadCompanyGatewayFailure{error: $error}';
}
}
class LoadCompanyGatewaySuccess implements StopLoading, PersistData {
LoadCompanyGatewaySuccess(this.companyGateway);
final CompanyGatewayEntity companyGateway;
@override
String toString() {
return 'LoadCompanyGatewaySuccess{companyGateway: $companyGateway}';
}
}
class LoadCompanyGatewaysRequest implements StartLoading {}
class LoadCompanyGatewaysFailure implements StopLoading {
LoadCompanyGatewaysFailure(this.error);
final dynamic error;
@override
String toString() {
return 'LoadCompanyGatewaysFailure{error: $error}';
}
}
class LoadCompanyGatewaysSuccess implements StopLoading, PersistData {
LoadCompanyGatewaysSuccess(this.companyGateways);
final BuiltList<CompanyGatewayEntity> companyGateways;
@override
String toString() {
return 'LoadCompanyGatewaysSuccess{companyGateways: $companyGateways}';
}
}
class SaveCompanyGatewayRequest implements StartSaving {
SaveCompanyGatewayRequest({this.completer, this.companyGateway});
final Completer completer;
final CompanyGatewayEntity companyGateway;
}
class SaveCompanyGatewaySuccess implements StopSaving, PersistData, PersistUI {
SaveCompanyGatewaySuccess(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class AddCompanyGatewaySuccess implements StopSaving, PersistData, PersistUI {
AddCompanyGatewaySuccess(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class SaveCompanyGatewayFailure implements StopSaving {
SaveCompanyGatewayFailure (this.error);
final Object error;
}
class ArchiveCompanyGatewayRequest implements StartSaving {
ArchiveCompanyGatewayRequest(this.completer, this.companyGatewayId);
final Completer completer;
final String companyGatewayId;
}
class ArchiveCompanyGatewaySuccess implements StopSaving, PersistData {
ArchiveCompanyGatewaySuccess(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class ArchiveCompanyGatewayFailure implements StopSaving {
ArchiveCompanyGatewayFailure(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class DeleteCompanyGatewayRequest implements StartSaving {
DeleteCompanyGatewayRequest(this.completer, this.companyGatewayId);
final Completer completer;
final String companyGatewayId;
}
class DeleteCompanyGatewaySuccess implements StopSaving, PersistData {
DeleteCompanyGatewaySuccess(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class DeleteCompanyGatewayFailure implements StopSaving {
DeleteCompanyGatewayFailure(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class RestoreCompanyGatewayRequest implements StartSaving {
RestoreCompanyGatewayRequest(this.completer, this.companyGatewayId);
final Completer completer;
final String companyGatewayId;
}
class RestoreCompanyGatewaySuccess implements StopSaving, PersistData {
RestoreCompanyGatewaySuccess(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class RestoreCompanyGatewayFailure implements StopSaving {
RestoreCompanyGatewayFailure(this.companyGateway);
final CompanyGatewayEntity companyGateway;
}
class FilterCompanyGateways {
FilterCompanyGateways(this.filter);
final String filter;
}
class SortCompanyGateways implements PersistUI {
SortCompanyGateways(this.field);
final String field;
}
class FilterCompanyGatewaysByState implements PersistUI {
FilterCompanyGatewaysByState(this.state);
final EntityState state;
}
class FilterCompanyGatewaysByCustom1 implements PersistUI {
FilterCompanyGatewaysByCustom1(this.value);
final String value;
}
class FilterCompanyGatewaysByCustom2 implements PersistUI {
FilterCompanyGatewaysByCustom2(this.value);
final String value;
}
class FilterCompanyGatewaysByEntity implements PersistUI {
FilterCompanyGatewaysByEntity({this.entityId, this.entityType});
final String entityId;
final EntityType entityType;
}
void handleCompanyGatewayAction(
BuildContext context, CompanyGatewayEntity companyGateway, EntityAction action) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final CompanyEntity company = state.selectedCompany;
final localization = AppLocalization.of(context);
switch (action) {
case EntityAction.edit:
store.dispatch(EditCompanyGateway(context: context, companyGateway: companyGateway));
break;
case EntityAction.restore:
store.dispatch(RestoreCompanyGatewayRequest(
snackBarCompleter(context, localization.restoredCompanyGateway), companyGateway.id));
break;
case EntityAction.archive:
store.dispatch(ArchiveCompanyGatewayRequest(
snackBarCompleter(context, localization.archivedCompanyGateway), companyGateway.id));
break;
case EntityAction.delete:
store.dispatch(DeleteCompanyGatewayRequest(
snackBarCompleter(context, localization.deletedCompanyGateway), companyGateway.id));
break;
}
}

View File

@ -0,0 +1,281 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:invoiceninja_flutter/redux/app/app_middleware.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_screen.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/edit/company_gateway_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/view/company_gateway_view_vm.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/repositories/company_gateway_repository.dart';
List<Middleware<AppState>> createStoreCompanyGatewaysMiddleware([
CompanyGatewayRepository repository = const CompanyGatewayRepository(),
]) {
final viewCompanyGatewayList = _viewCompanyGatewayList();
final viewCompanyGateway = _viewCompanyGateway();
final editCompanyGateway = _editCompanyGateway();
final loadCompanyGateways = _loadCompanyGateways(repository);
final loadCompanyGateway = _loadCompanyGateway(repository);
final saveCompanyGateway = _saveCompanyGateway(repository);
final archiveCompanyGateway = _archiveCompanyGateway(repository);
final deleteCompanyGateway = _deleteCompanyGateway(repository);
final restoreCompanyGateway = _restoreCompanyGateway(repository);
return [
TypedMiddleware<AppState, ViewCompanyGatewayList>(viewCompanyGatewayList),
TypedMiddleware<AppState, ViewCompanyGateway>(viewCompanyGateway),
TypedMiddleware<AppState, EditCompanyGateway>(editCompanyGateway),
TypedMiddleware<AppState, LoadCompanyGateways>(loadCompanyGateways),
TypedMiddleware<AppState, LoadCompanyGateway>(loadCompanyGateway),
TypedMiddleware<AppState, SaveCompanyGatewayRequest>(saveCompanyGateway),
TypedMiddleware<AppState, ArchiveCompanyGatewayRequest>(archiveCompanyGateway),
TypedMiddleware<AppState, DeleteCompanyGatewayRequest>(deleteCompanyGateway),
TypedMiddleware<AppState, RestoreCompanyGatewayRequest>(restoreCompanyGateway),
];
}
Middleware<AppState> _editCompanyGateway() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) async {
final action = dynamicAction as EditCompanyGateway;
if (!action.force && hasChanges(
store: store, context: action.context, action: action)) {
return;
}
next(action);
store.dispatch(UpdateCurrentRoute(CompanyGatewayEditScreen.route));
if (isMobile(action.context)) {
final companyGateway =
await Navigator.of(action.context).pushNamed(CompanyGatewayEditScreen.route);
if (action.completer != null && companyGateway != null) {
action.completer.complete(companyGateway);
}
}
};
}
Middleware<AppState> _viewCompanyGateway() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) async {
final action = dynamicAction as ViewCompanyGateway;
if (!action.force && hasChanges(
store: store, context: action.context, action: action)) {
return;
}
next(action);
store.dispatch(UpdateCurrentRoute(CompanyGatewayViewScreen.route));
if (isMobile(action.context)) {
Navigator.of(action.context).pushNamed(CompanyGatewayViewScreen.route);
}
};
}
Middleware<AppState> _viewCompanyGatewayList() {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ViewCompanyGatewayList;
if (!action.force && hasChanges(
store: store, context: action.context, action: action)) {
return;
}
next(action);
if (store.state.companyGatewayState.isStale) {
store.dispatch(LoadCompanyGateways());
}
store.dispatch(UpdateCurrentRoute(CompanyGatewayScreen.route));
if (isMobile(action.context)) {
Navigator.of(action.context).pushNamedAndRemoveUntil(
CompanyGatewayScreen.route, (Route<dynamic> route) => false);
}
};
}
Middleware<AppState> _archiveCompanyGateway(CompanyGatewayRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as ArchiveCompanyGatewayRequest;
final origCompanyGateway = store.state.companyGatewayState.map[action.companyGatewayId];
repository
.saveData(store.state.credentials,
origCompanyGateway, EntityAction.archive)
.then((CompanyGatewayEntity companyGateway) {
store.dispatch(ArchiveCompanyGatewaySuccess(companyGateway));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(ArchiveCompanyGatewayFailure(origCompanyGateway));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _deleteCompanyGateway(CompanyGatewayRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as DeleteCompanyGatewayRequest;
final origCompanyGateway = store.state.companyGatewayState.map[action.companyGatewayId];
repository
.saveData(store.state.credentials,
origCompanyGateway, EntityAction.delete)
.then((CompanyGatewayEntity companyGateway) {
store.dispatch(DeleteCompanyGatewaySuccess(companyGateway));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(DeleteCompanyGatewayFailure(origCompanyGateway));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _restoreCompanyGateway(CompanyGatewayRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as RestoreCompanyGatewayRequest;
final origCompanyGateway = store.state.companyGatewayState.map[action.companyGatewayId];
repository
.saveData(store.state.credentials,
origCompanyGateway, EntityAction.restore)
.then((CompanyGatewayEntity companyGateway) {
store.dispatch(RestoreCompanyGatewaySuccess(companyGateway));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(RestoreCompanyGatewayFailure(origCompanyGateway));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _saveCompanyGateway(CompanyGatewayRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as SaveCompanyGatewayRequest;
repository
.saveData(
store.state.credentials, action.companyGateway)
.then((CompanyGatewayEntity companyGateway) {
if (action.companyGateway.isNew) {
store.dispatch(AddCompanyGatewaySuccess(companyGateway));
} else {
store.dispatch(SaveCompanyGatewaySuccess(companyGateway));
}
final companyGatewayUIState = store.state.companyGatewayUIState;
if (companyGatewayUIState.saveCompleter != null) {
companyGatewayUIState.saveCompleter.complete(companyGateway);
}
}).catchError((Object error) {
print(error);
store.dispatch(SaveCompanyGatewayFailure(error));
action.completer.completeError(error);
});
next(action);
};
}
Middleware<AppState> _loadCompanyGateway(CompanyGatewayRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadCompanyGateway;
final AppState state = store.state;
if (state.isLoading) {
next(action);
return;
}
store.dispatch(LoadCompanyGatewayRequest());
repository
.loadItem(state.credentials, action.companyGatewayId)
.then((companyGateway) {
store.dispatch(LoadCompanyGatewaySuccess(companyGateway));
if (action.completer != null) {
action.completer.complete(null);
}
}).catchError((Object error) {
print(error);
store.dispatch(LoadCompanyGatewayFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}
Middleware<AppState> _loadCompanyGateways(CompanyGatewayRepository repository) {
return (Store<AppState> store, dynamic dynamicAction, NextDispatcher next) {
final action = dynamicAction as LoadCompanyGateways;
final AppState state = store.state;
if (!state.companyGatewayState.isStale && !action.force) {
next(action);
return;
}
if (state.isLoading) {
next(action);
return;
}
final int updatedAt = (state.companyGatewayState.lastUpdated / 1000).round();
store.dispatch(LoadCompanyGatewaysRequest());
repository
.loadList(state.credentials, updatedAt)
.then((data) {
store.dispatch(LoadCompanyGatewaysSuccess(data));
if (action.completer != null) {
action.completer.complete(null);
}
/*
if (state.productState.isStale) {
store.dispatch(LoadProducts());
}
*/
}).catchError((Object error) {
print(error);
store.dispatch(LoadCompanyGatewaysFailure(error));
if (action.completer != null) {
action.completer.completeError(error);
}
});
next(action);
};
}

View File

@ -0,0 +1,205 @@
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/company/company_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_state.dart';
EntityUIState companyGatewayUIReducer(CompanyGatewayUIState state, dynamic action) {
return state.rebuild((b) => b
..listUIState.replace(companyGatewayListReducer(state.listUIState, action))
..editing.replace(editingReducer(state.editing, action))
..selectedId = selectedIdReducer(state.selectedId, action));
}
Reducer<String> selectedIdReducer = combineReducers([
TypedReducer<String, ViewCompanyGateway>(
(String selectedId, dynamic action) => action.companyGatewayId),
TypedReducer<String, AddCompanyGatewaySuccess>(
(String selectedId, dynamic action) => action.companyGateway.id),
TypedReducer<String, FilterCompanyGatewaysByEntity>((selectedId, action) => action.entityId == null ? selectedId : '')
]);
final editingReducer = combineReducers<CompanyGatewayEntity>([
TypedReducer<CompanyGatewayEntity, SaveCompanyGatewaySuccess>(_updateEditing),
TypedReducer<CompanyGatewayEntity, AddCompanyGatewaySuccess>(_updateEditing),
TypedReducer<CompanyGatewayEntity, RestoreCompanyGatewaySuccess>(_updateEditing),
TypedReducer<CompanyGatewayEntity, ArchiveCompanyGatewaySuccess>(_updateEditing),
TypedReducer<CompanyGatewayEntity, DeleteCompanyGatewaySuccess>(_updateEditing),
TypedReducer<CompanyGatewayEntity, EditCompanyGateway>(_updateEditing),
TypedReducer<CompanyGatewayEntity, UpdateCompanyGateway>((companyGateway, action) {
return action.companyGateway.rebuild((b) => b..isChanged = true);
}),
TypedReducer<CompanyGatewayEntity, SelectCompany>(_clearEditing),
TypedReducer<CompanyGatewayEntity, DiscardChanges>(_clearEditing),
]);
CompanyGatewayEntity _clearEditing(CompanyGatewayEntity companyGateway, dynamic action) {
return CompanyGatewayEntity();
}
CompanyGatewayEntity _updateEditing(CompanyGatewayEntity companyGateway, dynamic action) {
return action.companyGateway;
}
final companyGatewayListReducer = combineReducers<ListUIState>([
TypedReducer<ListUIState, SortCompanyGateways>(_sortCompanyGateways),
TypedReducer<ListUIState, FilterCompanyGatewaysByState>(_filterCompanyGatewaysByState),
TypedReducer<ListUIState, FilterCompanyGateways>(_filterCompanyGateways),
TypedReducer<ListUIState, FilterCompanyGatewaysByCustom1>(_filterCompanyGatewaysByCustom1),
TypedReducer<ListUIState, FilterCompanyGatewaysByCustom2>(_filterCompanyGatewaysByCustom2),
TypedReducer<ListUIState, FilterCompanyGatewaysByEntity>(_filterCompanyGatewaysByClient),
]);
ListUIState _filterCompanyGatewaysByClient(
ListUIState companyGatewayListState, FilterCompanyGatewaysByEntity action) {
return companyGatewayListState.rebuild((b) => b
..filterEntityId = action.entityId
..filterEntityType = action.entityType);
}
ListUIState _filterCompanyGatewaysByCustom1(
ListUIState companyGatewayListState, FilterCompanyGatewaysByCustom1 action) {
if (companyGatewayListState.custom1Filters.contains(action.value)) {
return companyGatewayListState
.rebuild((b) => b..custom1Filters.remove(action.value));
} else {
return companyGatewayListState.rebuild((b) => b..custom1Filters.add(action.value));
}
}
ListUIState _filterCompanyGatewaysByCustom2(
ListUIState companyGatewayListState, FilterCompanyGatewaysByCustom2 action) {
if (companyGatewayListState.custom2Filters.contains(action.value)) {
return companyGatewayListState
.rebuild((b) => b..custom2Filters.remove(action.value));
} else {
return companyGatewayListState.rebuild((b) => b..custom2Filters.add(action.value));
}
}
ListUIState _filterCompanyGatewaysByState(
ListUIState companyGatewayListState, FilterCompanyGatewaysByState action) {
if (companyGatewayListState.stateFilters.contains(action.state)) {
return companyGatewayListState.rebuild((b) => b..stateFilters.remove(action.state));
} else {
return companyGatewayListState.rebuild((b) => b..stateFilters.add(action.state));
}
}
ListUIState _filterCompanyGateways(ListUIState companyGatewayListState, FilterCompanyGateways action) {
return companyGatewayListState.rebuild((b) => b..filter = action.filter
..filterClearedAt = action.filter == null
? DateTime.now().millisecondsSinceEpoch
: companyGatewayListState.filterClearedAt);
}
ListUIState _sortCompanyGateways(ListUIState companyGatewayListState, SortCompanyGateways action) {
return companyGatewayListState.rebuild((b) => b
..sortAscending = b.sortField != action.field || !b.sortAscending
..sortField = action.field);
}
final companyGatewaysReducer = combineReducers<CompanyGatewayState>([
TypedReducer<CompanyGatewayState, SaveCompanyGatewaySuccess>(_updateCompanyGateway),
TypedReducer<CompanyGatewayState, AddCompanyGatewaySuccess>(_addCompanyGateway),
TypedReducer<CompanyGatewayState, LoadCompanyGatewaysSuccess>(_setLoadedCompanyGateways),
TypedReducer<CompanyGatewayState, LoadCompanyGatewaySuccess>(_setLoadedCompanyGateway),
TypedReducer<CompanyGatewayState, ArchiveCompanyGatewayRequest>(_archiveCompanyGatewayRequest),
TypedReducer<CompanyGatewayState, ArchiveCompanyGatewaySuccess>(_archiveCompanyGatewaySuccess),
TypedReducer<CompanyGatewayState, ArchiveCompanyGatewayFailure>(_archiveCompanyGatewayFailure),
TypedReducer<CompanyGatewayState, DeleteCompanyGatewayRequest>(_deleteCompanyGatewayRequest),
TypedReducer<CompanyGatewayState, DeleteCompanyGatewaySuccess>(_deleteCompanyGatewaySuccess),
TypedReducer<CompanyGatewayState, DeleteCompanyGatewayFailure>(_deleteCompanyGatewayFailure),
TypedReducer<CompanyGatewayState, RestoreCompanyGatewayRequest>(_restoreCompanyGatewayRequest),
TypedReducer<CompanyGatewayState, RestoreCompanyGatewaySuccess>(_restoreCompanyGatewaySuccess),
TypedReducer<CompanyGatewayState, RestoreCompanyGatewayFailure>(_restoreCompanyGatewayFailure),
]);
CompanyGatewayState _archiveCompanyGatewayRequest(
CompanyGatewayState companyGatewayState, ArchiveCompanyGatewayRequest action) {
final companyGateway = companyGatewayState.map[action.companyGatewayId]
.rebuild((b) => b..archivedAt = DateTime.now().millisecondsSinceEpoch);
return companyGatewayState.rebuild((b) => b..map[action.companyGatewayId] = companyGateway);
}
CompanyGatewayState _archiveCompanyGatewaySuccess(
CompanyGatewayState companyGatewayState, ArchiveCompanyGatewaySuccess action) {
return companyGatewayState.rebuild((b) => b..map[action.companyGateway.id] = action.companyGateway);
}
CompanyGatewayState _archiveCompanyGatewayFailure(
CompanyGatewayState companyGatewayState, ArchiveCompanyGatewayFailure action) {
return companyGatewayState.rebuild((b) => b..map[action.companyGateway.id] = action.companyGateway);
}
CompanyGatewayState _deleteCompanyGatewayRequest(
CompanyGatewayState companyGatewayState, DeleteCompanyGatewayRequest action) {
final companyGateway = companyGatewayState.map[action.companyGatewayId].rebuild((b) => b
..archivedAt = DateTime.now().millisecondsSinceEpoch
..isDeleted = true);
return companyGatewayState.rebuild((b) => b..map[action.companyGatewayId] = companyGateway);
}
CompanyGatewayState _deleteCompanyGatewaySuccess(
CompanyGatewayState companyGatewayState, DeleteCompanyGatewaySuccess action) {
return companyGatewayState.rebuild((b) => b..map[action.companyGateway.id] = action.companyGateway);
}
CompanyGatewayState _deleteCompanyGatewayFailure(
CompanyGatewayState companyGatewayState, DeleteCompanyGatewayFailure action) {
return companyGatewayState.rebuild((b) => b..map[action.companyGateway.id] = action.companyGateway);
}
CompanyGatewayState _restoreCompanyGatewayRequest(
CompanyGatewayState companyGatewayState, RestoreCompanyGatewayRequest action) {
final companyGateway = companyGatewayState.map[action.companyGatewayId].rebuild((b) => b
..archivedAt = null
..isDeleted = false);
return companyGatewayState.rebuild((b) => b..map[action.companyGatewayId] = companyGateway);
}
CompanyGatewayState _restoreCompanyGatewaySuccess(
CompanyGatewayState companyGatewayState, RestoreCompanyGatewaySuccess action) {
return companyGatewayState.rebuild((b) => b..map[action.companyGateway.id] = action.companyGateway);
}
CompanyGatewayState _restoreCompanyGatewayFailure(
CompanyGatewayState companyGatewayState, RestoreCompanyGatewayFailure action) {
return companyGatewayState.rebuild((b) => b..map[action.companyGateway.id] = action.companyGateway);
}
CompanyGatewayState _addCompanyGateway(CompanyGatewayState companyGatewayState, AddCompanyGatewaySuccess action) {
return companyGatewayState.rebuild((b) => b
..map[action.companyGateway.id] = action.companyGateway
..list.add(action.companyGateway.id));
}
CompanyGatewayState _updateCompanyGateway(CompanyGatewayState companyGatewayState, SaveCompanyGatewaySuccess action) {
return companyGatewayState.rebuild((b) => b
..map[action.companyGateway.id] = action.companyGateway);
}
CompanyGatewayState _setLoadedCompanyGateway(
CompanyGatewayState companyGatewayState, LoadCompanyGatewaySuccess action) {
return companyGatewayState.rebuild((b) => b
..map[action.companyGateway.id] = action.companyGateway);
}
CompanyGatewayState _setLoadedCompanyGateways(
CompanyGatewayState companyGatewayState, LoadCompanyGatewaysSuccess action) {
final state = companyGatewayState.rebuild((b) => b
..lastUpdated = DateTime.now().millisecondsSinceEpoch
..map.addAll(Map.fromIterable(
action.companyGateways,
key: (dynamic item) => item.id,
value: (dynamic item) => item,
)));
return state.rebuild((b) => b..list.replace(state.map.keys));
}

View File

@ -0,0 +1,74 @@
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:memoize/memoize.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
var memoizedDropdownCompanyGatewayList = memo3(
(BuiltMap<String, CompanyGatewayEntity> companyGatewayMap, BuiltList<String> companyGatewayList,
String clientId) =>
dropdownCompanyGatewaysSelector(companyGatewayMap, companyGatewayList, clientId));
List<String> dropdownCompanyGatewaysSelector(BuiltMap<String, CompanyGatewayEntity> companyGatewayMap,
BuiltList<String> companyGatewayList, String clientId) {
final list = companyGatewayList.where((companyGatewayId) {
final companyGateway = companyGatewayMap[companyGatewayId];
/*
if (clientId != null && clientId > 0 && companyGateway.clientId != clientId) {
return false;
}
*/
return companyGateway.isActive;
}).toList();
list.sort((companyGatewayAId, companyGatewayBId) {
final companyGatewayA = companyGatewayMap[companyGatewayAId];
final companyGatewayB = companyGatewayMap[companyGatewayBId];
return companyGatewayA.compareTo(companyGatewayB, CompanyGatewayFields.name, true);
});
return list;
}
var memoizedFilteredCompanyGatewayList = memo3((BuiltMap<String, CompanyGatewayEntity> companyGatewayMap,
BuiltList<String> companyGatewayList, ListUIState companyGatewayListState) =>
filteredCompanyGatewaysSelector(companyGatewayMap, companyGatewayList, companyGatewayListState));
List<String> filteredCompanyGatewaysSelector(BuiltMap<String, CompanyGatewayEntity> companyGatewayMap,
BuiltList<String> companyGatewayList, ListUIState companyGatewayListState) {
final list = companyGatewayList.where((companyGatewayId) {
final companyGateway = companyGatewayMap[companyGatewayId];
if (companyGatewayListState.filterEntityId != null &&
companyGateway.entityId != companyGatewayListState.filterEntityId) {
return false;
} else {
}
if (!companyGateway.matchesStates(companyGatewayListState.stateFilters)) {
return false;
}
if (companyGatewayListState.custom1Filters.isNotEmpty &&
!companyGatewayListState.custom1Filters.contains(companyGateway.customValue1)) {
return false;
}
if (companyGatewayListState.custom2Filters.isNotEmpty &&
!companyGatewayListState.custom2Filters.contains(companyGateway.customValue2)) {
return false;
}
return companyGateway.matchesFilter(companyGatewayListState.filter);
}).toList();
list.sort((companyGatewayAId, companyGatewayBId) {
final companyGatewayA = companyGatewayMap[companyGatewayAId];
final companyGatewayB = companyGatewayMap[companyGatewayBId];
return companyGatewayA.compareTo(
companyGatewayB, companyGatewayListState.sortField, companyGatewayListState.sortAscending);
});
return list;
}
bool hasCompanyGatewayChanges(
CompanyGatewayEntity companyGateway, BuiltMap<String, CompanyGatewayEntity> companyGatewayMap) =>
companyGateway.isNew ? companyGateway.isChanged : companyGateway != companyGatewayMap[companyGateway.id];

View File

@ -0,0 +1,61 @@
import 'dart:async';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/redux/ui/entity_ui_state.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
part 'company_gateway_state.g.dart';
abstract class CompanyGatewayState implements Built<CompanyGatewayState, CompanyGatewayStateBuilder> {
factory CompanyGatewayState() {
return _$CompanyGatewayState._(
lastUpdated: 0,
map: BuiltMap<String, CompanyGatewayEntity>(),
list: BuiltList<String>(),
);
}
CompanyGatewayState._();
@nullable
int get lastUpdated;
BuiltMap<String, CompanyGatewayEntity> get map;
BuiltList<String> get list;
bool get isStale {
if (! isLoaded) {
return true;
}
return DateTime.now().millisecondsSinceEpoch - lastUpdated > kMillisecondsToRefreshData;
}
bool get isLoaded => lastUpdated != null && lastUpdated > 0;
static Serializer<CompanyGatewayState> get serializer => _$companyGatewayStateSerializer;
}
abstract class CompanyGatewayUIState extends Object with EntityUIState implements Built<CompanyGatewayUIState, CompanyGatewayUIStateBuilder> {
factory CompanyGatewayUIState() {
return _$CompanyGatewayUIState._(
listUIState: ListUIState(CompanyGatewayFields.name),
editing: CompanyGatewayEntity(),
selectedId: '',
);
}
CompanyGatewayUIState._();
@nullable
CompanyGatewayEntity get editing;
@override
bool get isCreatingNew => editing.isNew;
static Serializer<CompanyGatewayUIState> get serializer => _$companyGatewayUIStateSerializer;
}

View File

@ -0,0 +1,429 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'company_gateway_state.dart';
// **************************************************************************
// BuiltValueGenerator
// **************************************************************************
Serializer<CompanyGatewayState> _$companyGatewayStateSerializer =
new _$CompanyGatewayStateSerializer();
Serializer<CompanyGatewayUIState> _$companyGatewayUIStateSerializer =
new _$CompanyGatewayUIStateSerializer();
class _$CompanyGatewayStateSerializer
implements StructuredSerializer<CompanyGatewayState> {
@override
final Iterable<Type> types = const [
CompanyGatewayState,
_$CompanyGatewayState
];
@override
final String wireName = 'CompanyGatewayState';
@override
Iterable<Object> serialize(
Serializers serializers, CompanyGatewayState object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'map',
serializers.serialize(object.map,
specifiedType: const FullType(BuiltMap, const [
const FullType(String),
const FullType(CompanyGatewayEntity)
])),
'list',
serializers.serialize(object.list,
specifiedType:
const FullType(BuiltList, const [const FullType(String)])),
];
if (object.lastUpdated != null) {
result
..add('lastUpdated')
..add(serializers.serialize(object.lastUpdated,
specifiedType: const FullType(int)));
}
return result;
}
@override
CompanyGatewayState deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new CompanyGatewayStateBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'lastUpdated':
result.lastUpdated = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
break;
case 'map':
result.map.replace(serializers.deserialize(value,
specifiedType: const FullType(BuiltMap, const [
const FullType(String),
const FullType(CompanyGatewayEntity)
])) as BuiltMap<dynamic, dynamic>);
break;
case 'list':
result.list.replace(serializers.deserialize(value,
specifiedType:
const FullType(BuiltList, const [const FullType(String)]))
as BuiltList<dynamic>);
break;
}
}
return result.build();
}
}
class _$CompanyGatewayUIStateSerializer
implements StructuredSerializer<CompanyGatewayUIState> {
@override
final Iterable<Type> types = const [
CompanyGatewayUIState,
_$CompanyGatewayUIState
];
@override
final String wireName = 'CompanyGatewayUIState';
@override
Iterable<Object> serialize(
Serializers serializers, CompanyGatewayUIState object,
{FullType specifiedType = FullType.unspecified}) {
final result = <Object>[
'listUIState',
serializers.serialize(object.listUIState,
specifiedType: const FullType(ListUIState)),
];
if (object.editing != null) {
result
..add('editing')
..add(serializers.serialize(object.editing,
specifiedType: const FullType(CompanyGatewayEntity)));
}
if (object.selectedId != null) {
result
..add('selectedId')
..add(serializers.serialize(object.selectedId,
specifiedType: const FullType(String)));
}
return result;
}
@override
CompanyGatewayUIState deserialize(
Serializers serializers, Iterable<Object> serialized,
{FullType specifiedType = FullType.unspecified}) {
final result = new CompanyGatewayUIStateBuilder();
final iterator = serialized.iterator;
while (iterator.moveNext()) {
final key = iterator.current as String;
iterator.moveNext();
final dynamic value = iterator.current;
switch (key) {
case 'editing':
result.editing.replace(serializers.deserialize(value,
specifiedType: const FullType(CompanyGatewayEntity))
as CompanyGatewayEntity);
break;
case 'listUIState':
result.listUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(ListUIState)) as ListUIState);
break;
case 'selectedId':
result.selectedId = serializers.deserialize(value,
specifiedType: const FullType(String)) as String;
break;
}
}
return result.build();
}
}
class _$CompanyGatewayState extends CompanyGatewayState {
@override
final int lastUpdated;
@override
final BuiltMap<String, CompanyGatewayEntity> map;
@override
final BuiltList<String> list;
factory _$CompanyGatewayState(
[void Function(CompanyGatewayStateBuilder) updates]) =>
(new CompanyGatewayStateBuilder()..update(updates)).build();
_$CompanyGatewayState._({this.lastUpdated, this.map, this.list}) : super._() {
if (map == null) {
throw new BuiltValueNullFieldError('CompanyGatewayState', 'map');
}
if (list == null) {
throw new BuiltValueNullFieldError('CompanyGatewayState', 'list');
}
}
@override
CompanyGatewayState rebuild(
void Function(CompanyGatewayStateBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
CompanyGatewayStateBuilder toBuilder() =>
new CompanyGatewayStateBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is CompanyGatewayState &&
lastUpdated == other.lastUpdated &&
map == other.map &&
list == other.list;
}
@override
int get hashCode {
return $jf(
$jc($jc($jc(0, lastUpdated.hashCode), map.hashCode), list.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('CompanyGatewayState')
..add('lastUpdated', lastUpdated)
..add('map', map)
..add('list', list))
.toString();
}
}
class CompanyGatewayStateBuilder
implements Builder<CompanyGatewayState, CompanyGatewayStateBuilder> {
_$CompanyGatewayState _$v;
int _lastUpdated;
int get lastUpdated => _$this._lastUpdated;
set lastUpdated(int lastUpdated) => _$this._lastUpdated = lastUpdated;
MapBuilder<String, CompanyGatewayEntity> _map;
MapBuilder<String, CompanyGatewayEntity> get map =>
_$this._map ??= new MapBuilder<String, CompanyGatewayEntity>();
set map(MapBuilder<String, CompanyGatewayEntity> map) => _$this._map = map;
ListBuilder<String> _list;
ListBuilder<String> get list => _$this._list ??= new ListBuilder<String>();
set list(ListBuilder<String> list) => _$this._list = list;
CompanyGatewayStateBuilder();
CompanyGatewayStateBuilder get _$this {
if (_$v != null) {
_lastUpdated = _$v.lastUpdated;
_map = _$v.map?.toBuilder();
_list = _$v.list?.toBuilder();
_$v = null;
}
return this;
}
@override
void replace(CompanyGatewayState other) {
if (other == null) {
throw new ArgumentError.notNull('other');
}
_$v = other as _$CompanyGatewayState;
}
@override
void update(void Function(CompanyGatewayStateBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$CompanyGatewayState build() {
_$CompanyGatewayState _$result;
try {
_$result = _$v ??
new _$CompanyGatewayState._(
lastUpdated: lastUpdated, map: map.build(), list: list.build());
} catch (_) {
String _$failedField;
try {
_$failedField = 'map';
map.build();
_$failedField = 'list';
list.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'CompanyGatewayState', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
class _$CompanyGatewayUIState extends CompanyGatewayUIState {
@override
final CompanyGatewayEntity editing;
@override
final ListUIState listUIState;
@override
final String selectedId;
@override
final Completer<SelectableEntity> saveCompleter;
@override
final Completer<Null> cancelCompleter;
factory _$CompanyGatewayUIState(
[void Function(CompanyGatewayUIStateBuilder) updates]) =>
(new CompanyGatewayUIStateBuilder()..update(updates)).build();
_$CompanyGatewayUIState._(
{this.editing,
this.listUIState,
this.selectedId,
this.saveCompleter,
this.cancelCompleter})
: super._() {
if (listUIState == null) {
throw new BuiltValueNullFieldError(
'CompanyGatewayUIState', 'listUIState');
}
}
@override
CompanyGatewayUIState rebuild(
void Function(CompanyGatewayUIStateBuilder) updates) =>
(toBuilder()..update(updates)).build();
@override
CompanyGatewayUIStateBuilder toBuilder() =>
new CompanyGatewayUIStateBuilder()..replace(this);
@override
bool operator ==(Object other) {
if (identical(other, this)) return true;
return other is CompanyGatewayUIState &&
editing == other.editing &&
listUIState == other.listUIState &&
selectedId == other.selectedId &&
saveCompleter == other.saveCompleter &&
cancelCompleter == other.cancelCompleter;
}
@override
int get hashCode {
return $jf($jc(
$jc(
$jc($jc($jc(0, editing.hashCode), listUIState.hashCode),
selectedId.hashCode),
saveCompleter.hashCode),
cancelCompleter.hashCode));
}
@override
String toString() {
return (newBuiltValueToStringHelper('CompanyGatewayUIState')
..add('editing', editing)
..add('listUIState', listUIState)
..add('selectedId', selectedId)
..add('saveCompleter', saveCompleter)
..add('cancelCompleter', cancelCompleter))
.toString();
}
}
class CompanyGatewayUIStateBuilder
implements Builder<CompanyGatewayUIState, CompanyGatewayUIStateBuilder> {
_$CompanyGatewayUIState _$v;
CompanyGatewayEntityBuilder _editing;
CompanyGatewayEntityBuilder get editing =>
_$this._editing ??= new CompanyGatewayEntityBuilder();
set editing(CompanyGatewayEntityBuilder editing) => _$this._editing = editing;
ListUIStateBuilder _listUIState;
ListUIStateBuilder get listUIState =>
_$this._listUIState ??= new ListUIStateBuilder();
set listUIState(ListUIStateBuilder listUIState) =>
_$this._listUIState = listUIState;
String _selectedId;
String get selectedId => _$this._selectedId;
set selectedId(String selectedId) => _$this._selectedId = selectedId;
Completer<SelectableEntity> _saveCompleter;
Completer<SelectableEntity> get saveCompleter => _$this._saveCompleter;
set saveCompleter(Completer<SelectableEntity> saveCompleter) =>
_$this._saveCompleter = saveCompleter;
Completer<Null> _cancelCompleter;
Completer<Null> get cancelCompleter => _$this._cancelCompleter;
set cancelCompleter(Completer<Null> cancelCompleter) =>
_$this._cancelCompleter = cancelCompleter;
CompanyGatewayUIStateBuilder();
CompanyGatewayUIStateBuilder get _$this {
if (_$v != null) {
_editing = _$v.editing?.toBuilder();
_listUIState = _$v.listUIState?.toBuilder();
_selectedId = _$v.selectedId;
_saveCompleter = _$v.saveCompleter;
_cancelCompleter = _$v.cancelCompleter;
_$v = null;
}
return this;
}
@override
void replace(CompanyGatewayUIState other) {
if (other == null) {
throw new ArgumentError.notNull('other');
}
_$v = other as _$CompanyGatewayUIState;
}
@override
void update(void Function(CompanyGatewayUIStateBuilder) updates) {
if (updates != null) updates(this);
}
@override
_$CompanyGatewayUIState build() {
_$CompanyGatewayUIState _$result;
try {
_$result = _$v ??
new _$CompanyGatewayUIState._(
editing: _editing?.build(),
listUIState: listUIState.build(),
selectedId: selectedId,
saveCompleter: saveCompleter,
cancelCompleter: cancelCompleter);
} catch (_) {
String _$failedField;
try {
_$failedField = 'editing';
_editing?.build();
_$failedField = 'listUIState';
listUIState.build();
} catch (e) {
throw new BuiltValueNestedFieldError(
'CompanyGatewayUIState', _$failedField, e.toString());
}
rethrow;
}
replace(_$result);
return _$result;
}
}
// ignore_for_file: always_put_control_body_on_new_line,always_specify_types,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new

View File

@ -20,6 +20,8 @@ import 'package:invoiceninja_flutter/redux/quote/quote_reducer.dart';
import 'package:invoiceninja_flutter/redux/task/task_reducer.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_reducer.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_reducer.dart';
import 'package:invoiceninja_flutter/redux/group/group_reducer.dart';
UIState uiReducer(UIState state, dynamic action) {
@ -52,6 +54,8 @@ UIState uiReducer(UIState state, dynamic action) {
..dashboardUIState
.replace(dashboardUIReducer(state.dashboardUIState, action))
// STARTER: reducer - do not remove comment
..companyGatewayUIState.replace(companyGatewayUIReducer(state.companyGatewayUIState, action))
..groupUIState.replace(groupUIReducer(state.groupUIState, action))
..documentUIState.replace(documentUIReducer(state.documentUIState, action))
..expenseUIState.replace(expenseUIReducer(state.expenseUIState, action))

View File

@ -16,6 +16,8 @@ import 'package:invoiceninja_flutter/redux/quote/quote_state.dart';
import 'package:invoiceninja_flutter/redux/task/task_state.dart';
import 'package:invoiceninja_flutter/redux/vendor/vendor_state.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_state.dart';
import 'package:invoiceninja_flutter/redux/group/group_state.dart';
part 'ui_state.g.dart';
@ -49,6 +51,8 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
clientUIState: ClientUIState(),
invoiceUIState: InvoiceUIState(),
// STARTER: constructor - do not remove comment
companyGatewayUIState: CompanyGatewayUIState(),
groupUIState: GroupUIState(),
documentUIState: DocumentUIState(),
@ -102,6 +106,8 @@ abstract class UIState implements Built<UIState, UIStateBuilder> {
InvoiceUIState get invoiceUIState;
// STARTER: properties - do not remove comment
CompanyGatewayUIState get companyGatewayUIState;
GroupUIState get groupUIState;
DocumentUIState get documentUIState;

View File

@ -114,6 +114,9 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
'invoiceUIState',
serializers.serialize(object.invoiceUIState,
specifiedType: const FullType(InvoiceUIState)),
'companyGatewayUIState',
serializers.serialize(object.companyGatewayUIState,
specifiedType: const FullType(CompanyGatewayUIState)),
'groupUIState',
serializers.serialize(object.groupUIState,
specifiedType: const FullType(GroupUIState)),
@ -235,6 +238,11 @@ class _$UIStateSerializer implements StructuredSerializer<UIState> {
result.invoiceUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(InvoiceUIState)) as InvoiceUIState);
break;
case 'companyGatewayUIState':
result.companyGatewayUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(CompanyGatewayUIState))
as CompanyGatewayUIState);
break;
case 'groupUIState':
result.groupUIState.replace(serializers.deserialize(value,
specifiedType: const FullType(GroupUIState)) as GroupUIState);
@ -352,6 +360,8 @@ class _$UIState extends UIState {
@override
final InvoiceUIState invoiceUIState;
@override
final CompanyGatewayUIState companyGatewayUIState;
@override
final GroupUIState groupUIState;
@override
final DocumentUIState documentUIState;
@ -392,6 +402,7 @@ class _$UIState extends UIState {
this.productUIState,
this.clientUIState,
this.invoiceUIState,
this.companyGatewayUIState,
this.groupUIState,
this.documentUIState,
this.expenseUIState,
@ -454,6 +465,9 @@ class _$UIState extends UIState {
if (invoiceUIState == null) {
throw new BuiltValueNullFieldError('UIState', 'invoiceUIState');
}
if (companyGatewayUIState == null) {
throw new BuiltValueNullFieldError('UIState', 'companyGatewayUIState');
}
if (groupUIState == null) {
throw new BuiltValueNullFieldError('UIState', 'groupUIState');
}
@ -512,6 +526,7 @@ class _$UIState extends UIState {
productUIState == other.productUIState &&
clientUIState == other.clientUIState &&
invoiceUIState == other.invoiceUIState &&
companyGatewayUIState == other.companyGatewayUIState &&
groupUIState == other.groupUIState &&
documentUIState == other.documentUIState &&
expenseUIState == other.expenseUIState &&
@ -543,17 +558,17 @@ class _$UIState extends UIState {
$jc(
$jc(
$jc(
$jc($jc($jc($jc($jc($jc($jc($jc($jc(0, layout.hashCode), isTesting.hashCode), isMenuVisible.hashCode), isHistoryVisible.hashCode), selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), enableDarkMode.hashCode),
longPressSelectionIsDefault.hashCode),
requireAuthentication.hashCode),
emailPayment.hashCode),
autoStartTasks.hashCode),
addDocumentsToInvoice.hashCode),
filter.hashCode),
dashboardUIState.hashCode),
productUIState.hashCode),
clientUIState.hashCode),
invoiceUIState.hashCode),
$jc($jc($jc($jc($jc($jc($jc($jc($jc($jc(0, layout.hashCode), isTesting.hashCode), isMenuVisible.hashCode), isHistoryVisible.hashCode), selectedCompanyIndex.hashCode), currentRoute.hashCode), previousRoute.hashCode), enableDarkMode.hashCode), longPressSelectionIsDefault.hashCode),
requireAuthentication.hashCode),
emailPayment.hashCode),
autoStartTasks.hashCode),
addDocumentsToInvoice.hashCode),
filter.hashCode),
dashboardUIState.hashCode),
productUIState.hashCode),
clientUIState.hashCode),
invoiceUIState.hashCode),
companyGatewayUIState.hashCode),
groupUIState.hashCode),
documentUIState.hashCode),
expenseUIState.hashCode),
@ -586,6 +601,7 @@ class _$UIState extends UIState {
..add('productUIState', productUIState)
..add('clientUIState', clientUIState)
..add('invoiceUIState', invoiceUIState)
..add('companyGatewayUIState', companyGatewayUIState)
..add('groupUIState', groupUIState)
..add('documentUIState', documentUIState)
..add('expenseUIState', expenseUIState)
@ -691,6 +707,13 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
set invoiceUIState(InvoiceUIStateBuilder invoiceUIState) =>
_$this._invoiceUIState = invoiceUIState;
CompanyGatewayUIStateBuilder _companyGatewayUIState;
CompanyGatewayUIStateBuilder get companyGatewayUIState =>
_$this._companyGatewayUIState ??= new CompanyGatewayUIStateBuilder();
set companyGatewayUIState(
CompanyGatewayUIStateBuilder companyGatewayUIState) =>
_$this._companyGatewayUIState = companyGatewayUIState;
GroupUIStateBuilder _groupUIState;
GroupUIStateBuilder get groupUIState =>
_$this._groupUIState ??= new GroupUIStateBuilder();
@ -767,6 +790,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
_productUIState = _$v.productUIState?.toBuilder();
_clientUIState = _$v.clientUIState?.toBuilder();
_invoiceUIState = _$v.invoiceUIState?.toBuilder();
_companyGatewayUIState = _$v.companyGatewayUIState?.toBuilder();
_groupUIState = _$v.groupUIState?.toBuilder();
_documentUIState = _$v.documentUIState?.toBuilder();
_expenseUIState = _$v.expenseUIState?.toBuilder();
@ -818,6 +842,7 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
productUIState: productUIState.build(),
clientUIState: clientUIState.build(),
invoiceUIState: invoiceUIState.build(),
companyGatewayUIState: companyGatewayUIState.build(),
groupUIState: groupUIState.build(),
documentUIState: documentUIState.build(),
expenseUIState: expenseUIState.build(),
@ -838,6 +863,8 @@ class UIStateBuilder implements Builder<UIState, UIStateBuilder> {
clientUIState.build();
_$failedField = 'invoiceUIState';
invoiceUIState.build();
_$failedField = 'companyGatewayUIState';
companyGatewayUIState.build();
_$failedField = 'groupUIState';
groupUIState.build();
_$failedField = 'documentUIState';

View File

@ -25,6 +25,8 @@ import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart';
import 'package:invoiceninja_flutter/redux/quote/quote_actions.dart';
import 'package:url_launcher/url_launcher.dart';
// STARTER: import - do not remove comment
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
class AppDrawer extends StatelessWidget {
const AppDrawer({
@ -317,6 +319,19 @@ class AppDrawer extends StatelessWidget {
),
*/
// STARTER: menu - do not remove comment
DrawerTile(
company: company,
entityType: EntityType.companyGateway,
icon: getEntityIcon(EntityType.companyGateway),
title: localization.companyGateways,
onTap: () => store.dispatch(ViewcompanyGatewayList(context)),
onCreateTap: () {
navigator.pop();
store.dispatch(EditCompanyGateway(
companyGateway: CompanyGatewayEntity(), context: context));
},
),
DrawerTile(
company: company,
icon: FontAwesomeIcons.cog,

View File

@ -0,0 +1,166 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/lists/list_divider.dart';
import 'package:invoiceninja_flutter/ui/app/loading_indicator.dart';
import 'package:invoiceninja_flutter/ui/app/help_text.dart';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_list_item.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_list_vm.dart';
import 'package:invoiceninja_flutter/utils/icons.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class CompanyGatewayList extends StatelessWidget {
const CompanyGatewayList({
Key key,
@required this.viewModel,
}) : super(key: key);
final CompanyGatewayListVM viewModel;
@override
Widget build(BuildContext context) {
/*
final localization = AppLocalization.of(context);
final listState = viewModel.listState;
final filteredClientId = listState.filterEntityId;
final filteredClient =
filteredClientId != null ? viewModel.clientMap[filteredClientId] : null;
*/
return Column(
children: <Widget>[
Expanded(
child: !viewModel.isLoaded
? (viewModel.isLoading ? LoadingIndicator() : SizedBox())
: RefreshIndicator(
onRefresh: () => viewModel.onRefreshed(context),
child: viewModel.companyGatewayList.isEmpty
? HelpText(AppLocalization.of(context).noRecordsFound)
: ListView.separated(
shrinkWrap: true,
separatorBuilder: (context, index) => ListDivider(),
itemCount: viewModel.companyGatewayList.length,
itemBuilder: (BuildContext context, index) {
final companyGatewayId = viewModel.companyGatewayList[index];
final companyGateway = viewModel.companyGatewayMap[companyGatewayId];
final userCompany = viewModel.userCompany;
void showDialog() => showEntityActionsDialog(
userCompany: userCompany,
entity: companyGateway,
context: context,
onEntityAction: viewModel.onEntityAction);
return CompanyGatewayListItem(
user: viewModel.userCompany.user,
filter: viewModel.filter,
companyGateway: companyGateway,
onTap: () =>
viewModel.onCompanyGatewayTap(context, companyGateway),
onEntityAction: (EntityAction action) {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
context, companyGateway, action);
}
},
onLongPress: () =>
showDialog(),
);
},
),
),
),
/*
filteredClient != null
? Material(
color: Colors.orangeAccent,
elevation: 6.0,
child: InkWell(
onTap: () => viewModel.onViewEntityFilterPressed(context),
child: Row(
children: <Widget>[
SizedBox(width: 18.0),
Expanded(
child: Text(
'${localization.filteredBy} ${filteredClient.listDisplayName}',
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
),
),
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.white,
),
onPressed: () => viewModel.onClearEntityFilterPressed(),
)
],
),
),
)
: Container(),
Expanded(
child: !viewModel.isLoaded
? LoadingIndicator()
: RefreshIndicator(
onRefresh: () => viewModel.onRefreshed(context),
child: viewModel.companyGatewayList.isEmpty
? HelpText(AppLocalization.of(context).noRecordsFound)
: ListView.separated(
shrinkWrap: true,
separatorBuilder: (context, index) => ListDivider(),
itemCount: viewModel.companyGatewayList.length,
itemBuilder: (BuildContext context, index) {
final user = viewModel.user;
final companyGatewayId = viewModel.companyGatewayList[index];
final companyGateway = viewModel.companyGatewayMap[companyGatewayId];
final client =
viewModel.clientMap[companyGateway.clientId] ??
ClientEntity();
void showDialog() => showEntityActionsDialog(
entity: companyGateway,
context: context,
user: user,
onEntityAction: viewModel.onEntityAction);
return CompanyGatewayListItem(
user: viewModel.user,
filter: viewModel.filter,
companyGateway: companyGateway,
client:
viewModel.clientMap[companyGateway.clientId] ??
ClientEntity(),
onTap: () =>
viewModel.onCompanyGatewayTap(context, companyGateway),
onEntityAction: (EntityAction action) {
if (action == EntityAction.more) {
showDialog();
} else {
viewModel.onEntityAction(
context, companyGateway, action);
}
},
onLongPress: () =>
showDialog(),
);
},
),
),
),*/
],
);
}
}

View File

@ -0,0 +1,97 @@
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/ui/app/entity_state_label.dart';
import 'package:invoiceninja_flutter/utils/formatting.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/dismissible_entity.dart';
class CompanyGatewayListItem extends StatelessWidget {
const CompanyGatewayListItem({
@required this.user,
@required this.onEntityAction,
@required this.onTap,
@required this.onLongPress,
//@required this.onCheckboxChanged,
@required this.companyGateway,
@required this.filter,
});
final UserEntity user;
final Function(EntityAction) onEntityAction;
final GestureTapCallback onTap;
final GestureTapCallback onLongPress;
//final ValueChanged<bool> onCheckboxChanged;
final CompanyGatewayEntity companyGateway;
final String filter;
static final companyGatewayItemKey = (int id) => Key('__company_gateway_item_${id}__');
@override
Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final uiState = state.uiState;
final companyGatewayUIState = uiState.companyGatewayUIState;
final filterMatch = filter != null && filter.isNotEmpty
? companyGateway.matchesFilterValue(filter)
: null;
final subtitle = filterMatch;
return DismissibleEntity(
userCompany: state.userCompany,
entity: companyGateway,
isSelected: companyGateway.id ==
(uiState.isEditing
? companyGatewayUIState.editing.id
: companyGatewayUIState.selectedId),
onEntityAction: onEntityAction,
child: ListTile(
onTap: onTap,
onLongPress: onLongPress,
/*
leading: Checkbox(
//key: NinjaKeys.companyGatewayItemCheckbox(companyGateway.id),
value: true,
//onChanged: onCheckboxChanged,
onChanged: (value) {
return true;
},
),
*/
title: Container(
width: MediaQuery.of(context).size.width,
child: Row(
children: <Widget>[
Expanded(
child: Text(
companyGateway.name,
//key: NinjaKeys.clientItemClientKey(client.id),
style: Theme.of(context).textTheme.title,
),
),
Text(formatNumber(companyGateway.listDisplayAmount, context),
style: Theme.of(context).textTheme.title),
],
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
subtitle != null && subtitle.isNotEmpty ?
Text(
subtitle,
maxLines: 3,
overflow: TextOverflow.ellipsis,
) : Container(),
EntityStateLabel(companyGateway),
],
),
),
);
}
}

View File

@ -0,0 +1,102 @@
import 'dart:async';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:redux/redux.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/list_ui_state.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_selectors.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_list.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
class CompanyGatewayListBuilder extends StatelessWidget {
const CompanyGatewayListBuilder({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, CompanyGatewayListVM>(
converter: CompanyGatewayListVM.fromStore,
builder: (context, viewModel) {
return CompanyGatewayList(
viewModel: viewModel,
);
},
);
}
}
class CompanyGatewayListVM {
CompanyGatewayListVM({
@required this.userCompany,
@required this.companyGatewayList,
@required this.companyGatewayMap,
@required this.filter,
@required this.isLoading,
@required this.isLoaded,
@required this.onCompanyGatewayTap,
@required this.listState,
@required this.onRefreshed,
@required this.onEntityAction,
@required this.onClearEntityFilterPressed,
@required this.onViewEntityFilterPressed,
});
static CompanyGatewayListVM fromStore(Store<AppState> store) {
Future<Null> _handleRefresh(BuildContext context) {
if (store.state.isLoading) {
return Future<Null>(null);
}
final completer = snackBarCompleter(
context, AppLocalization.of(context).refreshComplete);
store.dispatch(LoadCompanyGateways(completer: completer, force: true));
return completer.future;
}
final state = store.state;
return CompanyGatewayListVM(
userCompany: state.userCompany,
listState: state.companyGatewayListState,
companyGatewayList: memoizedFilteredCompanyGatewayList(state.companyGatewayState.map,
state.companyGatewayState.list, state.companyGatewayListState),
companyGatewayMap: state.companyGatewayState.map,
isLoading: state.isLoading,
isLoaded: state.companyGatewayState.isLoaded,
filter: state.companyGatewayUIState.listUIState.filter,
onClearEntityFilterPressed: () =>
store.dispatch(FilterCompanyGatewaysByEntity()),
onViewEntityFilterPressed: (BuildContext context) => store.dispatch(
ViewClient(
clientId: state.companyGatewayListState.filterEntityId,
context: context)),
onCompanyGatewayTap: (context, companyGateway) {
store.dispatch(ViewCompanyGateway(companyGatewayId: companyGateway.id, context: context));
},
onEntityAction:
(BuildContext context, BaseEntity companyGateway, EntityAction action) =>
handleCompanyGatewayAction(context, companyGateway, action),
onRefreshed: (context) => _handleRefresh(context),
);
}
final UserCompanyEntity userCompany;
final List<String> companyGatewayList;
final BuiltMap<String, CompanyGatewayEntity> companyGatewayMap;
final ListUIState listState;
final String filter;
final bool isLoading;
final bool isLoaded;
final Function(BuildContext, CompanyGatewayEntity) onCompanyGatewayTap;
final Function(BuildContext) onRefreshed;
final Function(BuildContext, CompanyGatewayEntity, EntityAction) onEntityAction;
final Function onClearEntityFilterPressed;
final Function(BuildContext) onViewEntityFilterPressed;
}

View File

@ -0,0 +1,78 @@
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/ui/app/app_scaffold.dart';
import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/ui/app/list_filter.dart';
import 'package:invoiceninja_flutter/ui/app/list_filter_button.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_list_vm.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/ui/app/app_drawer_vm.dart';
import 'package:invoiceninja_flutter/ui/app/app_bottom_bar.dart';
class CompanyGatewayScreen extends StatelessWidget {
static const String route = '/company_gateway';
@override
Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
final company = state.selectedCompany;
final localization = AppLocalization.of(context);
return AppScaffold(
appBarTitle: ListFilter(
key: ValueKey(state.companyGatewayListState.filterClearedAt),
entityType: EntityType.companyGateway,
onFilterChanged: (value) {
store.dispatch(FilterCompanyGateways(value));
},
),
appBarActions: [
ListFilterButton(
entityType: EntityType.companyGateway,
onFilterPressed: (String value) {
store.dispatch(FilterCompanyGateways(value));
},
),
],
body: CompanyGatewayListBuilder(),
bottomNavigationBar: AppBottomBar(
entityType: EntityType.companyGateway,
onSelectedSortField: (value) => store.dispatch(SortCompanyGateways(value)),
customValues1: company.getCustomFieldValues(CustomFieldType.companyGateway1,
excludeBlank: true),
customValues2: company.getCustomFieldValues(CustomFieldType.companyGateway2,
excludeBlank: true),
onSelectedCustom1: (value) =>
store.dispatch(FilterCompanyGatewaysByCustom1(value)),
onSelectedCustom2: (value) =>
store.dispatch(FilterCompanyGatewaysByCustom2(value)),
sortFields: [
CompanyGatewayFields.updatedAt,
],
onSelectedState: (EntityState state, value) {
store.dispatch(FilterCompanyGatewaysByState(state));
},
),
floatingActionButton: user.canCreate(EntityType.companyGateway)
? FloatingActionButton(
heroTag: 'company_gateway_fab',
backgroundColor: Theme.of(context).primaryColorDark,
onPressed: () {
store.dispatch(
EditCompanyGateway(companyGateway: CompanyGatewayEntity(), context: context));
},
child: Icon(
Icons.add,
color: Colors.white,
),
tooltip: localization.newCompanyGateway,
)
: null,
);
}
}

View File

@ -0,0 +1,122 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/edit/company_gateway_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/action_icon_button.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
class CompanyGatewayEdit extends StatefulWidget {
const CompanyGatewayEdit({
Key key,
@required this.viewModel,
}) : super(key: key);
final CompanyGatewayEditVM viewModel;
@override
_CompanyGatewayEditState createState() => _CompanyGatewayEditState();
}
class _CompanyGatewayEditState extends State<CompanyGatewayEdit> {
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
// STARTER: controllers - do not remove comment
List<TextEditingController> _controllers = [];
@override
void didChangeDependencies() {
_controllers = [
// STARTER: array - do not remove comment
];
_controllers.forEach((controller) => controller.removeListener(_onChanged));
final companyGateway = widget.viewModel.companyGateway;
// STARTER: read value - do not remove comment
_controllers.forEach((controller) => controller.addListener(_onChanged));
super.didChangeDependencies();
}
@override
void dispose() {
_controllers.forEach((controller) {
controller.removeListener(_onChanged);
controller.dispose();
});
super.dispose();
}
void _onChanged() {
final companyGateway = widget.viewModel.companyGateway.rebuild((b) => b
// STARTER: set value - do not remove comment
);
if (companyGateway != widget.viewModel.companyGateway) {
widget.viewModel.onChanged(companyGateway);
}
}
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final localization = AppLocalization.of(context);
final companyGateway = viewModel.companyGateway;
return WillPopScope(
onWillPop: () async {
viewModel.onBackPressed();
return true;
},
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: isMobile(context),
title: Text(viewModel.companyGateway.isNew
? localization.newCompanyGateway
: localization.editCompanyGateway),
actions: <Widget>[
if (!isMobile(context))
FlatButton(
child: Text(
localization.cancel,
style: TextStyle(color: Colors.white),
),
onPressed: () => viewModel.onCancelPressed(context),
),
ActionIconButton(
icon: Icons.cloud_upload,
tooltip: localization.save,
isVisible: !companyGateway.isDeleted,
isDirty: companyGateway.isNew || companyGateway != viewModel.origCompanyGateway,
isSaving: viewModel.isSaving,
onPressed: () {
if (! _formKey.currentState.validate()) {
return;
}
viewModel.onSavePressed(context);
},
),
],
),
body: Form(
key: _formKey,
child: Builder(builder: (BuildContext context) {
return ListView(
children: <Widget>[
FormCard(
children: <Widget>[
// STARTER: widgets - do not remove comment
],
),
],
);
})
),
),
);
}
}

View File

@ -0,0 +1,108 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_screen.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/view/company_gateway_view_vm.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/edit/company_gateway_edit.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class CompanyGatewayEditScreen extends StatelessWidget {
const CompanyGatewayEditScreen({Key key}) : super(key: key);
static const String route = '/company_gateway/edit';
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, CompanyGatewayEditVM>(
converter: (Store<AppState> store) {
return CompanyGatewayEditVM.fromStore(store);
},
builder: (context, viewModel) {
return CompanyGatewayEdit(
viewModel: viewModel,
key: ValueKey(viewModel.companyGateway.id),
);
},
);
}
}
class CompanyGatewayEditVM {
CompanyGatewayEditVM({
@required this.state,
@required this.companyGateway,
@required this.company,
@required this.onChanged,
@required this.isSaving,
@required this.origCompanyGateway,
@required this.onSavePressed,
@required this.onCancelPressed,
@required this.onBackPressed,
@required this.isLoading,
});
factory CompanyGatewayEditVM.fromStore(Store<AppState> store) {
final companyGateway = store.state.companyGatewayUIState.editing;
final state = store.state;
return CompanyGatewayEditVM(
state: state,
isLoading: state.isLoading,
isSaving: state.isSaving,
origCompanyGateway: state.companyGatewayState.map[companyGateway.id],
companyGateway: companyGateway,
company: state.selectedCompany,
onChanged: (CompanyGatewayEntity companyGateway) {
store.dispatch(UpdateCompanyGateway(companyGateway));
},
onBackPressed: () {
if (state.uiState.currentRoute.contains(CompanyGatewayScreen.route)) {
store.dispatch(UpdateCurrentRoute(companyGateway.isNew ? CompanyGatewayScreen.route : CompanyGatewayViewScreen.route));
}
},
onCancelPressed: (BuildContext context) {
store.dispatch(EditCompanyGateway(
companyGateway: CompanyGatewayEntity(), context: context, force: true));
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
},
onSavePressed: (BuildContext context) {
final Completer<CompanyGatewayEntity> completer = new Completer<CompanyGatewayEntity>();
store.dispatch(SaveCompanyGatewayRequest(completer: completer, companyGateway: companyGateway));
return completer.future.then((savedCompanyGateway) {
store.dispatch(UpdateCurrentRoute(CompanyGatewayViewScreen.route));
if (isMobile(context)) {
if (companyGateway.isNew) {
Navigator.of(context).pushReplacementNamed(CompanyGatewayViewScreen.route);
} else {
Navigator.of(context).pop(savedCompanyGateway);
}
}
}).catchError((Object error) {
showDialog<ErrorDialog>(
context: context,
builder: (BuildContext context) {
return ErrorDialog(error);
});
});
},
);
}
final CompanyGatewayEntity companyGateway;
final CompanyEntity company;
final Function(CompanyGatewayEntity) onChanged;
final Function(BuildContext) onSavePressed;
final Function(BuildContext) onCancelPressed;
final Function onBackPressed;
final bool isLoading;
final bool isSaving;
final CompanyGatewayEntity origCompanyGateway;
final AppState state;
}

View File

@ -0,0 +1,54 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/edit_icon_button.dart';
import 'package:invoiceninja_flutter/ui/app/actions_menu_button.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/view/company_gateway_view_vm.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_state_title.dart';
class CompanyGatewayView extends StatefulWidget {
const CompanyGatewayView({
Key key,
@required this.viewModel,
}) : super(key: key);
final CompanyGatewayViewVM viewModel;
@override
_CompanyGatewayViewState createState() => new _CompanyGatewayViewState();
}
class _CompanyGatewayViewState extends State<CompanyGatewayView> {
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final userCompany = viewModel.state.userCompany;
final companyGateway = viewModel.companyGateway;
return Scaffold(
appBar: AppBar(
title: EntityStateTitle(entity: companyGateway),
actions: [
userCompany.canEditEntity(companyGateway)
? EditIconButton(
isVisible: !companyGateway.isDeleted,
onPressed: () => viewModel.onEditPressed(context),
)
: Container(),
ActionMenuButton(
entityActions: companyGateway.getActions(userCompany: userCompany),
isSaving: viewModel.isSaving,
entity: companyGateway,
onSelected: viewModel.onEntityAction,
)
],
),
body: FormCard(
children: [
// STARTER: widgets - do not remove comment
]
),
);
}
}

View File

@ -0,0 +1,102 @@
import 'dart:async';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/company_gateway_screen.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart';
import 'package:invoiceninja_flutter/data/models/company_gateway_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/company_gateway/view/company_gateway_view.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class CompanyGatewayViewScreen extends StatelessWidget {
const CompanyGatewayViewScreen({Key key}) : super(key: key);
static const String route = '/company_gateway/view';
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, CompanyGatewayViewVM>(
converter: (Store<AppState> store) {
return CompanyGatewayViewVM.fromStore(store);
},
builder: (context, vm) {
return CompanyGatewayView(
viewModel: vm,
);
},
);
}
}
class CompanyGatewayViewVM {
CompanyGatewayViewVM({
@required this.state,
@required this.companyGateway,
@required this.company,
@required this.onEntityAction,
@required this.onEditPressed,
@required this.onBackPressed,
@required this.onRefreshed,
@required this.isSaving,
@required this.isLoading,
@required this.isDirty,
});
factory CompanyGatewayViewVM.fromStore(Store<AppState> store) {
final state = store.state;
final companyGateway = state.companyGatewayState.map[state.companyGatewayUIState.selectedId] ??
CompanyGatewayEntity(id: state.companyGatewayUIState.selectedId);
Future<Null> _handleRefresh(BuildContext context) {
final completer = snackBarCompleter(
context, AppLocalization.of(context).refreshComplete);
store.dispatch(LoadCompanyGateway(completer: completer, companyGatewayId: companyGateway.id));
return completer.future;
}
return CompanyGatewayViewVM(
state: state,
company: state.selectedCompany,
isSaving: state.isSaving,
isLoading: state.isLoading,
isDirty: companyGateway.isNew,
companyGateway: companyGateway,
onEditPressed: (BuildContext context) {
final Completer<CompanyGatewayEntity> completer = Completer<CompanyGatewayEntity>();
store.dispatch(EditCompanyGateway(
companyGateway: companyGateway, context: context, completer: completer));
completer.future.then((companyGateway) {
Scaffold.of(context).showSnackBar(SnackBar(
content: SnackBarRow(
message: AppLocalization.of(context).updatedCompanyGateway,
)));
});
},
onRefreshed: (context) => _handleRefresh(context),
onBackPressed: () {
if (state.uiState.currentRoute.contains(CompanyGatewayScreen.route)) {
store.dispatch(UpdateCurrentRoute(CompanyGatewayScreen.route));
}
},
onEntityAction: (BuildContext context, EntityAction action) =>
handleCompanyGatewayAction(context, companyGateway, action),
);
}
final AppState state;
final CompanyGatewayEntity companyGateway;
final CompanyEntity company;
final Function(BuildContext, EntityAction) onEntityAction;
final Function(BuildContext) onEditPressed;
final Function onBackPressed;
final Function(BuildContext) onRefreshed;
final bool isSaving;
final bool isLoading;
final bool isDirty;
}