Skip to content

Commit

Permalink
#1452 - force refresh and display message of last updated
Browse files Browse the repository at this point in the history
  • Loading branch information
petmongrels committed Jul 11, 2024
1 parent dac49da commit 8a816a5
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 34 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,6 @@ else
$(call upload,platformTranslation,@packages/openchs-android/translations/ka_IN.json)
endif


deploy_platform_translations_staging:
make deploy_translations server=https://staging.avniproject.org port=443 username=admin password=$(OPENCHS_STAGING_ADMIN_PASSWORD)

Expand All @@ -496,3 +495,6 @@ deploy_platform_translations_for_flavor_live:
deploy_platform_translations_live_for_all_flavors:
make deploy_platform_translations_for_flavor_live flavor='lfe'
make deploy_platform_translations_for_flavor_live flavor='generic'

deploy_platform_translations_local_live:
make deploy_translations server=http://localhost port=8021 username=$(username) password=$(password)
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class CustomDashboardActions {
loading: false,
reportCardSectionMappings: [],
cardToCountResultMap: {},
countUpdateTime: null,
resultUpdatedAt: null,
hasFilters: false,
activeDashboardUUID: null,
customDashboardFilters: []
Expand Down Expand Up @@ -108,7 +108,7 @@ class CustomDashboardActions {
static setFilterApplied(state, action, context) {
const customDashboardCacheService = context.get(CustomDashboardCacheService);
customDashboardCacheService.clearResults(state.activeDashboardUUID);
return CustomDashboardActions.refreshCount(state, action, context);
return state;
}

static setFilterCleared(state, action, context) {
Expand All @@ -132,7 +132,6 @@ class CustomDashboardActions {
const newState = {...state};

newState.cardToCountResultMap = {};
newState.countUpdateTime = new Date(); //Update this to ensure reportCard count change is reflected

const ruleInputArray = context.get(DashboardFilterService).toRuleInputObjects(state.activeDashboardUUID, selectedFilterValues);
reportCardSectionMappings.forEach(rcm => {
Expand Down Expand Up @@ -168,7 +167,8 @@ class CustomDashboardActions {
}
General.logDebug('CustomDashboardActions', `${rcm.card.name} took ${new Date() - start} ms`);
});
customDashboardCacheService.setDashboardUpdateCompleted(state.activeDashboardUUID);
const {dashboardCache} = customDashboardCacheService.getDashboardCache(state.activeDashboardUUID);
newState.resultUpdatedAt = dashboardCache.updatedAt;
return newState;
}

Expand All @@ -193,14 +193,33 @@ class CustomDashboardActions {
}
return state;
}

static forceRefresh(state, action, context) {
const customDashboardCacheService = context.get(CustomDashboardCacheService);
customDashboardCacheService.clearResults(state.activeDashboardUUID);
return state;
}

static clearCounts(state, action, context) {
const newState = {...state};
newState.cardToCountResultMap = {};
return newState;
}
}

// This is not a reducer, just a code reuse mechanism
export function performCustomDashboardActionAndRefresh(dispatcher, actionName, action) {
dispatcher.dispatchAction(actionName, action);
// These are not reducers, just a code reuse mechanism
export function performCustomDashboardActionAndRefresh(dispatcher, actionName, payload) {
dispatcher.dispatchAction(actionName, payload);
setTimeout(() => dispatcher.dispatchAction(CustomDashboardActionNames.REFRESH_COUNT), 500);
}

export function performCustomDashboardActionAndClearRefresh(dispatcher, actionName, payload) {
dispatcher.dispatchAction(actionName, payload);
dispatcher.dispatchAction(CustomDashboardActionNames.CLEAR_COUNTS, payload);
setTimeout(() => dispatcher.dispatchAction(CustomDashboardActionNames.REFRESH_COUNT), 500);
}


const ActionPrefix = 'CustomDashboard';

const CustomDashboardActionNames = {
Expand All @@ -212,7 +231,9 @@ const CustomDashboardActionNames = {
SET_DASHBOARD_FILTERS: `${ActionPrefix}.SET_DASHBOARD_FILTERS`,
FILTER_APPLIED: `${ActionPrefix}.FILTER_APPLIED`,
FILTER_CLEARED: `${ActionPrefix}.FILTER_CLEARED`,
DISABLE_AUTO_REFRESH_VALUE_UPDATED: `${ActionPrefix}.DISABLE_AUTO_REFRESH_VALUE_UPDATED`
DISABLE_AUTO_REFRESH_VALUE_UPDATED: `${ActionPrefix}.DISABLE_AUTO_REFRESH_VALUE_UPDATED`,
FORCE_REFRESH: `${ActionPrefix}.FORCE_REFRESH`,
CLEAR_COUNTS: `${ActionPrefix}.CLEAR_COUNTS`
};

const CustomDashboardActionMap = new Map([
Expand All @@ -224,7 +245,9 @@ const CustomDashboardActionMap = new Map([
[CustomDashboardActionNames.SET_DASHBOARD_FILTERS, CustomDashboardActions.setCustomDashboardFilters],
[CustomDashboardActionNames.FILTER_APPLIED, CustomDashboardActions.setFilterApplied],
[CustomDashboardActionNames.FILTER_CLEARED, CustomDashboardActions.setFilterCleared],
[CustomDashboardActionNames.DISABLE_AUTO_REFRESH_VALUE_UPDATED, CustomDashboardActions.disableAutoRefreshValueUpdated]
[CustomDashboardActionNames.DISABLE_AUTO_REFRESH_VALUE_UPDATED, CustomDashboardActions.disableAutoRefreshValueUpdated],
[CustomDashboardActionNames.FORCE_REFRESH, CustomDashboardActions.forceRefresh],
[CustomDashboardActionNames.CLEAR_COUNTS, CustomDashboardActions.clearCounts]
]);

export {CustomDashboardActionNames, CustomDashboardActionMap, CustomDashboardActions}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import BaseService from "./BaseService";
import Service from "../framework/bean/Service";
import {CustomDashboardCache, DashboardFilterConfig} from "openchs-models";
import {CustomDashboardCache, Dashboard, DashboardFilterConfig, EncounterType, Program, Range, SubjectType} from "openchs-models";
import _ from "lodash";
import EntityService from "./EntityService";
import {Dashboard, EncounterType, Range, Program, SubjectType} from "openchs-models";
import DashboardFilterService from "./reports/DashboardFilterService";
import General from "../utility/General";
import FormMetaDataSelection from "../model/FormMetaDataSelection";
Expand Down Expand Up @@ -138,13 +137,15 @@ class CustomDashboardCacheService extends BaseService {
result.reportCard = reportCard.uuid;
dashboardCache.nestedReportCardResults.push(result);
});
dashboardCache.updatedAt = new Date();
this.saveOrUpdate(dashboardCache);
}

clearResults(dashboardUUID) {
const dashboardCache = getDashboardCache(this, dashboardUUID);
dashboardCache.reportCardResults = [];
dashboardCache.nestedReportCardResults = [];
dashboardCache.updatedAt = null;
this.saveOrUpdate(dashboardCache);
}

Expand All @@ -160,13 +161,8 @@ class CustomDashboardCacheService extends BaseService {
_.remove(dashboardCache.reportCardResults, (x) => x.reportCard === reportCard.uuid && x.dashboard === dashboardCache.dashboard.uuid);
reportCardResult.dashboard = dashboardUUID;
reportCardResult.reportCard = reportCard.uuid;
dashboardCache.reportCardResults.push(reportCardResult);
this.saveOrUpdate(dashboardCache);
}

setDashboardUpdateCompleted(dashboardUUID) {
const dashboardCache = getDashboardCache(this, dashboardUUID);
dashboardCache.updatedAt = new Date();
dashboardCache.reportCardResults.push(reportCardResult);
this.saveOrUpdate(dashboardCache);
}
}
Expand Down
7 changes: 5 additions & 2 deletions packages/openchs-android/src/service/SyncService.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ import AllSyncableEntityMetaData from "../model/AllSyncableEntityMetaData";
import {IndividualSearchActionNames as IndividualSearchActions} from '../action/individual/IndividualSearchActions';
import {LandingViewActionsNames as LandingViewActions} from '../action/LandingViewActions';
import {MyDashboardActionNames} from '../action/mydashboard/MyDashboardActions';
import {CustomDashboardActionNames, performCustomDashboardActionAndRefresh} from '../action/customDashboard/CustomDashboardActions';
import {
CustomDashboardActionNames,
performCustomDashboardActionAndClearRefresh,
} from '../action/customDashboard/CustomDashboardActions';
import LocalCacheService from "./LocalCacheService";
import CustomDashboardService, {CustomDashboardType} from './customDashboard/CustomDashboardService';

Expand Down Expand Up @@ -412,7 +415,7 @@ class SyncService extends BaseService {
const customDashboardService = this.context.getService(CustomDashboardService);
const renderCustomDashboard = customDashboardService.isCustomDashboardMarkedPrimary();
if (renderCustomDashboard) {
performCustomDashboardActionAndRefresh(this, CustomDashboardActionNames.ON_LOAD, {customDashboardType: CustomDashboardType.None});
performCustomDashboardActionAndClearRefresh(this, CustomDashboardActionNames.ON_LOAD, {customDashboardType: CustomDashboardType.None});
} else {
this.dispatchAction(MyDashboardActionNames.ON_LOAD);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import CHSContainer from "../common/CHSContainer";
import AppHeader from "../common/AppHeader";
import React, {Fragment} from "react";
import Reducers from "../../reducer";
import {CustomDashboardActionNames as Actions, performCustomDashboardActionAndRefresh} from "../../action/customDashboard/CustomDashboardActions";
import {
CustomDashboardActionNames as Actions,
performCustomDashboardActionAndClearRefresh,
performCustomDashboardActionAndRefresh
} from "../../action/customDashboard/CustomDashboardActions";
import {SafeAreaView, ScrollView, StyleSheet, Text, TouchableNativeFeedback, View} from "react-native";
import _ from "lodash";
import CustomDashboardTab from "./CustomDashboardTab";
Expand Down Expand Up @@ -32,6 +36,7 @@ import MCIIcon from "react-native-vector-icons/MaterialCommunityIcons";
import Line from '../common/Line';
import {CardTileView} from './CardTileView';
import {CardListView} from './CardListView';
import UserInfoService from "../../service/UserInfoService";

const viewNameMap = {
'ApprovalListingView': ApprovalListingView,
Expand All @@ -41,15 +46,37 @@ const viewNameMap = {
'ChecklistListingView': ChecklistListingView
};

function RefreshSection({I18n, onRefreshPressed, lastUpdatedOn}) {
const refreshSectionStyle = {
paddingLeft: 15,
color: Styles.grey,
fontSize: 8,
fontWeight: 'bold',
textTransform: 'uppercase'
};
return <TouchableNativeFeedback onPress={() => onRefreshPressed()}>
<View style={{
backgroundColor: Colors.SubHeaderBackground,
flexDirection: 'row',
justifyContent: 'space-between',
minHeight: 45,
alignItems: 'center'
}}>
<Text style={refreshSectionStyle}>{I18n.t('lastRefreshedMessage', {dateTime: General.formatDateTime(lastUpdatedOn)})}</Text>
<MCIIcon style={{fontSize: 30, color: Colors.DullIconColor}} name='refresh'/>
</View>
</TouchableNativeFeedback>;
}

function SubHeader({I18n, onFilterPressed}) {
const filterLabelStyle = {
paddingLeft: 15,
color: Styles.grey,
fontSize: Styles.normalTextSize,
fontWeight: 'bold',
textTransform: 'uppercase'
textTransform: 'uppercase',
};
return <TouchableNativeFeedback onPress={() => onFilterPressed()}>
return <TouchableNativeFeedback onPress={() => onFilterPressed()} style={{flex: 0.5}}>
<View style={{
backgroundColor: Colors.SubHeaderBackground,
flexDirection: 'row',
Expand Down Expand Up @@ -110,12 +137,12 @@ class CustomDashboardView extends AbstractComponent {

UNSAFE_componentWillMount() {
const {customDashboardType} = this.props;
performCustomDashboardActionAndRefresh(this, Actions.ON_LOAD, {customDashboardType});
performCustomDashboardActionAndClearRefresh(this, Actions.ON_LOAD, {customDashboardType});
super.UNSAFE_componentWillMount();
}

onClearFilters() {
performCustomDashboardActionAndRefresh(this, Actions.FILTER_CLEARED, {dashboardUUID: this.state.activeDashboardUUID});
performCustomDashboardActionAndClearRefresh(this, Actions.FILTER_CLEARED, {dashboardUUID: this.state.activeDashboardUUID});
}

onDashboardNamePress(uuid) {
Expand Down Expand Up @@ -167,7 +194,7 @@ class CustomDashboardView extends AbstractComponent {
<View key={section.uuid} style={styles.sectionContainer}>
{section.viewType !== DashboardSection.viewTypeName.Default &&
this.renderSectionName(section.name, section.description, section.viewType, cards)}
<View style={section.viewType === 'Tile'? styles.cardContainer: styles.listContainer}>
<View style={section.viewType === 'Tile' ? styles.cardContainer : styles.listContainer}>
{_.map(cards, (card, index) => {
return section.viewType === 'Tile' ?
<CardTileView key={card.itemKey} reportCard={card} I18n={this.I18n}
Expand Down Expand Up @@ -231,21 +258,21 @@ class CustomDashboardView extends AbstractComponent {
return (<View/>);
}

renderFilters() {
return this.state.filtersPresent && <SubHeader I18n={this.I18n} onFilterPressed={() => this.onFilterPressed()}/>;
}

onFilterPressed() {
const {activeDashboardUUID} = this.state;
TypedTransition.from(this)
.with({
dashboardUUID: activeDashboardUUID,
onFilterChosen: (ruleInputArray) => this.dispatchAction(Actions.FILTER_APPLIED, {ruleInput: {ruleInputArray: ruleInputArray}, filterApplied: true}),
onFilterChosen: (ruleInputArray) => performCustomDashboardActionAndClearRefresh(this, Actions.FILTER_APPLIED, {
ruleInput: {ruleInputArray: ruleInputArray},
filterApplied: true
}),
loadFiltersData: (filters) => this.dispatchAction(Actions.SET_DASHBOARD_FILTERS, {customDashboardFilters: filters, filterApplied: true}),
}).to(FiltersViewV2, true);
}

render() {
const settings = this.getService(UserInfoService).getUserSettingsObject();
General.logDebug("CustomDashboardView", "render");
const {hideBackButton, startSync, renderSync, icon, customDashboardType, onSearch, showSearch} = this.props;
const title = this.props.title || 'dashboards';
Expand All @@ -271,7 +298,13 @@ class CustomDashboardView extends AbstractComponent {
{this.renderZeroResultsMessageIfNeeded()}
</ScrollView>
</SafeAreaView>}
{this.renderFilters()}
<View style={{display: "flex", flexDirection: "row", flex: 1, justifyContent: "space-between"}}>
{settings.autoRefreshDisabled && !_.isNil(this.state.resultUpdatedAt) &&
<RefreshSection I18n={this.I18n}
onRefreshPressed={() => performCustomDashboardActionAndClearRefresh(this, Actions.FORCE_REFRESH)}
lastUpdatedOn={this.state.resultUpdatedAt}/>}
{this.state.filtersPresent && <SubHeader I18n={this.I18n} onFilterPressed={() => this.onFilterPressed()}/>}
</View>
<Fragment>
{hasFilters && <View style={{display: "flex", padding: 10}}>
<SafeAreaView style={{maxHeight: 160}}>
Expand Down Expand Up @@ -317,7 +350,7 @@ const styles = StyleSheet.create({
justifyContent: 'flex-start',
},
listContainer: {
marginTop: 16
marginTop: 16
}
});

Expand Down
3 changes: 2 additions & 1 deletion packages/openchs-android/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@
"addressFilterImplicitBehaviorHint": "(Selection includes lower levels implicitly)",
"copyErrorTryAgain": "Copy Error & Try Again",
"copyErrorAndCancel": "Copy Error & Cancel",
"reportCopiedReportByPasting": "Report is copied. You can paste in a messaging app to report."
"reportCopiedReportByPasting": "Report is copied. You can paste in a messaging app to report.",
"lastRefreshedMessage": "Card numbers last updated on {{dateTime}"
}
}

0 comments on commit 8a816a5

Please sign in to comment.