Company selector

This commit is contained in:
unknown 2018-05-23 11:55:14 -07:00
parent b875d6e93b
commit 1ae335997e
13 changed files with 132 additions and 76 deletions

View File

@ -49,6 +49,8 @@ class CompanyEntity extends Object with _$CompanyEntitySerializerMixin {
CompanyEntity(this.id); CompanyEntity(this.id);
factory CompanyEntity.fromJson(Map<String, dynamic> json) => _$CompanyEntityFromJson(json); factory CompanyEntity.fromJson(Map<String, dynamic> json) => _$CompanyEntityFromJson(json);
bool isBlank() => this.token == null;
} }

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:core'; import 'dart:core';
import 'dart:convert';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:invoiceninja/redux/auth/auth_state.dart'; import 'package:invoiceninja/redux/auth/auth_state.dart';
@ -20,7 +21,7 @@ class AuthRepositoryFlutter {
/// Loads products first from File storage. If they don't exist or encounter an /// Loads products first from File storage. If they don't exist or encounter an
/// error, it attempts to load the Products from a Web Client. /// error, it attempts to load the Products from a Web Client.
Future<List<dynamic>> login(String email, String password, String url) async { Future<List<CompanyEntity>> login(String email, String password, String url) async {
final data = await webClient.postList(url + '/login', '', { final data = await webClient.postList(url + '/login', '', {
'api_secret': 'secret', 'api_secret': 'secret',

View File

@ -18,7 +18,7 @@ class DashboardRepositoryFlutter {
this.webClient = const WebClient(), this.webClient = const WebClient(),
}); });
Future<dynamic> loadItem(CompanyEntity company, AuthState auth) async { Future<DashboardEntity> loadItem(CompanyEntity company, AuthState auth) async {
final data = await webClient.fetchItem( final data = await webClient.fetchItem(
auth.url + '/dashboard', company.token); auth.url + '/dashboard', company.token);

View File

@ -18,7 +18,7 @@ class ProductsRepositoryFlutter {
this.webClient = const WebClient(), this.webClient = const WebClient(),
}); });
Future<List<dynamic>> loadList(CompanyEntity company, AuthState auth) async { Future<List<ProductEntity>> loadList(CompanyEntity company, AuthState auth) async {
final products = await webClient.fetchList( final products = await webClient.fetchList(
auth.url + '/products', company.token); auth.url + '/products', company.token);

View File

@ -49,7 +49,7 @@ class WebClient {
} }
Future<dynamic> postList(String url, String token, var data) async { Future<List<dynamic>> postList(String url, String token, var data) async {
final http.Response response = await sendPostRequest(url, token, data); final http.Response response = await sendPostRequest(url, token, data);
//print(response.body); //print(response.body);

View File

@ -24,16 +24,16 @@ AppState appReducer(AppState state, action) {
selectedCompanyId: selectedCompanyIdReducer(state.selectedCompanyId, action), selectedCompanyId: selectedCompanyIdReducer(state.selectedCompanyId, action),
isLoading: loadingReducer(state.isLoading, action), isLoading: loadingReducer(state.isLoading, action),
auth: authReducer(state.auth, action), auth: authReducer(state.auth, action),
company1: state.selectedCompanyId == 1 companyState1: state.selectedCompanyId == 1
? companyReducer(state.company1, action) : state.company1, ? companyReducer(state.companyState1, action) : state.companyState1,
company2: state.selectedCompanyId == 2 companyState2: state.selectedCompanyId == 2
? companyReducer(state.company2, action) : state.company2, ? companyReducer(state.companyState2, action) : state.companyState2,
company3: state.selectedCompanyId == 3 companyState3: state.selectedCompanyId == 3
? companyReducer(state.company3, action) : state.company3, ? companyReducer(state.companyState3, action) : state.companyState3,
company4: state.selectedCompanyId == 4 companyState4: state.selectedCompanyId == 4
? companyReducer(state.company4, action) : state.company4, ? companyReducer(state.companyState4, action) : state.companyState4,
company5: state.selectedCompanyId == 5 companyState5: state.selectedCompanyId == 5
? companyReducer(state.company5, action) : state.company5, ? companyReducer(state.companyState5, action) : state.companyState5,
); );
} }

View File

@ -10,27 +10,27 @@ class AppState {
final bool isLoading; final bool isLoading;
final AuthState auth; final AuthState auth;
final int selectedCompanyId; final int selectedCompanyId;
final CompanyState company1; final CompanyState companyState1;
final CompanyState company2; final CompanyState companyState2;
final CompanyState company3; final CompanyState companyState3;
final CompanyState company4; final CompanyState companyState4;
final CompanyState company5; final CompanyState companyState5;
AppState( AppState(
{this.isLoading = false, {this.isLoading = false,
this.selectedCompanyId = 0, this.selectedCompanyId = 0,
AuthState auth, AuthState auth,
CompanyState company1, CompanyState companyState1,
CompanyState company2, CompanyState companyState2,
CompanyState company3, CompanyState companyState3,
CompanyState company4, CompanyState companyState4,
CompanyState company5,}) : CompanyState companyState5,}) :
auth = auth ?? AuthState(), auth = auth ?? AuthState(),
company1 = company1 ?? CompanyState(), companyState1 = companyState1 ?? CompanyState(),
company2 = company2 ?? CompanyState(), companyState2 = companyState2 ?? CompanyState(),
company3 = company3 ?? CompanyState(), companyState3 = companyState3 ?? CompanyState(),
company4 = company4 ?? CompanyState(), companyState4 = companyState4 ?? CompanyState(),
company5 = company5 ?? CompanyState(); companyState5 = companyState5 ?? CompanyState();
factory AppState.loading() => AppState(isLoading: true); factory AppState.loading() => AppState(isLoading: true);
@ -47,21 +47,21 @@ class AppState {
String selectedCompany, String selectedCompany,
bool isLoading, bool isLoading,
AuthState auth, AuthState auth,
CompanyState company1, CompanyState companyState1,
CompanyState company2, CompanyState companyState2,
CompanyState company3, CompanyState companyState3,
CompanyState company4, CompanyState companyState4,
CompanyState company5, CompanyState companyState5,
}) { }) {
return AppState( return AppState(
selectedCompanyId : selectedCompany ?? this.selectedCompanyId, selectedCompanyId : selectedCompany ?? this.selectedCompanyId,
isLoading: isLoading ?? this.isLoading, isLoading: isLoading ?? this.isLoading,
auth: auth ?? this.auth, auth: auth ?? this.auth,
company1: company1 ?? this.company1, companyState1: companyState1 ?? this.companyState1,
company2: company2 ?? this.company2, companyState2: companyState2 ?? this.companyState2,
company3: company3 ?? this.company3, companyState3: companyState3 ?? this.companyState3,
company4: company4 ?? this.company4, companyState4: companyState4 ?? this.companyState4,
company5: company5 ?? this.company5, companyState5: companyState5 ?? this.companyState5,
); );
} }
@ -70,11 +70,11 @@ class AppState {
selectedCompanyId.hashCode ^ selectedCompanyId.hashCode ^
isLoading.hashCode ^ isLoading.hashCode ^
auth.hashCode ^ auth.hashCode ^
company1.hashCode ^ companyState1.hashCode ^
company2.hashCode ^ companyState2.hashCode ^
company3.hashCode ^ companyState3.hashCode ^
company4.hashCode ^ companyState4.hashCode ^
company5.hashCode; companyState5.hashCode;
@override @override
bool operator == (Object other) => bool operator == (Object other) =>
@ -82,33 +82,33 @@ class AppState {
other is AppState && other is AppState &&
runtimeType == other.runtimeType && runtimeType == other.runtimeType &&
selectedCompanyId == other.selectedCompanyId && selectedCompanyId == other.selectedCompanyId &&
company1 == other.company1 && companyState1 == other.companyState1 &&
company2 == other.company2 && companyState2 == other.companyState2 &&
company3 == other.company3 && companyState3 == other.companyState3 &&
company4 == other.company4 && companyState4 == other.companyState4 &&
company5 == other.company5 && companyState5 == other.companyState5 &&
auth == other.auth; auth == other.auth;
@override @override
String toString() { String toString() {
return 'AppState{isLoading: $isLoading, url: ${auth.url}, companyId: ${selectedCompanyId}, company1: ${company1.company.name}, company2: ${company2.company.name}'; return 'AppState{isLoading: $isLoading, url: ${auth.url}, companyId: ${selectedCompanyId}, company1: ${companyState1.company.name}, company2: ${companyState2.company.name}';
} }
CompanyState selectedCompanyState() { CompanyState selectedCompanyState() {
switch (this.selectedCompanyId) { switch (this.selectedCompanyId) {
case 1: case 1:
return this.company1; return this.companyState1;
case 2: case 2:
return this.company2; return this.companyState2;
case 3: case 3:
return this.company3; return this.companyState3;
case 4: case 4:
return this.company4; return this.companyState4;
case 5: case 5:
return this.company5; return this.companyState5;
} }
return this.company1; return this.companyState1;
} }
CompanyEntity selectedCompany() { CompanyEntity selectedCompany() {

View File

@ -50,7 +50,6 @@ Middleware<AppState> _createLoginRequest(AuthRepositoryFlutter repository) {
store.dispatch(SelectCompany(1)); store.dispatch(SelectCompany(1));
store.dispatch(UserLoginSuccess()); store.dispatch(UserLoginSuccess());
//store.dispatch(LoadDashboardAction());
Navigator.of(action.context).pushNamed(AppRoutes.dashboard); Navigator.of(action.context).pushNamed(AppRoutes.dashboard);
} }
@ -59,14 +58,3 @@ Middleware<AppState> _createLoginRequest(AuthRepositoryFlutter repository) {
next(action); next(action);
}; };
} }
/*
Middleware<AppState> _createLoginSuccess() {
return (Store<AppState> store, action, NextDispatcher next) {
next(action);
};
}
*/

View File

@ -0,0 +1,24 @@
import 'package:invoiceninja/data/models/models.dart';
import 'package:invoiceninja/redux/app/app_state.dart';
List<CompanyEntity> companiesSelector(AppState state) {
List<CompanyEntity> list = [];
if (! state.companyState1.company.isBlank()) {
list.add(state.companyState1.company);
}
if (! state.companyState2.company.isBlank()) {
list.add(state.companyState2.company);
}
if (! state.companyState3.company.isBlank()) {
list.add(state.companyState3.company);
}
if (! state.companyState4.company.isBlank()) {
list.add(state.companyState4.company);
}
if (! state.companyState5.company.isBlank()) {
list.add(state.companyState5.company);
}
return list;
}

View File

@ -5,7 +5,7 @@ import 'package:invoiceninja/data/models/entities.dart';
@immutable @immutable
class CompanyState { class CompanyState {
CompanyEntity company; final CompanyEntity company;
final ProductState productState; final ProductState productState;
final DashboardState dashboardState; final DashboardState dashboardState;

View File

@ -1,16 +1,50 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja/routes.dart'; import 'package:invoiceninja/routes.dart';
import 'package:invoiceninja/data/models/entities.dart';
class CustomDrawer extends StatelessWidget { class CustomDrawer extends StatelessWidget {
final String companyName; final String companyName;
final bool hasMultipleCompanies;
final List<CompanyEntity> companies;
CustomDrawer({ CustomDrawer({
Key key, Key key,
@required this.companyName, @required this.companyName,
@required this.hasMultipleCompanies,
@required this.companies,
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _singleCompany = Align(
alignment: FractionalOffset.bottomLeft,
child: Text(companyName),
);
final _multipleCompanies = Align(
alignment: FractionalOffset.bottomLeft,
child: new DropdownButton<String>(
items: this.companies.map((CompanyEntity company) =>
DropdownMenuItem<String>(
value: company.id.toString(),
child: Text(company.id.toString()),
)
).toList(),
onChanged: (_) {
},
),
/*
child: DropdownButton(
items: this.companies.map((CompanyEntity company) {
return DropdownMenuItem(
child: Text(company.name),
);
}),
),
*/
);
return Drawer( return Drawer(
child: ListView( child: ListView(
children: <Widget>[ children: <Widget>[
@ -23,7 +57,7 @@ class CustomDrawer extends StatelessWidget {
child: Text('Logo'), child: Text('Logo'),
), ),
), ),
Text(this.companyName), this.companies.length > 1 ? _multipleCompanies : _singleCompany,
], ],
)), )),
color: Colors.white10, color: Colors.white10,

View File

@ -2,11 +2,10 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja/redux/dashboard/dashboard_actions.dart';
import 'package:invoiceninja/data/models/models.dart';
import 'package:invoiceninja/ui/app/custom_drawer.dart'; import 'package:invoiceninja/ui/app/custom_drawer.dart';
import 'package:invoiceninja/redux/app/app_state.dart'; import 'package:invoiceninja/redux/app/app_state.dart';
import 'package:invoiceninja/redux/dashboard/dashboard_state.dart'; import 'package:invoiceninja/redux/company/company_selectors.dart';
import 'package:invoiceninja/data/models/models.dart';
class CustomDrawerVM extends StatelessWidget { class CustomDrawerVM extends StatelessWidget {
CustomDrawerVM({Key key}) : super(key: key); CustomDrawerVM({Key key}) : super(key: key);
@ -18,6 +17,8 @@ class CustomDrawerVM extends StatelessWidget {
builder: (context, vm) { builder: (context, vm) {
return CustomDrawer( return CustomDrawer(
companyName: vm.companyName, companyName: vm.companyName,
hasMultipleCompanies: vm.hasMultipleCompanies,
companies: vm.companies,
); );
}, },
); );
@ -26,14 +27,20 @@ class CustomDrawerVM extends StatelessWidget {
class _ViewModel { class _ViewModel {
final String companyName; final String companyName;
final bool hasMultipleCompanies;
final List<CompanyEntity> companies;
_ViewModel({ _ViewModel({
@required this.companyName, @required this.companyName,
}); @required this.hasMultipleCompanies,
@required this.companies,
});
static _ViewModel fromStore(Store<AppState> store) { static _ViewModel fromStore(Store<AppState> store) {
return _ViewModel( return _ViewModel(
companyName: store.state.selectedCompany().name, companyName: store.state.selectedCompany().name,
hasMultipleCompanies: store.state.companyState2.company.token != null,
companies: companiesSelector(store.state),
); );
} }
} }

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja/keys.dart'; import 'package:invoiceninja/keys.dart';
import 'package:invoiceninja/ui/app/custom_drawer.dart'; import 'package:invoiceninja/ui/app/custom_drawer_vm.dart';
class ClientList extends StatelessWidget { class ClientList extends StatelessWidget {
ClientList() : super(key: NinjaKeys.clientList); ClientList() : super(key: NinjaKeys.clientList);
@ -11,7 +11,7 @@ class ClientList extends StatelessWidget {
appBar: new AppBar( appBar: new AppBar(
title: new Text('Clients'), title: new Text('Clients'),
), ),
drawer: new CustomDrawer(), drawer: new CustomDrawerVM(),
body: new Center( body: new Center(
child: new Column( child: new Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,