From 9073af0d3c558e6d775802267674600a49fda8d7 Mon Sep 17 00:00:00 2001 From: himeshr Date: Mon, 15 Jan 2024 18:31:02 +0530 Subject: [PATCH] avniproject/avni-client#1256 | First draft code changes to support nested reportCards on customDashboard --- .../customDashboard/CustomDashboardActions.js | 23 ++++++++++++++++--- .../src/service/RuleEvaluationService.js | 9 ++++++++ .../src/views/approval/ApprovalListingView.js | 3 ++- .../src/views/customDashboard/CardListView.js | 6 ++--- .../src/views/customDashboard/CardTileView.js | 6 ++--- .../customDashboard/CustomDashboardView.js | 13 ++++++++--- 6 files changed, 47 insertions(+), 13 deletions(-) diff --git a/packages/openchs-android/src/action/customDashboard/CustomDashboardActions.js b/packages/openchs-android/src/action/customDashboard/CustomDashboardActions.js index 4ff4045f2..ba57d0561 100644 --- a/packages/openchs-android/src/action/customDashboard/CustomDashboardActions.js +++ b/packages/openchs-android/src/action/customDashboard/CustomDashboardActions.js @@ -73,7 +73,8 @@ class CustomDashboardActions { // This action is responsible for loading data for multiple views. If any of the views have to be updated then this mega action has to be invoked and duplicating the callback implementation on the action. We have to break this action into smaller actions for each view. Starting with task here, which is why it invokes a different callback and the service doesn't handle task. static onCardPress(state, action, context) { const newState = {...state}; - const reportCard = context.get(EntityService).findByUUID(action.reportCardUUID, ReportCard.schema.name); + const rcUUID = action.reportCardUUID.substring(0, action.reportCardUUID.indexOf('#')); + const reportCard = context.get(EntityService).findByUUID(rcUUID, ReportCard.schema.name); if (reportCard.isStandardTaskType()) { action.goToTaskLists(reportCard.standardReportCardType.getTaskTypeType(), state.ruleInput.ruleInputArray); } else { @@ -112,7 +113,19 @@ class CustomDashboardActions { newState.countUpdateTime = new Date(); //Update this to ensure reportCard count change is reflected reportCardSectionMappings.forEach(rcm => { const start = new Date(); - newState.cardToCountResultMap[rcm.card.uuid] = context.get(ReportCardService).getReportCardCount(rcm.card, newState.ruleInput.ruleInputArray); + const countQueryResponse = context.get(ReportCardService).getReportCardCount(rcm.card, newState.ruleInput.ruleInputArray); + //todo, set counts for rcm.card.uuid with #identifier suffix if needed + if(rcm.card.nested) { + _.map(countQueryResponse, (reportCard, index) => { + const itemKey = rcm.card.getCardId(index); + newState.cardToCountResultMap[itemKey] = { + ...reportCard, + itemKey + }; + }); + } else { + newState.cardToCountResultMap[rcm.card.getCardId()] = countQueryResponse; + } General.logDebug('CustomDashboardActions', `${rcm.card.name} took ${new Date() - start} ms`); }); return newState; @@ -122,8 +135,12 @@ class CustomDashboardActions { const newState = {...state}; const reportCardSectionMappings = state.reportCardSectionMappings; newState.countUpdateTime = new Date(); //Update this to ensure reportCard count change is reflected + //todo, remove counts for rcm.card.uuid with #identifier suffix if needed reportCardSectionMappings.forEach(rcm => { - newState.cardToCountResultMap[rcm.card.uuid]= null; + const keysOfReportCard= _.keys(newState.cardToCountResultMap).filter((itemKey) => itemKey.startsWith(rcm.card.uuid)); + _.forEach(keysOfReportCard, (itemKey) => { + newState.cardToCountResultMap[itemKey]= null; + }); }); return newState; } diff --git a/packages/openchs-android/src/service/RuleEvaluationService.js b/packages/openchs-android/src/service/RuleEvaluationService.js index d2ca1ec81..baad2689d 100644 --- a/packages/openchs-android/src/service/RuleEvaluationService.js +++ b/packages/openchs-android/src/service/RuleEvaluationService.js @@ -706,6 +706,15 @@ class RuleEvaluationService extends BaseService { const queryResult = this.executeDashboardCardRule(reportCard, ruleInput); if (this.isOldStyleQueryResult(queryResult)) { return {primaryValue: queryResult.length, secondaryValue: null, clickable: true}; + } else if (reportCard.nested) { + return _.map(queryResult.reportCards, (reportCardResultsItr, index) => ({ + textColor: reportCard.textColor, + cardColor: reportCard.cardColor, + ...reportCardResultsItr, + clickable: _.isFunction(reportCardResultsItr.lineListFunction), + itemKey: reportCard.getCardId(index), + reportCardUUID: reportCard.uuid + }) ); } else { return { primaryValue: queryResult.primaryValue, diff --git a/packages/openchs-android/src/views/approval/ApprovalListingView.js b/packages/openchs-android/src/views/approval/ApprovalListingView.js index ed4c1576c..140d8dfc6 100644 --- a/packages/openchs-android/src/views/approval/ApprovalListingView.js +++ b/packages/openchs-android/src/views/approval/ApprovalListingView.js @@ -52,7 +52,8 @@ class ApprovalListingView extends AbstractComponent { onFilterChange(filterItem) { const {reportCardUUID, reportsFilter} = this.props; - const reportCard = this.getService(EntityService).findByUUID(reportCardUUID, ReportCard.schema.name); + const rcUUID = reportCardUUID.substring(0, reportCardUUID.indexOf('#')); + const reportCard = this.getService(EntityService).findByUUID(rcUUID, ReportCard.schema.name); const subjects = this.getService(ReportCardService).getResultForApprovalCardsType(reportCard.standardReportCardType, reportsFilter, filterItem.value); this.setState({subjects: subjects, formMapping: filterItem.value}); } diff --git a/packages/openchs-android/src/views/customDashboard/CardListView.js b/packages/openchs-android/src/views/customDashboard/CardListView.js index a064d7541..c1a399a67 100644 --- a/packages/openchs-android/src/views/customDashboard/CardListView.js +++ b/packages/openchs-android/src/views/customDashboard/CardListView.js @@ -6,7 +6,7 @@ import {CountResult} from "./CountResult"; import {get} from 'lodash'; export const CardListView = ({reportCard, I18n, onCardPress, countResult}) => { - const {name, colour, uuid} = reportCard; + const {name, colour, itemKey} = reportCard; const renderNumber = () => { return (_.isNil(get(countResult, 'primaryValue')) ? : @@ -21,8 +21,8 @@ export const CardListView = ({reportCard, I18n, onCardPress, countResult}) => { }; return ( - onCardPress(uuid)} disabled={!get(countResult, 'clickable')}> - + onCardPress(itemKey)} disabled={!get(countResult, 'clickable')}> + {I18n.t(name)} diff --git a/packages/openchs-android/src/views/customDashboard/CardTileView.js b/packages/openchs-android/src/views/customDashboard/CardTileView.js index 88e749f49..4a96e3f6a 100644 --- a/packages/openchs-android/src/views/customDashboard/CardTileView.js +++ b/packages/openchs-android/src/views/customDashboard/CardTileView.js @@ -28,13 +28,13 @@ const renderNumber = function (countResult, textColor) { const cardGap = 16; export const CardTileView = ({index, reportCard, I18n, onCardPress, countResult}) => { - const {name, uuid, textColor, iconName} = reportCard; + const {name, itemKey, textColor, iconName} = reportCard; const cardWidth = (Dimensions.get('window').width - cardGap * 3) / 2; const cardColor = reportCard.cardColor || '#ffffff'; return ( - onCardPress(uuid)} disabled={!get(countResult, 'clickable')}> - onCardPress(itemKey)} disabled={!get(countResult, 'clickable')}> + { + const repeatTimes = cardIter.nested ? cardIter.initCountOfCards: 1; + return Array(repeatTimes).fill(cardIter).map((card, i) => ({ ...card, itemKey: card.getCardId(i)})); + } const activeDashboardSectionMappings = _.filter(this.state.reportCardSectionMappings, ({dashboardSection}) => this.state.activeDashboardUUID === dashboardSection.dashboard.uuid); const sectionWiseData = _.chain(activeDashboardSectionMappings) .groupBy(({dashboardSection}) => dashboardSection.uuid) .map((groupedData, sectionUUID) => { const section = this.getService(EntityService).findByUUID(sectionUUID, DashboardSection.schema.name); - const cards = _.map(_.sortBy(groupedData, 'displayOrder'), ({card}) => card); + const cardsWithNestedContent = _.map(_.sortBy(groupedData, 'displayOrder'), ({card}) => card); + //todo split nested cardsWithNestedContent into separate ones + const cards = _.flatMap(cardsWithNestedContent, splitNestedCards); return {section, cards}; }) .sortBy('section.displayOrder') @@ -129,13 +135,14 @@ class CustomDashboardView extends AbstractComponent { this.renderSectionName(section.name, section.description, section.viewType, cards)} {_.map(cards, (card, index) => ( + //todo, use explicit key instead of card.uuid ))}