diff --git a/src/clincoded/static/components/variant_central/interpretation/shared/calculator.js b/src/clincoded/static/components/variant_central/interpretation/shared/calculator.js index 83be34758..cba48480e 100644 --- a/src/clincoded/static/components/variant_central/interpretation/shared/calculator.js +++ b/src/clincoded/static/components/variant_central/interpretation/shared/calculator.js @@ -1,100 +1,55 @@ 'use strict'; -var React = require('react'); -var _ = require('underscore'); -var RestMixin = require('../../../rest').RestMixin; -var form = require('../../../../libs/bootstrap/form'); -var Form = form.Form; -var Input = form.Input; -var FormMixin = form.FormMixin; +import React from 'react'; +import _ from 'underscore'; var PathogenicityCalculator = module.exports.PathogenicityCalculator = React.createClass({ - mixins: [FormMixin, RestMixin], - propTypes: { interpretation: React.PropTypes.object, }, getInitialState: function() { return { - rules: 'ACMG 2015' // Default role for calculation + rules: 'ACMG 2015' // Currently use ACMG rules only }; }, - render: function() { - var interpretation = this.props.interpretation; - var evaluations = interpretation && interpretation.evaluations && interpretation.evaluations.length ? interpretation.evaluations : null; - var result = evaluations ? calculatePathogenicity(evaluations) : null; - var rules = this.state.rules; - - return ( -
{interpretation ? - progressBar(result, rules) - : - null - } -
- ); - }, -}); - -var progressBar = function(result, rules) { - return ( -
-
-
-
Benign:
- {result && result.benign_summary && result.benign_summary.length ? result.benign_summary.join(' | ') : 'No criteria met' } -
-
-
Pathogenic:
- {result && result.path_summary && result.path_summary.length ? result.path_summary.join(' | ') : 'No criteria met' } -
-
-
Calculated Pathogenicity{' (' + rules +')'}:
- {result && result.assertion ? result.assertion : 'None'} -
-
-

-
- ); -}; - -// Function to calculate pathogenicity -var calculatePathogenicity = function(evaluationObjList) { + calculatePathogenicity: function(evaluationObjList) { // setup count values - var MET = 'met'; - var NOT_MET = 'not-met'; - var NOT_EVALUATED = 'not-evaluated'; - var MODIFIER_VS = 'very-strong'; - var MODIFIER_S = 'strong'; - var MODIFIER_M = 'moderate'; - var MODIFIER_P = 'supporting'; - var MODIFIER_SA = 'stand-alone'; + const MET = 'met'; + const NOT_MET = 'not-met'; + const NOT_EVALUATED = 'not-evaluated'; + const MODIFIER_VS = 'very-strong'; + const MODIFIER_S = 'strong'; + const MODIFIER_M = 'moderate'; + const MODIFIER_P = 'supporting'; + const MODIFIER_SA = 'stand-alone'; + + let result = null; if (evaluationObjList && evaluationObjList.length) { - var evaluated = false; + let evaluated = false; // Initialize count numbers - var pvs_count = 0; - var ps_count = 0; - var pm_count = 0; - var pp_count = 0; - var ba_count = 0; - var bs_count = 0; - var bp_count = 0; + let pvs_count = 0; + let ps_count = 0; + let pm_count = 0; + let pp_count = 0; + let ba_count = 0; + let bs_count = 0; + let bp_count = 0; // count each criteria level (PVS, PS, PM, PP, BA, BS, BP) - for (var evaluationObj of evaluationObjList) { + for (let evaluationObj of evaluationObjList) { // In each evaluation object, criteria and criteriaStatus must exist, criteriaModifier may or may not - var criteria = evaluationObj.criteria; - var criteriaStatus = evaluationObj.criteriaStatus; + let criteria = evaluationObj.criteria; + let criteriaStatus = evaluationObj.criteriaStatus; // count met criteria only, modified by criteriaModifier if (criteriaStatus === MET) { evaluated = true; - var criteriaModifier = evaluationObj.criteriaModifier; + let criteriaModifier = evaluationObj.criteriaModifier; if ((criteria.indexOf('PVS') === 0 && criteriaModifier === '') || (criteria.indexOf('P') === 0 && criteriaModifier === MODIFIER_VS)) { pvs_count += 1; } else if ((criteria.indexOf('PS') === 0 && criteriaModifier === '') || (criteria.indexOf('P') === 0 && criteriaModifier === MODIFIER_S)) { @@ -115,13 +70,13 @@ var calculatePathogenicity = function(evaluationObjList) { } } - var contradict = ((pvs_count > 0 || ps_count > 0 || pm_count > 0 || pp_count > 0) && (ba_count > 0 || bs_count > 0 || bp_count > 0)) ? true : false; - var patho_assertion = null; - var benign_assertion = null; + let contradict = ((pvs_count > 0 || ps_count > 0 || pm_count > 0 || pp_count > 0) && (ba_count > 0 || bs_count > 0 || bp_count > 0)) ? true : false; + let patho_assertion = null; + let benign_assertion = null; // Algorithm, ACMG Standarts & Guidelines 2015 // setup cases for 4 types of assertions (Pathogenic, Likely pathogenic, Benign and Likely benign) - var cases = { + let cases = { path_pvs2: pvs_count >= 2 ? true : false, path_pvs1_ps1: (pvs_count === 1 && ps_count >= 1) ? true : false, path_pvs1_pm2: (pvs_count === 1 && pm_count >= 2) ? true : false, @@ -144,9 +99,9 @@ var calculatePathogenicity = function(evaluationObjList) { likelyBenign_bs1_pp1: (bs_count === 1 && bp_count === 1) ? true : false, likelyBenign_pp2: (bp_count >= 2) ? true : false, - } + }; - for (var cs of Object.keys(cases)) { + for (let cs of Object.keys(cases)) { if (cases[cs]) { if (cs.indexOf('path_') !== -1) { patho_assertion = 'Pathogenic'; @@ -162,7 +117,7 @@ var calculatePathogenicity = function(evaluationObjList) { } } - var assertion = null; + let assertion = null; if (!evaluated) { assertion = ''; } else if ((patho_assertion && contradict) || (benign_assertion && contradict)) { @@ -175,206 +130,102 @@ var calculatePathogenicity = function(evaluationObjList) { assertion = 'Uncertain significance - insufficient evidence'; } - var result = { + result = { assertion: assertion, - path_summary: [], - benign_summary: [] - }; + path_summary: {}, + benign_summary: {} + } + if (pvs_count > 0) { - result.path_summary.push('Very strong: ' + pvs_count.toString()); + result.path_summary['Very strong'] = pvs_count; } if (ps_count > 0) { - result.path_summary.push('Strong: ' + ps_count.toString()); + result.path_summary['Strong'] = ps_count; } if (pm_count > 0) { - result.path_summary.push('Moderate: ' + pm_count.toString()); + result.path_summary['Moderate'] = pm_count; } if (pp_count > 0) { - result.path_summary.push('Supporting: ' + pp_count.toString()); + result.path_summary['Supporting'] = pp_count; } if (ba_count > 0) { - result.benign_summary.push('Stand alone: ' + ba_count.toString()); + result.benign_summary['Stand alone'] = ba_count; } if (bs_count > 0) { - result.benign_summary.push('Strong: ' + bs_count.toString()); + result.benign_summary['Strong'] = bs_count; } if (bp_count > 0) { - result.benign_summary.push('Supporting: ' + bp_count.toString());; + result.benign_summary['Supporting'] = bp_count; } } return result; -}; - -var TestCalculator = module.exports.TestCalculator = React.createClass({ - mixins: [FormMixin, RestMixin], - - propTypes: { - interpretation: React.PropTypes.object, - }, - - getInitialState: function() { - return { - // For test pathogenicity calculator only - //criteriaList: null, - criteria_evaluated: null, - PVS1: false, - PS1: false, - PS2: false, - PS3: false, - PS4: false, - PM1: false, - PM2: false, - PM3: false, - PM4: false, - PM5: false, - PM6: false, - PP1: false, - PP2: false, - PP3: false, - PP4: false, - PP5: false, - BA1: false, - BS1: false, - BS2: false, - BS3: false, - BS4: false, - BP1: false, - BP2: false, - BP3: false, - BP4: false, - BP5: false, - BP6: false, - BP7: false, - // Test above - - rules: 'ACMG 2015' // Default role for calculation - }; - }, - - // Function for test pathogeinicity calculator only, will be removed later. - handleChange: function(ref, e) { - var criteria_value = this.refs[ref].getValue(); - if (!this.state.ref || this.state.ref !== criteria_value) { - var critObj = {}; - critObj[ref] = criteria_value; - this.setState(critObj); - } - - var criteria_evaluated = this.state.criteria_evaluated ? this.state.criteria_evaluated : []; - var criteriaObj = {}; - criteriaObj.criteria = ref; - if (criteria_value === 'not-met' || criteria_value === 'met') { - criteriaObj.criteriaStatus = criteria_value; - criteriaObj.criteriaModifier = ''; - } else { - criteriaObj.criteriaStatus = 'met'; - criteriaObj.criteriaModifier = criteria_value; - } - - var criteria_index = -1; - criteria_evaluated.map((ct, i) => { - if (ct.criteria === ref) { - criteria_index = i; - } - }); - if (criteria_index > -1 && criteria_value === 'not-evaluated') { - criteria_evaluated.splice(criteria_index, 1); - } else if (criteria_index > -1 ) { - criteria_evaluated[criteria_index] = criteriaObj; - } else if (criteria_value !== 'not-evaluated') { - criteria_evaluated.push(criteriaObj); - } - - this.setState({ - criteria_evaluated: criteria_evaluated - }); - }, - - // Function for testing pathogenic calculator. Will be removed later. - setDropdown: function(criteria) { - return ( - - - - - - {(criteria.indexOf('PP') === 0 || criteria.indexOf('BP') === 0) ? null : } - {criteria.indexOf('M') === 1 ? null : (criteria.indexOf('P') === 0 ? : null)} - {criteria.indexOf('S') === 1 ? null : } - {criteria.indexOf('VS') === 1 ? null : (criteria.indexOf('P') === 0 ? : null)} - - ); }, render: function() { - var result = calculatePathogenicity(this.state.criteria_evaluated); - var rules = this.state.rules; + let interpretation = this.props.interpretation ? this.props.interpretation : null; + let evaluations = interpretation && interpretation.evaluations && interpretation.evaluations.length ? interpretation.evaluations : null; + let result = evaluations ? this.calculatePathogenicity(evaluations) : null; + let rules = this.state.rules; + + let benign_summary = result && result.benign_summary ? result.benign_summary : null; + let path_summary = result && result.path_summary ? result.path_summary : null; return ( -
-
- Test Pathogenicity Calculator -
- Select option values for any combination of criteria and check result in progress bar below. -
- {progressBar(result, rules)} -
-
- - - - - - - - - - - - - - - -
- {this.setDropdown('PVS1')} - - {this.setDropdown('PS1')} - {this.setDropdown('PS2')} - {this.setDropdown('PS3')} - {this.setDropdown('PS4')} - - {this.setDropdown('PM1')} - {this.setDropdown('PM2')} - {this.setDropdown('PM3')} - {this.setDropdown('PM4')} - {this.setDropdown('PM5')} - {this.setDropdown('PM6')} - - {this.setDropdown('PP1')} - {this.setDropdown('PP2')} - {this.setDropdown('PP3')} - {this.setDropdown('PP4')} - {this.setDropdown('PP5')} -
- {this.setDropdown('BA1')} - - {this.setDropdown('BS1')} - {this.setDropdown('BS2')} - {this.setDropdown('BS3')} - {this.setDropdown('BS4')} - - {this.setDropdown('BP1')} - {this.setDropdown('BP2')} - {this.setDropdown('BP3')} - {this.setDropdown('BP4')} - {this.setDropdown('BP5')} - {this.setDropdown('BP6')} - {this.setDropdown('BP7')} -
-
+
+ {interpretation ? +
+
+
+
Benign
+
+ {benign_summary && Object.keys(benign_summary).length ? + Object.keys(benign_summary).map((criteria, i) => { + return ( + + {criteria + ': '} + {benign_summary[criteria]} + {i < 2 ?     : null} + + ); + }) + : + 'No criteria met' + } +
+
+
+
+
+
Pathogenic
+
+ {path_summary && Object.keys(path_summary).length ? + Object.keys(path_summary).map((criteria, i) => { + return ( + + {criteria + ': '} + {path_summary[criteria]} + {i < 3 ?     : null} + + ); + }) + : + 'No criteria met' + } +
+
+
+
+
+
Calculated Pathogenicity
+
{result && result.assertion ? result.assertion : 'None'}
+
+
+
+ : + null + }
); - } + }, }); - diff --git a/src/clincoded/static/scss/clincoded/modules/_curator.scss b/src/clincoded/static/scss/clincoded/modules/_curator.scss index 5e35f3636..f94515830 100644 --- a/src/clincoded/static/scss/clincoded/modules/_curator.scss +++ b/src/clincoded/static/scss/clincoded/modules/_curator.scss @@ -1628,31 +1628,127 @@ dl.inline-dl { } } -.progress-bar { - width: 100%; - padding: 0 0 10px 0; +.progress-bar-area { + border-radius: 4px; + margin-bottom: 10px; + padding: 10px 0; + border: solid 1px #dddddd; + background-color: #f5f5f5; - .benign-box { - border: solid 2px #8bcd9c; - padding-left: 10px; - width: 32%; - float: left; - background-color: #fff; + div { + margin: 0; + padding: 0; + + dl { + margin: 0; + padding-left: 30px; + position: relative; + + &:before { + content: "\f058"; + font-family: 'FontAwesome'; + font-size: 18pt; + position: absolute; + left: 0; + padding: 0px; + } + + &.benign-result:before { + color: #92cd9e; + } + + &.path-result:before { + color: #f4978a; + } + + &.calculate-result:before { + content: "\f1ec"; + font-family: 'FontAwesome'; + font-size: 15pt; + color: #1b75bc; + top: 8px; + } + + dd { + font-size: 12px; + line-height: 22px; + } + + .criteria-strength { + border: none; + margin-left: 0; + padding-left: 0; + background-color: #f5f5f5; + color: #000; + cursor: text; + } + + .badge { + background-color: #b7b7b7; + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: 700; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: middle; + border-radius: 10px; + } + } } - .pathogenic-box { - border: solid 2px #d78; - padding-left: 10px; - width: 34%; - float: left; - background-color: #fff; + .benign-box { + padding-left: 1em; } .assertion-box { - border: solid 2px #1b75bc; - padding-left: 10px; - width: 34%; - float: left; - background-color: #fff; + padding-left: 0; + line-height: 20px; + } + + @media not screen and (min-width: $screen-lg-min) { + .benign-box { + padding-left: 1em; + padding-right: 1em; + } + + .path-box { + padding-left: 1em; + } + + .assertion-box { + padding-left: 4em; + } + } + + @media not screen and (min-width: $screen-md-min) { + .benign-box { + padding-left: 1em; + padding-right: 1em; + } + + .path-box { + padding-left: 1em; + } + + .assertion-box { + padding-left: 2em; + } + } + + @media not screen and (min-width: $screen-sm-min) { + padding-left: 20px; + + .assertion-box { + padding-left: 20px; + } + + .path-box { + margin-top: 15px; + margin-bottom: 15px; + } } } diff --git a/src/clincoded/static/scss/fontawesome/_icons.scss b/src/clincoded/static/scss/fontawesome/_icons.scss index 960ed356e..f8a2cfd68 100644 --- a/src/clincoded/static/scss/fontawesome/_icons.scss +++ b/src/clincoded/static/scss/fontawesome/_icons.scss @@ -516,7 +516,7 @@ //.#{$fa-css-prefix}-yelp:before { content: $fa-var-yelp; } //.#{$fa-css-prefix}-newspaper-o:before { content: $fa-var-newspaper-o; } //.#{$fa-css-prefix}-wifi:before { content: $fa-var-wifi; } -//.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; } +.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; } //.#{$fa-css-prefix}-paypal:before { content: $fa-var-paypal; } //.#{$fa-css-prefix}-google-wallet:before { content: $fa-var-google-wallet; } //.#{$fa-css-prefix}-cc-visa:before { content: $fa-var-cc-visa; }