This commit is contained in:
unknown 2018-07-30 12:25:04 +03:00
parent 5f4552dbae
commit 74e763224c
9 changed files with 146 additions and 26 deletions

View File

@ -18,10 +18,16 @@ class ViewClient implements PersistUI {
class EditClient implements PersistUI {
final ClientEntity client;
final ContactEntity contact;
final BuildContext context;
final Completer completer;
final bool trackRoute;
EditClient({this.client, this.context, this.completer, this.trackRoute = true});
EditClient({this.client, this.contact, this.context, this.completer, this.trackRoute = true});
}
class EditContact implements PersistUI {
final ContactEntity contact;
EditContact([this.contact]);
}
class UpdateClient implements PersistUI {

View File

@ -10,10 +10,20 @@ EntityUIState clientUIReducer(ClientUIState state, dynamic action) {
return state.rebuild((b) => b
..listUIState.replace(clientListReducer(state.listUIState, action))
..editing.replace(editingReducer(state.editing, action))
..editingContact.replace(editingContactReducer(state.editingContact, action))
..selectedId = selectedIdReducer(state.selectedId, action)
);
}
final editingContactReducer = combineReducers<ContactEntity>([
TypedReducer<ContactEntity, EditClient>(editContact),
TypedReducer<ContactEntity, EditContact>(editContact),
]);
ContactEntity editContact(ContactEntity contact, dynamic action) {
return action.contact ?? ContactEntity();
}
Reducer<int> selectedIdReducer = combineReducers([
TypedReducer<int, ViewClient>((int selectedId, dynamic action) => action.clientId),
TypedReducer<int, AddClientSuccess>((int selectedId, dynamic action) => action.client.id),

View File

@ -45,6 +45,7 @@ abstract class ClientUIState extends Object with EntityUIState implements Built<
return _$ClientUIState._(
listUIState: ListUIState(ClientFields.name),
editing: ClientEntity(),
editingContact: ContactEntity(),
selectedId: 0,
);
}
@ -53,6 +54,9 @@ abstract class ClientUIState extends Object with EntityUIState implements Built<
@nullable
ClientEntity get editing;
@nullable
ContactEntity get editingContact;
@override
bool get isCreatingNew => editing.isNew;

View File

@ -105,6 +105,12 @@ class _$ClientUIStateSerializer implements StructuredSerializer<ClientUIState> {
..add(serializers.serialize(object.editing,
specifiedType: const FullType(ClientEntity)));
}
if (object.editingContact != null) {
result
..add('editingContact')
..add(serializers.serialize(object.editingContact,
specifiedType: const FullType(ContactEntity)));
}
return result;
}
@ -124,6 +130,10 @@ class _$ClientUIStateSerializer implements StructuredSerializer<ClientUIState> {
result.editing.replace(serializers.deserialize(value,
specifiedType: const FullType(ClientEntity)) as ClientEntity);
break;
case 'editingContact':
result.editingContact.replace(serializers.deserialize(value,
specifiedType: const FullType(ContactEntity)) as ContactEntity);
break;
case 'selectedId':
result.selectedId = serializers.deserialize(value,
specifiedType: const FullType(int)) as int;
@ -255,6 +265,8 @@ class _$ClientUIState extends ClientUIState {
@override
final ClientEntity editing;
@override
final ContactEntity editingContact;
@override
final int selectedId;
@override
final ListUIState listUIState;
@ -262,7 +274,8 @@ class _$ClientUIState extends ClientUIState {
factory _$ClientUIState([void updates(ClientUIStateBuilder b)]) =>
(new ClientUIStateBuilder()..update(updates)).build();
_$ClientUIState._({this.editing, this.selectedId, this.listUIState})
_$ClientUIState._(
{this.editing, this.editingContact, this.selectedId, this.listUIState})
: super._() {
if (selectedId == null)
throw new BuiltValueNullFieldError('ClientUIState', 'selectedId');
@ -282,13 +295,16 @@ class _$ClientUIState extends ClientUIState {
if (identical(other, this)) return true;
if (other is! ClientUIState) return false;
return editing == other.editing &&
editingContact == other.editingContact &&
selectedId == other.selectedId &&
listUIState == other.listUIState;
}
@override
int get hashCode {
return $jf($jc($jc($jc(0, editing.hashCode), selectedId.hashCode),
return $jf($jc(
$jc($jc($jc(0, editing.hashCode), editingContact.hashCode),
selectedId.hashCode),
listUIState.hashCode));
}
@ -296,6 +312,7 @@ class _$ClientUIState extends ClientUIState {
String toString() {
return (newBuiltValueToStringHelper('ClientUIState')
..add('editing', editing)
..add('editingContact', editingContact)
..add('selectedId', selectedId)
..add('listUIState', listUIState))
.toString();
@ -311,6 +328,12 @@ class ClientUIStateBuilder
_$this._editing ??= new ClientEntityBuilder();
set editing(ClientEntityBuilder editing) => _$this._editing = editing;
ContactEntityBuilder _editingContact;
ContactEntityBuilder get editingContact =>
_$this._editingContact ??= new ContactEntityBuilder();
set editingContact(ContactEntityBuilder editingContact) =>
_$this._editingContact = editingContact;
int _selectedId;
int get selectedId => _$this._selectedId;
set selectedId(int selectedId) => _$this._selectedId = selectedId;
@ -326,6 +349,7 @@ class ClientUIStateBuilder
ClientUIStateBuilder get _$this {
if (_$v != null) {
_editing = _$v.editing?.toBuilder();
_editingContact = _$v.editingContact?.toBuilder();
_selectedId = _$v.selectedId;
_listUIState = _$v.listUIState?.toBuilder();
_$v = null;
@ -351,6 +375,7 @@ class ClientUIStateBuilder
_$result = _$v ??
new _$ClientUIState._(
editing: _editing?.build(),
editingContact: _editingContact?.build(),
selectedId: selectedId,
listUIState: listUIState.build());
} catch (_) {
@ -358,6 +383,8 @@ class ClientUIStateBuilder
try {
_$failedField = 'editing';
_editing?.build();
_$failedField = 'editingContact';
_editingContact?.build();
_$failedField = 'listUIState';
listUIState.build();

View File

@ -1,13 +1,13 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_billing_address.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_contacts_vm.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_details.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_settings.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_shipping_address.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/save_icon_button.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_contacts.dart';
class ClientEdit extends StatefulWidget {
final ClientEditVM viewModel;
@ -97,9 +97,7 @@ class _ClientEditState extends State<ClientEdit>
ClientEditDetails(
viewModel: widget.viewModel,
),
ClientEditContacts(
viewModel: widget.viewModel,
),
ClientEditContactsScreen(),
ClientEditSettings(
viewModel: widget.viewModel,
),

View File

@ -4,21 +4,30 @@ import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/forms/custom_field.dart';
import 'package:invoiceninja_flutter/ui/app/icon_text.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_contacts_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart';
class ClientEditContacts extends StatelessWidget {
class ClientEditContacts extends StatefulWidget {
const ClientEditContacts({
Key key,
@required this.viewModel,
}) : super(key: key);
final ClientEditVM viewModel;
final ClientEditContactsVM viewModel;
@override
_ClientEditContactsState createState() => new _ClientEditContactsState();
}
class _ClientEditContactsState extends State<ClientEditContacts> {
ContactEntity selectedContact;
void _showContactEditor(ContactEntity contact, BuildContext context) {
showDialog<ContactEditDetails>(
context: context,
builder: (BuildContext context) {
final viewModel = widget.viewModel;
final client = viewModel.client;
return ContactEditDetails(
@ -34,13 +43,26 @@ class ClientEditContacts extends StatelessWidget {
@override
Widget build(BuildContext context) {
final localization = AppLocalization.of(context);
final viewModel = widget.viewModel;
final client = viewModel.client;
final contacts = client.contacts.map((contact) => ContactListTile(
contact: contact,
onTap: () => _showContactEditor(contact, context),
));
/*
final contact = client.contacts.contains(viewModel.contact)
? viewModel.contact
: null;
if (contact != null && contact != selectedContact) {
selectedContact = contact;
WidgetsBinding.instance.addPostFrameCallback((duration) {
_showContactEditor(contact, context);
});
}
*/
return ListView(
children: []
..addAll(contacts)
@ -100,7 +122,7 @@ class ContactEditDetails extends StatefulWidget {
final int index;
final ContactEntity contact;
final ClientEditVM viewModel;
final ClientEditContactsVM viewModel;
final bool isRemoveVisible;
@override

View File

@ -0,0 +1,64 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/ui/client/edit/client_edit_contacts.dart';
import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/redux/client/client_actions.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class ClientEditContactsScreen extends StatelessWidget {
const ClientEditContactsScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, ClientEditContactsVM>(
converter: (Store<AppState> store) {
return ClientEditContactsVM.fromStore(store);
},
builder: (context, vm) {
return ClientEditContacts(
viewModel: vm,
);
},
);
}
}
class ClientEditContactsVM {
final CompanyEntity company;
final ClientEntity client;
final ContactEntity contact;
final Function() onAddContactPressed;
final Function(int) onRemoveContactPressed;
final Function onDoneContactPressed;
final Function(ContactEntity, int) onChangedContact;
ClientEditContactsVM({
@required this.company,
@required this.client,
@required this.contact,
@required this.onAddContactPressed,
@required this.onRemoveContactPressed,
@required this.onDoneContactPressed,
@required this.onChangedContact,
});
factory ClientEditContactsVM.fromStore(Store<AppState> store) {
final AppState state = store.state;
final client = state.clientUIState.editing;
return ClientEditContactsVM(
company: state.selectedCompany,
client: client,
contact: state.clientUIState.editingContact,
onAddContactPressed: () => store.dispatch(AddContact()),
onRemoveContactPressed: (index) =>
store.dispatch(DeleteContact(index)),
onDoneContactPressed: () => store.dispatch(EditContact()),
onChangedContact: (contact, index) {
store.dispatch(
UpdateContact(contact: contact, index: index));
});
}
}

View File

@ -40,9 +40,6 @@ class ClientEditVM {
final ClientEntity client;
final ClientEntity origClient;
final Function(ClientEntity) onChanged;
final Function() onAddContactPressed;
final Function(int) onRemoveContactPressed;
final Function(ContactEntity, int) onChangedContact;
final Function(BuildContext) onSavePressed;
final Function onBackPressed;
final BuiltMap<int, CountryEntity> countryMap;
@ -54,9 +51,6 @@ class ClientEditVM {
@required this.isSaving,
@required this.client,
@required this.origClient,
@required this.onAddContactPressed,
@required this.onRemoveContactPressed,
@required this.onChangedContact,
@required this.onChanged,
@required this.onSavePressed,
@required this.onBackPressed,
@ -79,11 +73,6 @@ class ClientEditVM {
isSaving: state.isSaving,
onBackPressed: () =>
store.dispatch(UpdateCurrentRoute(ClientScreen.route)),
onAddContactPressed: () => store.dispatch(AddContact()),
onRemoveContactPressed: (index) => store.dispatch(DeleteContact(index)),
onChangedContact: (contact, index) {
store.dispatch(UpdateContact(contact: contact, index: index));
},
onChanged: (ClientEntity client) =>
store.dispatch(UpdateClient(client)),
onSavePressed: (BuildContext context) {

View File

@ -22,7 +22,7 @@ class InvoiceEditItems extends StatefulWidget {
}
class _InvoiceEditItemsState extends State<InvoiceEditItems> {
InvoiceItemEntity dialogInvoiceItem;
InvoiceItemEntity selectedInvoiceItem;
void _showInvoiceItemEditor(
InvoiceItemEntity invoiceItem, BuildContext context) {
@ -47,8 +47,8 @@ class _InvoiceEditItemsState extends State<InvoiceEditItems> {
? viewModel.invoiceItem
: null;
if (invoiceItem != null && invoiceItem != dialogInvoiceItem) {
dialogInvoiceItem = invoiceItem;
if (invoiceItem != null && invoiceItem != selectedInvoiceItem) {
selectedInvoiceItem = invoiceItem;
WidgetsBinding.instance.addPostFrameCallback((duration) {
_showInvoiceItemEditor(invoiceItem, context);
});