Projects
This commit is contained in:
parent
2691d706a1
commit
f11c48b7ec
|
|
@ -70,3 +70,40 @@ List<int> filteredProjectsSelector(
|
|||
|
||||
return list;
|
||||
}
|
||||
|
||||
var memoizedProjectStatsForClient = memo4((int clientId,
|
||||
BuiltMap<int, ProjectEntity> projectMap,
|
||||
String activeLabel,
|
||||
String archivedLabel) =>
|
||||
projectStatsForClient(clientId, projectMap, activeLabel, archivedLabel));
|
||||
|
||||
String projectStatsForClient(
|
||||
int clientId,
|
||||
BuiltMap<int, ProjectEntity> projectMap,
|
||||
String activeLabel,
|
||||
String archivedLabel) {
|
||||
int countActive = 0;
|
||||
int countArchived = 0;
|
||||
projectMap.forEach((projectId, project) {
|
||||
if (project.clientId == clientId) {
|
||||
if (project.isActive) {
|
||||
countActive++;
|
||||
} else if (project.isArchived) {
|
||||
countArchived++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
String str = '';
|
||||
if (countActive > 0) {
|
||||
str = '$countActive $activeLabel';
|
||||
if (countArchived > 0) {
|
||||
str += ' • ';
|
||||
}
|
||||
}
|
||||
if (countArchived > 0) {
|
||||
str += '$countArchived $archivedLabel';
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart';
|
|||
import 'package:invoiceninja_flutter/redux/product/product_actions.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/app_drawer_vm.dart';
|
||||
import 'package:invoiceninja_flutter/ui/settings/settings_screen.dart';
|
||||
import 'package:invoiceninja_flutter/utils/icons.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||
|
|
@ -152,7 +153,7 @@ class AppDrawer extends StatelessWidget {
|
|||
DrawerTile(
|
||||
company: company,
|
||||
entityType: EntityType.client,
|
||||
icon: FontAwesomeIcons.users,
|
||||
icon: getEntityIcon(EntityType.client),
|
||||
title: localization.clients,
|
||||
onTap: () => store.dispatch(ViewClientList(context)),
|
||||
onCreateTap: () {
|
||||
|
|
@ -164,7 +165,7 @@ class AppDrawer extends StatelessWidget {
|
|||
DrawerTile(
|
||||
company: company,
|
||||
entityType: EntityType.product,
|
||||
icon: FontAwesomeIcons.cube,
|
||||
icon: getEntityIcon(EntityType.product),
|
||||
title: localization.products,
|
||||
onTap: () {
|
||||
store.dispatch(ViewProductList(context));
|
||||
|
|
@ -178,7 +179,7 @@ class AppDrawer extends StatelessWidget {
|
|||
DrawerTile(
|
||||
company: company,
|
||||
entityType: EntityType.invoice,
|
||||
icon: FontAwesomeIcons.filePdf,
|
||||
icon: getEntityIcon(EntityType.invoice),
|
||||
title: localization.invoices,
|
||||
onTap: () => store.dispatch(ViewInvoiceList(context)),
|
||||
onCreateTap: () {
|
||||
|
|
@ -190,7 +191,7 @@ class AppDrawer extends StatelessWidget {
|
|||
DrawerTile(
|
||||
company: company,
|
||||
entityType: EntityType.payment,
|
||||
icon: FontAwesomeIcons.creditCard,
|
||||
icon: getEntityIcon(EntityType.payment),
|
||||
title: localization.payments,
|
||||
onTap: () => store.dispatch(ViewPaymentList(context)),
|
||||
onCreateTap: () {
|
||||
|
|
@ -202,7 +203,7 @@ class AppDrawer extends StatelessWidget {
|
|||
DrawerTile(
|
||||
company: company,
|
||||
entityType: EntityType.quote,
|
||||
icon: FontAwesomeIcons.fileAlt,
|
||||
icon: getEntityIcon(EntityType.quote),
|
||||
title: localization.quotes,
|
||||
onTap: () => store.dispatch(ViewQuoteList(context)),
|
||||
onCreateTap: () {
|
||||
|
|
@ -215,7 +216,7 @@ class AppDrawer extends StatelessWidget {
|
|||
DrawerTile(
|
||||
company: company,
|
||||
entityType: EntityType.project,
|
||||
icon: FontAwesomeIcons.briefcase,
|
||||
icon: getEntityIcon(EntityType.project),
|
||||
title: localization.projects,
|
||||
onTap: () => store.dispatch(ViewProjectList(context)),
|
||||
onCreateTap: () {
|
||||
|
|
|
|||
|
|
@ -3,15 +3,16 @@ import 'package:invoiceninja_flutter/data/models/client_model.dart';
|
|||
import 'package:invoiceninja_flutter/data/models/entities.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
import 'package:invoiceninja_flutter/redux/invoice/invoice_selectors.dart';
|
||||
import 'package:invoiceninja_flutter/redux/project/project_selectors.dart';
|
||||
import 'package:invoiceninja_flutter/redux/payment/payment_selectors.dart';
|
||||
import 'package:invoiceninja_flutter/redux/quote/quote_selectors.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/FieldGrid.dart';
|
||||
import 'package:invoiceninja_flutter/ui/client/view/client_view_vm.dart';
|
||||
import 'package:invoiceninja_flutter/utils/formatting.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/icon_message.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/two_value_header.dart';
|
||||
import 'package:invoiceninja_flutter/utils/icons.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
|
||||
class ClientOverview extends StatelessWidget {
|
||||
|
|
@ -67,7 +68,7 @@ class ClientOverview extends StatelessWidget {
|
|||
height: 1.0,
|
||||
),
|
||||
EntityListTile(
|
||||
icon: FontAwesomeIcons.filePdf,
|
||||
icon: getEntityIcon(EntityType.invoice),
|
||||
title: localization.invoices,
|
||||
onTap: () => viewModel.onEntityPressed(context, EntityType.invoice),
|
||||
subtitle: memoizedInvoiceStatsForClient(
|
||||
|
|
@ -77,7 +78,7 @@ class ClientOverview extends StatelessWidget {
|
|||
localization.archived),
|
||||
),
|
||||
EntityListTile(
|
||||
icon: FontAwesomeIcons.creditCard,
|
||||
icon: getEntityIcon(EntityType.payment),
|
||||
title: localization.payments,
|
||||
onTap: () => viewModel.onEntityPressed(context, EntityType.payment),
|
||||
subtitle: memoizedPaymentStatsForClient(
|
||||
|
|
@ -87,16 +88,32 @@ class ClientOverview extends StatelessWidget {
|
|||
localization.active,
|
||||
localization.archived),
|
||||
),
|
||||
company.isModuleEnabled(EntityType.quote) ? EntityListTile(
|
||||
icon: FontAwesomeIcons.fileAlt,
|
||||
title: localization.quotes,
|
||||
onTap: () => viewModel.onEntityPressed(context, EntityType.quote),
|
||||
subtitle: memoizedQuoteStatsForClient(
|
||||
client.id,
|
||||
state.quoteState.map,
|
||||
localization.active,
|
||||
localization.archived),
|
||||
) : Container(),
|
||||
company.isModuleEnabled(EntityType.quote)
|
||||
? EntityListTile(
|
||||
icon: getEntityIcon(EntityType.quote),
|
||||
title: localization.quotes,
|
||||
onTap: () =>
|
||||
viewModel.onEntityPressed(context, EntityType.quote),
|
||||
subtitle: memoizedQuoteStatsForClient(
|
||||
client.id,
|
||||
state.quoteState.map,
|
||||
localization.active,
|
||||
localization.archived),
|
||||
)
|
||||
: Container(),
|
||||
company.isModuleEnabled(EntityType.project)
|
||||
? EntityListTile(
|
||||
icon: getEntityIcon(EntityType.project),
|
||||
title: localization.projects,
|
||||
onTap: () =>
|
||||
viewModel.onEntityPressed(context, EntityType.project),
|
||||
subtitle: memoizedProjectStatsForClient(
|
||||
client.id,
|
||||
state.projectState.map,
|
||||
localization.active,
|
||||
localization.archived),
|
||||
)
|
||||
: Container(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ IconData getEntityIcon(EntityType entityType) {
|
|||
switch (entityType) {
|
||||
case EntityType.product:
|
||||
return FontAwesomeIcons.cube;
|
||||
case EntityType.project:
|
||||
return FontAwesomeIcons.cube;
|
||||
case EntityType.client:
|
||||
return FontAwesomeIcons.users;
|
||||
case EntityType.invoice:
|
||||
|
|
|
|||
Loading…
Reference in New Issue