From 2bd9513050f8138734890afb63ec511352fd7d58 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 20 Feb 2020 22:22:49 +0200 Subject: [PATCH] History fixes --- lib/data/models/entities.dart | 4 ++ lib/data/models/entities.g.dart | 12 ++++ lib/redux/app/app_state.dart | 3 +- lib/redux/ui/pref_reducer.dart | 13 ++++- lib/redux/ui/pref_state.dart | 2 +- lib/redux/ui/ui_reducer.dart | 9 --- lib/ui/app/history_drawer.dart | 100 ++++++++++++++++++++------------ lib/ui/app/menu_drawer.dart | 12 ++-- lib/utils/icons.dart | 6 ++ 9 files changed, 105 insertions(+), 56 deletions(-) diff --git a/lib/data/models/entities.dart b/lib/data/models/entities.dart index 7300f6532..9f8e51732 100644 --- a/lib/data/models/entities.dart +++ b/lib/data/models/entities.dart @@ -13,6 +13,10 @@ class EntityType extends EnumClass { static Serializer get serializer => _$entityTypeSerializer; + static const EntityType dashboard = _$dashboard; + static const EntityType reports = _$reports; + static const EntityType settings = _$settings; + static const EntityType taxRate = _$taxRate; static const EntityType companyGateway = _$companyGateway; static const EntityType invoice = _$invoice; diff --git a/lib/data/models/entities.g.dart b/lib/data/models/entities.g.dart index 9a6bc4595..a30726c3d 100644 --- a/lib/data/models/entities.g.dart +++ b/lib/data/models/entities.g.dart @@ -6,6 +6,9 @@ part of 'entities.dart'; // BuiltValueGenerator // ************************************************************************** +const EntityType _$dashboard = const EntityType._('dashboard'); +const EntityType _$reports = const EntityType._('reports'); +const EntityType _$settings = const EntityType._('settings'); const EntityType _$taxRate = const EntityType._('taxRate'); const EntityType _$companyGateway = const EntityType._('companyGateway'); const EntityType _$invoice = const EntityType._('invoice'); @@ -43,6 +46,12 @@ const EntityType _$font = const EntityType._('font'); EntityType _$typeValueOf(String name) { switch (name) { + case 'dashboard': + return _$dashboard; + case 'reports': + return _$reports; + case 'settings': + return _$settings; case 'taxRate': return _$taxRate; case 'companyGateway': @@ -118,6 +127,9 @@ EntityType _$typeValueOf(String name) { final BuiltSet _$typeValues = new BuiltSet(const [ + _$dashboard, + _$reports, + _$settings, _$taxRate, _$companyGateway, _$invoice, diff --git a/lib/redux/app/app_state.dart b/lib/redux/app/app_state.dart index 8d3fb6c6a..b0d3ad9a3 100644 --- a/lib/redux/app/app_state.dart +++ b/lib/redux/app/app_state.dart @@ -450,7 +450,8 @@ abstract class AppState implements Built { //return 'History: $historyList'; //return 'Report State: ${uiState.reportsUIState}, Settings: ${userCompany.settings}'; //return 'UserCompany Settngs: ${userCompany.settings}, User Settings: ${user.userCompany.settings}'; - return 'Currency Map: ${staticState.currencyMap}'; + //return 'Currency Map: ${staticState.currencyMap}'; + //return 'History: $historyList'; return 'Layout: ${prefState.appLayout}, Route: ${uiState.currentRoute} Prev: ${uiState.previousRoute}'; } } diff --git a/lib/redux/ui/pref_reducer.dart b/lib/redux/ui/pref_reducer.dart index 4ce04cb5c..7aaf74429 100644 --- a/lib/redux/ui/pref_reducer.dart +++ b/lib/redux/ui/pref_reducer.dart @@ -7,6 +7,7 @@ import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_actions.dart'; import 'package:invoiceninja_flutter/redux/company/company_state.dart'; import 'package:invoiceninja_flutter/redux/company_gateway/company_gateway_actions.dart'; +import 'package:invoiceninja_flutter/redux/dashboard/dashboard_actions.dart'; import 'package:invoiceninja_flutter/redux/expense/expense_actions.dart'; import 'package:invoiceninja_flutter/redux/group/group_actions.dart'; import 'package:invoiceninja_flutter/redux/invoice/invoice_actions.dart'; @@ -14,6 +15,7 @@ import 'package:invoiceninja_flutter/redux/payment/payment_actions.dart'; import 'package:invoiceninja_flutter/redux/product/product_actions.dart'; import 'package:invoiceninja_flutter/redux/project/project_actions.dart'; import 'package:invoiceninja_flutter/redux/quote/quote_actions.dart'; +import 'package:invoiceninja_flutter/redux/reports/reports_actions.dart'; import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart'; import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart' as prefix0; @@ -297,6 +299,15 @@ Reducer> historyReducer = combineReducers([ } }, ), + TypedReducer, ViewDashboard>((historyList, action) => + _addToHistory( + historyList, HistoryRecord(entityType: EntityType.dashboard))), + TypedReducer, ViewReports>((historyList, action) => + _addToHistory( + historyList, HistoryRecord(entityType: EntityType.reports))), + TypedReducer, ViewSettings>((historyList, action) => + _addToHistory( + historyList, HistoryRecord(entityType: EntityType.settings))), TypedReducer, ViewClient>((historyList, action) => _addToHistory(historyList, HistoryRecord(id: action.clientId, entityType: EntityType.client))), @@ -391,7 +402,7 @@ Reducer> historyReducer = combineReducers([ BuiltList _addToHistory( BuiltList list, HistoryRecord record) { // don't track new records - if (record.id == null || record.id.startsWith('-')) { + if (record.id != null && record.id.startsWith('-')) { return list; } diff --git a/lib/redux/ui/pref_state.dart b/lib/redux/ui/pref_state.dart index bfd6e575a..974245dd3 100644 --- a/lib/redux/ui/pref_state.dart +++ b/lib/redux/ui/pref_state.dart @@ -171,8 +171,8 @@ class AppSidebarMode extends EnumClass { abstract class HistoryRecord implements Built { factory HistoryRecord({ - @required String id, @required EntityType entityType, + String id, }) { return _$HistoryRecord._( id: id, diff --git a/lib/redux/ui/ui_reducer.dart b/lib/redux/ui/ui_reducer.dart index aa4649ac0..97d98511b 100644 --- a/lib/redux/ui/ui_reducer.dart +++ b/lib/redux/ui/ui_reducer.dart @@ -1,4 +1,3 @@ -import 'package:built_collection/built_collection.dart'; import 'package:invoiceninja_flutter/data/models/entities.dart'; import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; import 'package:invoiceninja_flutter/redux/client/client_actions.dart'; @@ -14,7 +13,6 @@ import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; import 'package:invoiceninja_flutter/redux/ui/ui_state.dart'; import 'package:invoiceninja_flutter/redux/product/product_reducer.dart'; import 'package:invoiceninja_flutter/redux/invoice/invoice_reducer.dart'; -import 'package:invoiceninja_flutter/ui/app/screen_imports.dart'; import 'package:redux/redux.dart'; import 'package:invoiceninja_flutter/redux/document/document_reducer.dart'; import 'package:invoiceninja_flutter/redux/expense/expense_reducer.dart'; @@ -23,7 +21,6 @@ import 'package:invoiceninja_flutter/redux/project/project_reducer.dart'; 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/user/user_reducer.dart'; import 'package:invoiceninja_flutter/redux/tax_rate/tax_rate_reducer.dart'; @@ -66,12 +63,6 @@ UIState uiReducer(UIState state, dynamic action) { .replace(settingsUIReducer(state.settingsUIState, action))); } -Reducer> routeHistoryReducer = combineReducers([ - TypedReducer, ViewDashboard>((history, action) { - return history.rebuild((b) => b..add(DashboardScreenBuilder.route)); - }), -]); - Reducer filterReducer = combineReducers([ TypedReducer((filter, action) { return action.filter; diff --git a/lib/ui/app/history_drawer.dart b/lib/ui/app/history_drawer.dart index 158b0ada4..b66ee6070 100644 --- a/lib/ui/app/history_drawer.dart +++ b/lib/ui/app/history_drawer.dart @@ -34,11 +34,14 @@ class HistoryDrawer extends StatelessWidget { final widgets = []; for (var history in state.historyList) { - final entity = - state.getEntityMap(history.entityType)[history.id] as BaseEntity; + final entityMap = state.getEntityMap(history.entityType); - if (entity == null || (entity.isDeleted ?? false)) { - continue; + if (entityMap != null) { + final entity = entityMap[history.id] as BaseEntity; + + if (entity?.isDeleted == true) { + continue; + } } widgets.add(HistoryListTile( @@ -104,26 +107,46 @@ class _HistoryListTileState extends State { final state = store.state; final history = widget.history; - final entity = - state.getEntityMap(history.entityType)[history.id] as BaseEntity; + Widget text; String clientId; - switch (history.entityType) { - case EntityType.invoice: - clientId = (entity as InvoiceEntity).clientId; - break; - case EntityType.payment: - clientId = (entity as PaymentEntity).clientId; - break; - case EntityType.task: - clientId = (entity as TaskEntity).clientId; - break; - case EntityType.expense: - clientId = (entity as ExpenseEntity).clientId; - break; - case EntityType.project: - clientId = (entity as ProjectEntity).clientId; - break; + BaseEntity entity; + + if ([ + EntityType.dashboard, + EntityType.reports, + EntityType.settings, + ].contains(history.entityType)) { + text = Text(localization.lookup(history.entityType.toString())); + } else { + entity = state.getEntityMap(history.entityType)[history.id] as BaseEntity; + + if (entity == null) { + return SizedBox(); + } + + switch (history.entityType) { + case EntityType.invoice: + clientId = (entity as InvoiceEntity).clientId; + break; + case EntityType.payment: + clientId = (entity as PaymentEntity).clientId; + break; + case EntityType.task: + clientId = (entity as TaskEntity).clientId; + break; + case EntityType.expense: + clientId = (entity as ExpenseEntity).clientId; + break; + case EntityType.project: + clientId = (entity as ProjectEntity).clientId; + break; + } + + text = Text(entity.listDisplayName.isEmpty + ? formatNumber(entity.listDisplayAmount, context, + formatNumberType: entity.listDisplayAmountType) + : entity.listDisplayName); } return Container( @@ -132,11 +155,10 @@ class _HistoryListTileState extends State { child: ListTile( key: ValueKey('__${history.id}_${history.entityType}__'), leading: Icon(getEntityIcon(history.entityType)), - title: Text(entity.listDisplayName.isEmpty - ? formatNumber(entity.listDisplayAmount, context, - formatNumberType: entity.listDisplayAmountType) - : entity.listDisplayName), - subtitle: Text(localization.lookup('${history.entityType}')), + title: text, + subtitle: history.id == null + ? null + : Text(localization.lookup('${history.entityType}')), // TODO this needs to be localized trailing: LiveText( () => timeago.format(history.dateTime, locale: 'en_short'), @@ -191,17 +213,19 @@ class _HistoryListTileState extends State { entityId: history.id, entityType: history.entityType); }, - onLongPress: () { - showEntityActionsDialog( - context: context, - entities: [entity], - client: state.clientState.map[clientId], - completer: state.prefState.isHistoryFloated - ? (Completer() - ..future.then((value) => Navigator.pop(context))) - : null, - ); - }, + onLongPress: entity == null + ? null + : () { + showEntityActionsDialog( + context: context, + entities: [entity], + client: state.clientState.map[clientId], + completer: state.prefState.isHistoryFloated + ? (Completer() + ..future.then((value) => Navigator.pop(context))) + : null, + ); + }, ), ); } diff --git a/lib/ui/app/menu_drawer.dart b/lib/ui/app/menu_drawer.dart index ab202c637..d90268b27 100644 --- a/lib/ui/app/menu_drawer.dart +++ b/lib/ui/app/menu_drawer.dart @@ -191,9 +191,7 @@ class MenuDrawer extends StatelessWidget { children: [ DrawerTile( company: company, - icon: kIsWeb - ? Icons.dashboard - : FontAwesomeIcons.tachometerAlt, + icon: getEntityIcon(EntityType.dashboard), title: localization.dashboard, onTap: () => store.dispatch( ViewDashboard(navigator: Navigator.of(context))), @@ -257,7 +255,7 @@ class MenuDrawer extends StatelessWidget { // STARTER: menu - do not remove comment DrawerTile( company: company, - icon: FontAwesomeIcons.chartLine, + icon: getEntityIcon(EntityType.reports), title: localization.reports, onTap: () { store.dispatch( @@ -266,7 +264,7 @@ class MenuDrawer extends StatelessWidget { ), DrawerTile( company: company, - icon: FontAwesomeIcons.cog, + icon: getEntityIcon(EntityType.settings), title: localization.settings, onTap: () { store.dispatch(ViewSettings( @@ -338,7 +336,9 @@ class _DrawerTileState extends State { ? kDashboard : widget.title == localization.settings ? kSettings - : widget.title == localization.reports ? kReports : widget.entityType.name; + : widget.title == localization.reports + ? kReports + : widget.entityType.name; Widget trailingWidget; if (!state.prefState.isMenuCollapsed) { diff --git a/lib/utils/icons.dart b/lib/utils/icons.dart index a8275d41e..2d7c5e086 100644 --- a/lib/utils/icons.dart +++ b/lib/utils/icons.dart @@ -55,6 +55,12 @@ IconData getEntityActionIcon(EntityAction entityAction) { IconData getEntityIcon(EntityType entityType) { switch (entityType) { + case EntityType.dashboard: + return FontAwesomeIcons.tachometerAlt; + case EntityType.reports: + return FontAwesomeIcons.chartLine; + case EntityType.settings: + return FontAwesomeIcons.cog; case EntityType.product: return FontAwesomeIcons.cube; case EntityType.project: