Skip to content

Commit

Permalink
Opt out feature - add frontend check for whether opt out is disabled …
Browse files Browse the repository at this point in the history
…for user org (#4375)

Add frontend check to determine whether user's org is in the list of
orgs that do not allow OPT OUT feature yet, i.e. via config variable,
`OPT_OUT_DISABLED_ORG_IDS`

---------

Co-authored-by: Amy Chen <clone@cesium.cirg.washington.edu>
  • Loading branch information
achen2401 and Amy Chen committed Apr 9, 2024
1 parent 0e2ed98 commit 072cfc2
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 36 deletions.
100 changes: 67 additions & 33 deletions portal/static/js/src/empro.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import EMPRO_DOMAIN_MAPPINGS from "./data/common/empro_domain_mappings.json";
import {
EPROMS_SUBSTUDY_ID,
EPROMS_SUBSTUDY_QUESTIONNAIRE_IDENTIFIER,
EMPRO_TRIGGER_STATE_OPTOUT_KEY
EMPRO_TRIGGER_STATE_OPTOUT_KEY,
} from "./data/common/consts.js";
import tnthAjax from "./modules/TnthAjax.js";
import tnthDate from "./modules/TnthDate.js";
import { CurrentUserObj } from "./mixins/CurrentUser.js";
import TestResponsesJson from "./data/common/test/SubStudyQuestionnaireTestData.json";
import TestTriggersJson from "./data/common/test/TestTriggersData.json";
import { getUrlParameter } from "./modules/Utility";
Expand All @@ -22,9 +23,11 @@ var emproObj = function () {
this.hasHardTrigger = false;
this.hasSoftTrigger = false;
this.userId = 0;
this.userOrgs = [];
this.visitMonth = 0;
this.authorDate = null;
this.cachedAccessKey = null;
this.optOutNotAllowed = false;
};
emproObj.prototype.getDomainDisplay = function (domain) {
if (!domain) return "";
Expand Down Expand Up @@ -114,7 +117,7 @@ emproObj.prototype.setOptoutSubmitData = function () {
var triggerObject = {};
EmproObj.selectedOptOutDomains.forEach((item) => {
triggerObject[item] = {
[EMPRO_TRIGGER_STATE_OPTOUT_KEY]: true,
[EMPRO_TRIGGER_STATE_OPTOUT_KEY]: true,
};
});
var submitData = {
Expand Down Expand Up @@ -299,7 +302,7 @@ emproObj.prototype.initOptOutModal = function (autoShow) {
}
$("#emproOptOutModal").modal(autoShow ? "show" : "hide");
};
emproObj.prototype.onDetectOptOutDomains = function() {
emproObj.prototype.onDetectOptOutDomains = function () {
this.populateOptoutInputItems();
this.initOptOutElementEvents();
this.initOptOutModal(true);
Expand Down Expand Up @@ -327,15 +330,42 @@ emproObj.prototype.initTriggerItemsVis = function () {
return;
}
};
emproObj.prototype.checkUserOrgAllowOptOut = function (userId, userOrgs, callback) {
callback = callback || function () {};
if (!userId || !userOrgs || !userOrgs.length) {
callback(false);
return;
}
const OPT_OUT_ORGS_KEY = "OPT_OUT_DISABLED_ORG_IDS";
// get opt out disabled orgs from setting
tnthAjax.setting(OPT_OUT_ORGS_KEY, userId, null, (data) => {
if (!data || !data[OPT_OUT_ORGS_KEY]) {
callback(false);
return;
}
const optOutDisabledOrgs = data[OPT_OUT_ORGS_KEY];
if (!optOutDisabledOrgs.length) {
callback(false);
return;
}
const orgsToCompare = optOutDisabledOrgs.map((orgId) => parseInt(orgId));
// callback return true if the userOrg is in the OPT OUT disabled org list
callback(
!!userOrgs.find((orgId) => orgsToCompare.indexOf(parseInt(orgId)) !== -1)
);
});
};
emproObj.prototype.init = function () {
tnthAjax.getCurrentUser((data) => {
if (!data || !data.id) return;
this.userId = data.id;

const self = this;
this.setLoadingVis(true);
CurrentUserObj.initCurrentUser(() => {
this.userId = CurrentUserObj.getUserId();
this.userOrgs = CurrentUserObj.getUserOrgs();
const isDebugging = getUrlParameter("debug");

this.setLoadingVis(true);

if (!this.userId || !this.userOrgs || !this.userOrgs.length) {
this.setLoadingVis(false);
return;
}
tnthAjax.getUserResearchStudies(this.userId, "patient", false, (data) => {
if (
!isDebugging &&
Expand Down Expand Up @@ -494,6 +524,7 @@ emproObj.prototype.processTriggerData = function (data) {
for (let q in data.triggers.domain[key]) {
// if sequence count >= 3, the user can choose to opt_out of respective domain
if (
!self.optOutNotAllowed &&
q === "_sequential_hard_trigger_count" &&
parseInt(data.triggers.domain[key][q]) >= 3
) {
Expand Down Expand Up @@ -529,34 +560,37 @@ emproObj.prototype.initTriggerDomains = function (params, callbackFunc) {
callback({ error: true });
return;
}
//var self = this;
const isDebugging = getUrlParameter("debug");
tnthAjax.getSubStudyTriggers(this.userId, params, (data) => {
if (isDebugging) {
data = TestTriggersJson;
}
console.log("Trigger data: ", data);
if (!data || data.error || !data.triggers || !data.triggers.domain) {
callback({ error: true, reason: "no trigger data" });
return false;
}
this.checkUserOrgAllowOptOut(this.userId, this.userOrgs, (isOptOutDisabled) => {
this.optOutNotAllowed = isOptOutDisabled;
console.log("Opt out is disabled ", isOptOutDisabled);
tnthAjax.getSubStudyTriggers(this.userId, params, (data) => {
if (isDebugging) {
data = TestTriggersJson;
}
console.log("Trigger data: ", data);
if (!data || data.error || !data.triggers || !data.triggers.domain) {
callback({ error: true, reason: "no trigger data" });
return false;
}

this.processTriggerData(data);
this.processTriggerData(data);

/*
* display user domain topic(s)
*/
this.populateDomainDisplay();
/*
* show/hide sections based on triggers
*/
this.initTriggerItemsVis();
/*
* display user domain topic(s)
*/
this.populateDomainDisplay();
/*
* show/hide sections based on triggers
*/
this.initTriggerItemsVis();

callback(data);
callback(data);

//console.log("self.domains? ", self.domains);
//console.log("has hard triggers ", self.hasHardTrigger);
//console.log("has soft triggers ", self.hasSoftTrigger);
//console.log("self.domains? ", self.domains);
//console.log("has hard triggers ", self.hasHardTrigger);
//console.log("has soft triggers ", self.hasSoftTrigger);
});
});
};
let EmproObj = new emproObj();
Expand Down
3 changes: 3 additions & 0 deletions portal/static/js/src/mixins/CurrentUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ var CurrentUser = { /* global $ i18next */
getRoleType: function() {
return this.isPatientUser()?"patient":"staff";
},
getUserResearchStudies: function() {
return this.userResearchStudyIds;
},
setUserResearchStudies: function(callback) {
callback = callback || function() {};
tnthAjax.getUserResearchStudies(this.userId, this.getRoleType(), "", data => {
Expand Down
3 changes: 2 additions & 1 deletion portal/static/js/src/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1581,8 +1581,9 @@ export default (function() {
return this.hasSubStudyTriggers() && this.getPostTxActionStatus() === "missed";
},
isPostTxActionRequired: function() {
const actionStatus = this.getPostTxActionStatus();
return this.subStudyTriggers.data &&
(["due", "overdue", "required"].indexOf(this.getPostTxActionStatus()) !== -1
(["due", "overdue", "required"].indexOf(actionStatus) !== -1
);
},
isPostTxActionNotApplicable: function() {
Expand Down
4 changes: 2 additions & 2 deletions portal/templates/profile/profile_macros.html
Original file line number Diff line number Diff line change
Expand Up @@ -890,10 +890,10 @@ <h4 class="text-muted">{% if person and person.username %}{{ _("for") + " " + pe
<div class="loader" v-show="postTxQuestionnaire.loading"><i class="fa fa-spinner fa-spin fa-2x icon"></i></div>
<!-- display trigger areas if indicated -->
<div id="triggersSection" v-if="hasSubStudyTriggers()">
<h5 class="muted" v-show="!isSubStudyTriggersResolved()">{{_("Actions Required (for Clinicians/Site Staff)")}}</h5>
<h5 class="muted" v-show="isPostTxActionRequired()">{{_("Actions Required (for Clinicians/Site Staff)")}}</h5>
<div class="item">{{_("EMPRO questionnaire completed on:")}} <span class="text" v-html="subStudyTriggers.displaydate"></span></div>
<div class="item">
<p v-if="!isSubStudyTriggersResolved()">{{_("ACTION REQUIRED for high distress areas:")}}</p>
<p v-if="isPostTxActionRequired()">{{_("ACTION REQUIRED for high distress areas:")}}</p>
<p v-else>{{_("High distress areas")}}</p>
<ul class="list">
<li v-for="item in subStudyTriggers.domains" v-text="item.replace(/_/g, ' ')" class="text"></li>
Expand Down
1 change: 1 addition & 0 deletions portal/views/portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,7 @@ def config_settings(config_key):
'LOCALIZED_AFFILIATE_ORG',
'LR_',
'MAINTENANCE_',
'OPT_OUT_DISABLED_ORG_IDS',
'PROTECTED_FIELDS',
'PROTECTED_ORG',
'PATIENT_LIST_ADDL_FIELDS',
Expand Down

0 comments on commit 072cfc2

Please sign in to comment.