Skip to content

SBI Pre-launch Adjustments #343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 52 additions & 4 deletions microsetta_interface/implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1991,7 +1991,8 @@ def get_source(*, account_id=None, source_id=None):


@prerequisite([SOURCE_PREREQS_MET, BIOSPECIMEN_PREREQS_MET])
def get_kits(*, account_id=None, source_id=None, check_survey_date=False):
def get_kits(*, account_id=None, source_id=None, check_survey_date=False,
sample_site=None):
# Retrieve the account
has_error, account, _ = ApiRequest.get('/accounts/%s' % account_id)
if has_error:
Expand Down Expand Up @@ -2073,6 +2074,28 @@ def get_kits(*, account_id=None, source_id=None, check_survey_date=False):

prompt_survey_update = prompt_response['prompt']

# For Cheek samples, we want to display prompt to return to the My Profile
# tab and take the Skin Scoring App external survey.
# Set a default value of False
prompt_skin_app = False
if sample_site == "Cheek":
# We need to verify that they're eligible for the app, which means
# they either already have credentials, or some are availabile. The
# business logic is handled in the API, we just need to see if the
# survey is available to the source.
has_error, surveys_output, _ = ApiRequest.get(
'/accounts/%s/sources/%s/survey_templates' % (
account_id, source_id
)
)
if has_error:
return surveys_output

for survey in surveys_output:
if survey['survey_template_id'] == SKIN_SCORING_APP_ID:
prompt_skin_app = True
break

need_reconsent_data = check_current_consent(
account_id, source_id, "data"
)
Expand All @@ -2097,7 +2120,8 @@ def get_kits(*, account_id=None, source_id=None, check_survey_date=False):
prompt_survey_id=BASIC_INFO_ID,
need_reconsent_data=need_reconsent_data,
need_reconsent_biospecimen=need_reconsent_biospecimen,
show_update_age=show_update_age
show_update_age=show_update_age,
prompt_skin_app=prompt_skin_app
)


Expand Down Expand Up @@ -2486,6 +2510,30 @@ def get_update_sample(*, account_id=None, source_id=None, sample_id=None):
sample_output['date'] = ""
sample_output['time'] = ""

if sample_output['sample_site'] == "Cheek":
# Format date and time to be JavaScript-friendly
sslwd = sample_output['barcode_meta'].get(
'sample_site_last_washed_date'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure whether these keys are guaranteed to exist as the private API can return an empty dict? If they are not assured to exist then they could they be accessed through get?

https://github.com/biocore/microsetta-private-api/blob/d9653bc1059957f8afab23c4ca804810c365255b/microsetta_private_api/repo/sample_repo.py#L423

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three keys should exist for any cheek sample, and their absence would indicate an unexpected state. However, using get doesn't hurt anything and mitigates the minimal potential for an error.

)
if sslwd is None:
sslwd = ""
sample_output['barcode_meta']['sample_site_last_washed_date'] = sslwd

sslwt = sample_output['barcode_meta'].get(
'sample_site_last_washed_time'
)
if sslwt is None:
sslwt = ""
sample_output['barcode_meta']['sample_site_last_washed_time'] = sslwt

sslwp = sample_output['barcode_meta'].get(
'sample_site_last_washed_product'
)
if sslwp is None:
sslwp = ""
sample_output['barcode_meta'][
'sample_site_last_washed_product'] = sslwp

profile_has_samples = _check_if_source_has_samples(account_id, source_id)

need_reconsent_data = check_current_consent(
Expand Down Expand Up @@ -2573,8 +2621,8 @@ def post_update_sample(*, account_id=None, source_id=None, sample_id=None):
return sample_output

return redirect(
"/accounts/%s/sources/%s/kits?check_survey_date=True" %
(account_id, source_id)
"/accounts/%s/sources/%s/kits?check_survey_date=True&sample_site=%s" %
(account_id, source_id, model['sample_site'])
)


Expand Down
10 changes: 10 additions & 0 deletions microsetta_interface/routes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ paths:
- $ref: '#/components/parameters/account_id'
- $ref: '#/components/parameters/source_id'
- $ref: '#/components/parameters/check_survey_date'
- $ref: '#/components/parameters/sample_site'
responses:
'200':
description: Display of kits for a source
Expand Down Expand Up @@ -1658,6 +1659,12 @@ components:
description: T/F flag on whether the Kits page should check user's most recent survey update date
schema:
$ref: '#/components/schemas/check_survey_date'
sample_site:
name: sample_site
in: query
description: The sample site of the last sample the user edited
schema:
$ref: '#/components/schemas/sample_site'
external_report_id:
name: external_report_id
in: path
Expand Down Expand Up @@ -1728,6 +1735,9 @@ components:
check_survey_date:
type: boolean
example: True
sample_site:
type: string
example: "Cheek"
external_report_id:
type: string
example: "b0b0b0b0-b0b0-b0b0-b0b0-b0b0b0b0b0b0"
12 changes: 12 additions & 0 deletions microsetta_interface/static/css/minimal_interface.css
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,18 @@ li.active-profile {
color: var(--tmi-blue);
}

.alert-kits {
background: var(--tmi-orange-bg);
border-left: 8px solid var(--tmi-orange);
border-radius: 12px;
color: var(--tmi-gray-90);
}

.alert-kits a {
color: var(--tmi-blue);
}


.alert-nutrition {
background: var(--tmi-orange-bg);
border-left: 8px solid var(--tmi-orange);
Expand Down
7 changes: 6 additions & 1 deletion microsetta_interface/templates/kits.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,15 @@
{% else %}
<div class="container profile-container">
{% if prompt_survey_update %}
<div class="alert alert-primary alert-nutrition mt-4" role="alert">
<div class="alert alert-primary alert-kits mt-4" role="alert">
{{ _('Thank you for logging your sample information. It looks like you haven\'t updated your profile recently. Please review') }} <a href="/accounts/{{account_id}}/sources/{{source_id}}/take_survey?survey_template_id={{prompt_survey_id}}">{{ _('your survey responses') }}</a> {{ _('to ensure they\'re as current and complete as possible.') }}
</div>
{% endif %}
{% if prompt_skin_app %}
<div class="alert alert-primary alert-kits mt-4" role="alert">
{{ _('You now have access to the Skin Scoring App survey. Please return to the') }} <a href="/accounts/{{account_id}}/sources/{{source_id}}/take_survey?survey_template_id={{prompt_survey_id}}">{{ _('My Profile tab') }}</a> {{ _('to complete it.') }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why prompt rather than redirect?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accessing the Skin Scoring App isn't a simple redirect to an external site. It requires the user to open a pop-up on our side with instructions, hit a button to be allocated credentials, then hit a button to open the external site. As such, prompting the user to access it feels cleaner from a UX perspective than redirecting them to the My Profile tab with the pop-up already opened.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. To check, does the pop up behave ok on mobile?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the formatting is responsive and I've tested it using both Firefox and Chrome's developer-mode settings for a handful of different screen sizes.

</div>
{% endif %}
{% if profile_has_samples and (need_reconsent_data or need_reconsent_biospecimen) %}
<div id="consent_alert" class="alert alert-consent mt-4" role="alert">
{{ _('To update your existing samples or contribute new samples, please review the following:') }}<br />
Expand Down
4 changes: 2 additions & 2 deletions microsetta_interface/templates/sample.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@
timeFormat: 'h:mm p',
interval: 30,
{% if sample.barcode_meta['sample_site_last_washed_time'] == "" %}
defaultTime: 'now',
defaultTime: '',
{% else %}
defaultTime: '{{ sample.barcode_meta['sample_site_last_washed_time'] }}',
{% endif %}
Expand Down Expand Up @@ -318,7 +318,7 @@
</div>
<div class="row mt-2 barcode-meta-cheek">
<div class="col-12">
<label for="sample_site_last_washed_date" name="sample_site_last_washed_date_label" class="sample-label">{{ _('When did you last wash the area that was swabbed before taking the sample?') }}*</label>
<label for="sample_site_last_washed_date" name="sample_site_last_washed_date_label" class="sample-label">{{ _('When did you last wash the area that was swabbed before taking the sample?') }}</label>
</div>
</div>
<div class="row barcode-meta-cheek">
Expand Down
7 changes: 5 additions & 2 deletions microsetta_interface/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,11 @@ def test_new_human_source_to_sample(self):
url = self.redirectURL(resp)
# Flask's client.get() function doesn't like the query string being
# attached to the url string. So we'll restructure it.
url = url.replace("?check_survey_date=True", "")
query_string = {"check_survey_date": "True"}
url = url.replace("?check_survey_date=True&sample_site=Stool", "")
query_string = {
"check_survey_date": "True",
"sample_site": "Stool"
}
resp = self.app.get(url, query_string=query_string)
self.assertPageTitle(resp, 'My Kits')

Expand Down