From 12390bb98b8508139180db6f5088c540395d6976 Mon Sep 17 00:00:00 2001 From: tamslo Date: Fri, 6 Dec 2024 12:03:17 +0100 Subject: [PATCH] refactor(app): add inhibitor list to PDF --- app/lib/common/models/drug/drug.dart | 21 ++++- .../common/widgets/gene_modulator_list.dart | 79 +++++++++++++------ .../widgets/phenoconversion_explanation.dart | 14 +++- app/lib/faq/pages/content.dart | 2 +- 4 files changed, 86 insertions(+), 30 deletions(-) diff --git a/app/lib/common/models/drug/drug.dart b/app/lib/common/models/drug/drug.dart index ab12020f..932a5676 100644 --- a/app/lib/common/models/drug/drug.dart +++ b/app/lib/common/models/drug/drug.dart @@ -195,16 +195,26 @@ extension CriticalDrugs on List { List getDrugsWithBrandNames( List? drugNames, - { bool capitalize = false } + { + bool capitalize = false, + String? brandNamesPrefix, + } ) { return drugNames?.map( - (drugName) => _getDrugWithBrandNames(drugName, capitalize: capitalize) + (drugName) => _getDrugWithBrandNames( + drugName, + capitalize: capitalize, + brandNamesPrefix: brandNamesPrefix, + ) ).toList() ?? []; } String _getDrugWithBrandNames( String drugName, - { required bool capitalize } + { + bool capitalize = false, + String? brandNamesPrefix, + } ) { final drug = DrugsWithGuidelines.instance.drugs?.firstOrNullWhere( (drug) => drug.name == drugName @@ -213,5 +223,8 @@ String _getDrugWithBrandNames( if (drug == null || drug.annotations.brandNames.isEmpty) { return displayedDrugName; } - return '$displayedDrugName (${drug.annotations.brandNames.join(', ')})'; + final branNamesString = drug.annotations.brandNames.join(', '); + return brandNamesPrefix != null + ? '$displayedDrugName ($brandNamesPrefix: $branNamesString)' + : '$displayedDrugName ($branNamesString)'; } diff --git a/app/lib/common/widgets/gene_modulator_list.dart b/app/lib/common/widgets/gene_modulator_list.dart index b5844f9c..51aff1ca 100644 --- a/app/lib/common/widgets/gene_modulator_list.dart +++ b/app/lib/common/widgets/gene_modulator_list.dart @@ -1,8 +1,8 @@ import '../module.dart'; -class GeneModulatorList extends StatelessWidget { +// TODO(tamslo): if only one item, just print label and text afterwards +class GeneModulatorList { const GeneModulatorList({ - super.key, required this.geneName, this.onlyActiveDrugs = false, this.displayedDrug, @@ -12,25 +12,70 @@ class GeneModulatorList extends StatelessWidget { final bool onlyActiveDrugs; final String? displayedDrug; + List _filterActiveModulatorDrugNames(List allModulatorDrugs) { + final activeModulators = activeInhibitorsFor( + geneName, + drug: displayedDrug, + ); + return allModulatorDrugs.filter(activeModulators.contains).toList(); + } + List _getModulatorDrugNames( + BuildContext context, Map>modulatorDefinition, String geneName, ) { final allModulatorDrugs = modulatorDefinition[geneName]!.keys.toList(); - if (onlyActiveDrugs) { - final activeModulators = activeInhibitorsFor( - geneName, - drug: displayedDrug, - ); - return allModulatorDrugs.filter(activeModulators.contains).toList(); + final modulatorDrugNames = onlyActiveDrugs + ? _filterActiveModulatorDrugNames(allModulatorDrugs) + : allModulatorDrugs; + return getDrugsWithBrandNames( + modulatorDrugNames, + capitalize: true, + brandNamesPrefix: context.l10n.drug_item_brand_names.toLowerCase(), + ); + } + + Map> getContent(BuildContext context) { + final contentDefinition = { + context.l10n.strong_inhibitors_description: strongDrugInhibitors, + context.l10n.moderate_inhibitors_description: moderateDrugInhibitors, + }; + final content = >{}; + for (final subdefinition in contentDefinition.entries) { + final modulatorDefinition = subdefinition.value; + final drugNames = + _getModulatorDrugNames(context, modulatorDefinition, geneName); + if (drugNames.isEmpty) continue; + final getDescription = subdefinition.key; + content[getDescription(geneName)] = drugNames; } - return allModulatorDrugs; + return content; } + String asString(BuildContext context, {String linePrefix = ''}) { + final listString = StringBuffer(); + for (final modulatorContentEntry in getContent(context).entries) { + final entryString = StringBuffer(modulatorContentEntry.key); + for (final drugName in modulatorContentEntry.value) { + entryString.write('\n$linePrefix- $drugName'); + } + listString.write('\n$linePrefix$entryString'); + } + return listString.toString(); + } + + GeneModulatorListWidget get widget => GeneModulatorListWidget(this); +} + +class GeneModulatorListWidget extends StatelessWidget { + const GeneModulatorListWidget(this.listDefinition); + + final GeneModulatorList listDefinition; + List _buildModulatorSublist(modulatorContentEntry) { final descriptionText = modulatorContentEntry.key; final modulatorDrugNames = modulatorContentEntry.value; - if (modulatorDrugNames.isEmpty) return [SizedBox.shrink()]; return [ SizedBox(height: PharMeTheme.smallSpace), Text( @@ -38,23 +83,13 @@ class GeneModulatorList extends StatelessWidget { style: TextStyle(fontStyle: FontStyle.italic), ), SizedBox(height: PharMeTheme.smallSpace), - UnorderedList( - getDrugsWithBrandNames( - modulatorDrugNames, - capitalize: true, - ), - ), + UnorderedList(modulatorDrugNames), ]; } @override Widget build(BuildContext context) { - final modulatorContent = { - context.l10n.strong_inhibitors_description(geneName): - _getModulatorDrugNames(strongDrugInhibitors, geneName), - context.l10n.moderate_inhibitors_description(geneName): - _getModulatorDrugNames(moderateDrugInhibitors, geneName), - }; + final modulatorContent = listDefinition.getContent(context); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: diff --git a/app/lib/common/widgets/phenoconversion_explanation.dart b/app/lib/common/widgets/phenoconversion_explanation.dart index c9796a65..0c0e7bb5 100644 --- a/app/lib/common/widgets/phenoconversion_explanation.dart +++ b/app/lib/common/widgets/phenoconversion_explanation.dart @@ -90,8 +90,16 @@ String? getPhenoconversionExplanationString({ }) { final displayConfig = displayType.getConfig(context); return inhibitedGenotypes.flatMap((genotypeResult) => [ - _getPhenoconversionDetailText(context, genotypeResult, drug: drugName, displayConfig: displayConfig), - // TODO: get list + _getPhenoconversionDetailText( + context, + genotypeResult, drug: drugName, + displayConfig: displayConfig, + ), + GeneModulatorList( + geneName: genotypeResult.gene, + onlyActiveDrugs: true, + displayedDrug: drugName, + ).asString(context, linePrefix: ' '), ]).join(displayConfig.partSeparator); } @@ -135,7 +143,7 @@ class PhenoconversionExplanation extends StatelessWidget { geneName: genotypeResult.gene, onlyActiveDrugs: true, displayedDrug: drugName, - ), + ).widget, ] ).toList(), ); diff --git a/app/lib/faq/pages/content.dart b/app/lib/faq/pages/content.dart index a190b555..d8cad59e 100644 --- a/app/lib/faq/pages/content.dart +++ b/app/lib/faq/pages/content.dart @@ -70,7 +70,7 @@ final faqContent = [ children: [ Text(context.l10n.faq_answer_phenoconversion), ...inhibitableGenes.map( - (geneName) => GeneModulatorList(geneName: geneName), + (geneName) => GeneModulatorList(geneName: geneName).widget, ), ], ),