Skip to content

Commit

Permalink
#808 Improved render/update performance of a few fundamental react co…
Browse files Browse the repository at this point in the history
…ntrols. Switched to flatlist from listview.
  • Loading branch information
petmongrels committed Jan 20, 2023
1 parent 4823004 commit 14e9e34
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 123 deletions.
82 changes: 29 additions & 53 deletions packages/openchs-android/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class MyDashboardActions {
const genderQuery = (path) => _.map(action.selectedGenders, (gender) => `${path} = "${gender.name}"`);

const customFilterService = context.get(CustomFilterService);
var individualUUIDs = [];
let individualUUIDs = [];
const selectedCustomFilterBySubjectType = _.mapValues(action.selectedCustomFilters, selectedFilters => {
const s = selectedFilters.filter(filter => filter.subjectTypeUUID === action.selectedSubjectType.uuid);
return s.length === 0 ? [] : s
Expand Down
22 changes: 11 additions & 11 deletions packages/openchs-android/src/service/IndividualService.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,17 +422,17 @@ class IndividualService extends BaseService {
fromDate)
.filtered((_.isEmpty(addressQuery) ? 'uuid != null' : `${addressQuery}`))
.map((individual) => {
const registrationDate = individual.registrationDate;
return {
individual,
visitInfo: {
uuid: individual.uuid,
visitName: [],
groupingBy: General.formatDate(registrationDate),
sortingBy: registrationDate,
allow: true,
}
};
const registrationDate = individual.registrationDate;
return {
individual,
visitInfo: {
uuid: individual.uuid,
visitName: [],
groupingBy: General.formatDate(registrationDate),
sortingBy: registrationDate,
allow: true,
}
};
})
.reduce(this._uniqIndividualWithVisitName, new Map())
.values()]
Expand Down
22 changes: 11 additions & 11 deletions packages/openchs-android/src/views/common/ProgramFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ class ProgramFilter extends AbstractComponent {
const valueLabelPairs = this.props.visits.map(({uuid, operationalProgramName, operationalEncounterTypeName, name}) => new RadioLabelValue(operationalProgramName || operationalEncounterTypeName || name, uuid, false));
return (
<RadioGroup
multiSelect={this.props.multiSelect}
style={{
marginTop: Styles.VerticalSpacingBetweenInGroupFormElements,
marginBottom: Styles.VerticalSpacingBetweenInGroupFormElements
}}
borderStyle={{borderWidth: 0}}
inPairs={true}
onPress={({label, value}) => this.props.onToggle(label, value)}
selectionFn={(value) => this.props.selectionFn(value)}
labelKey={this.props.name}
mandatory={false}
multiSelect={this.props.multiSelect}
style={{
marginTop: Styles.VerticalSpacingBetweenInGroupFormElements,
marginBottom: Styles.VerticalSpacingBetweenInGroupFormElements
}}
borderStyle={{borderWidth: 0}}
inPairs={true}
onPress={({label, value}) => this.props.onToggle(label, value)}
selectionFn={(value) => this.props.selectionFn(value)}
labelKey={this.props.name}
mandatory={false}
labelValuePairs={valueLabelPairs}/>
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/openchs-android/src/views/filter/FiltersView.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import {Dimensions, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import {Dimensions, StyleSheet, FlatList, Text, TouchableOpacity, View} from 'react-native';
import AbstractComponent from "../../framework/view/AbstractComponent";
import Distances from '../primitives/Distances'
import SingleSelectFilter from './SingleSelectFilter';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class ValidationErrorMessage extends AbstractComponent {
super(props, context);
}

shouldComponentUpdate(nextProps, nextState, nextContext) {
return this.props.validationResult !== nextProps.validationResult;
}

render() {
return _.isNil(this.props.validationResult) || this.props.validationResult.success ? <View/> : <Text style={{color: Colors.ValidationError, flex: 0.3}}>{this.I18n.t(this.props.validationResult.messageKey, this.props.validationResult.extra)}</Text>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
import AbstractComponent from "../../framework/view/AbstractComponent";
import {Text, TouchableNativeFeedback, View} from "react-native";
import ListView from "deprecated-react-native-listview";
import {FlatList, TouchableNativeFeedback, View} from "react-native";
import PropTypes from 'prop-types';
import React from "react";
import React, {Component} from "react";
import Path from "../../framework/routing/Path";
import GlobalStyles from "../primitives/GlobalStyles";
import AppHeader from "../common/AppHeader";
import Colors from "../primitives/Colors";
import General from "../../utility/General";
import CHSContainer from "../common/CHSContainer";
import Styles from "../primitives/Styles";
import SearchResultsHeader from "./SearchResultsHeader";
import IndividualDetailsCard from "../common/IndividualDetailsCard";
import {IndividualSearchActionNames as Actions} from "../../action/individual/IndividualSearchActions";
import {Individual} from "openchs-models";
import ListViewHelper from "../../utility/ListViewHelper";
import {getUnderlyingRealmCollection, Individual} from "openchs-models";
import ZeroResults from "../common/ZeroResults";

class IndividualSearchResultRow extends Component {
static propTypes = {
item: PropTypes.any.isRequired,
onResultRowPress: PropTypes.func.isRequired
}

constructor(props, context) {
super(props, context);
}

shouldComponentUpdate() {
return false;
}

render() {
const {item, onResultRowPress} = this.props;
const individual = new Individual(item);
General.logDebug("IndividualSearchResultRow", `${individual.name}`);
return <TouchableNativeFeedback key={individual.uuid} onPress={() => onResultRowPress(individual)}
background={TouchableNativeFeedback.SelectableBackground()}>
<View>
<IndividualDetailsCard individual={individual}/>
</View>
</TouchableNativeFeedback>;
}
}

@Path('/individualSearchResults')
class IndividualSearchResultsView extends AbstractComponent {
static propTypes = {
Expand All @@ -39,31 +61,23 @@ class IndividualSearchResultsView extends AbstractComponent {
super.UNSAFE_componentWillMount();
}

renderRow(item, onResultRowPress) {
return <TouchableNativeFeedback onPress={() => onResultRowPress(new Individual(item))}
background={TouchableNativeFeedback.SelectableBackground()}>
<View>
<IndividualDetailsCard individual={new Individual(item)}/>
</View>
</TouchableNativeFeedback>
}

render() {
General.logDebug(this.viewName(), 'render');
const dataSource = ListViewHelper.getDataSource(this.props.searchResults);
const title = this.props.headerTitle || "searchResults";
const searchResultsCollection = getUnderlyingRealmCollection(this.props.searchResults);

return (
<CHSContainer theme={{iconFamily: 'MaterialIcons'}} style={{backgroundColor: Colors.GreyContentBackground}}>
<View style={{backgroundColor: Colors.GreyContentBackground}}>
<AppHeader title={this.I18n.t(title)}/>
<SearchResultsHeader totalCount={this.props.totalSearchResultsCount}
displayedCount={this.props.searchResults.length}/>
<ListView enableEmptySections={true}
dataSource={dataSource}
style={{marginBottom: 16}}
renderRow={(item) => this.renderRow(item, this.onResultRowPress.bind(this))}/>
<FlatList
data={searchResultsCollection}
keyExtractor={(item) => item.uuid}
renderItem={({item}) => <IndividualSearchResultRow item={item} onResultRowPress={this.onResultRowPress.bind(this)}/>}
/>
<ZeroResults count={this.props.searchResults.length}/>
</CHSContainer>
</View>
);
}

Expand Down
Loading

0 comments on commit 14e9e34

Please sign in to comment.