Skip to content

Commit

Permalink
EDRN Data Model (CDE Explorer) support
Browse files Browse the repository at this point in the history
- Add root objects to CDE Explorer's page context so we can have them pre-sorted alphabetically
- `gdown.download` doesn't raise an exception on error but returns None as the written filename, so test for this condition and raise our own exception (wkentaro/gdown#276)
- Make `update_nodes` "public" since we expect to call this from outside the class context
- When installing the CDE explorer, put it on the EDRN CDE page, not the LabCAS page. Also make it stand out. Also, initially populate it. Also, call it the "EDRN Data Model", not the "LabCAS CDEs"
- Make required CDEs stand out with color and icon
- Move the "Update from Google Drive" button appear next to the "View Update Log" button
- Hide the "Attributes" heading entirely if there are no attributes
  • Loading branch information
nutjob4life committed Aug 2, 2023
1 parent 74aa5a6 commit f35e547
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 24 deletions.
15 changes: 12 additions & 3 deletions src/edrnsite.content/src/edrnsite/content/_explorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ class CDEExplorerPage(Page):

content_panels = Page.content_panels + [FieldPanel('spreadsheet_id')]

def get_context(self, request: HttpRequest, *args, **kwargs) -> dict:
context = super().get_context(request, args, kwargs)
context['root_objects'] = self.root_objects.all().order_by('name')
return context

def _log(self, message):
'''Log a timestampped message to our update log and also to the _logger.'''
_logger.warning(message)
Expand All @@ -92,7 +97,11 @@ def _read_sheet(self, url):
os.close(fd)
self._log(f'Downloading {self.spreadsheet_id} from Gdrive')
# use_cookies must be False to work on tumor.jpl.nasa.gov
gdown.download(id=self.spreadsheet_id, output=fn, quiet=True, use_cookies=False, format='xlsx')
fn = gdown.download(id=self.spreadsheet_id, output=fn, quiet=True, use_cookies=False, format='xlsx')
# gdown doesn't raise an exception on error, but returns None as the filename—even when we pass
# in the filename we want to use; see wkentaro/gdown#276
if fn is None:
raise ValueError('Error reading from gdown; check console log as gdown does not pass this info along')
return fn

def _parse_attributes(self, name, sheet):
Expand Down Expand Up @@ -148,7 +157,7 @@ def _parse_structure(self, sheet):
self._log(f'Total root objects: {len(roots)}: {", ".join([i.name for i in roots])}')
return roots

def _update_nodes(self):
def update_nodes(self):
'''Update the CDE nodes of this page.
⚠️ Not re-entrant!
Expand Down Expand Up @@ -189,7 +198,7 @@ def serve(self, request: HttpRequest) -> HttpResponse:
if request.GET.get('update') == 'true':
if request.user.is_staff or request.user.is_superuser:
if self.spreadsheet_id:
return HttpResponseRedirect(self._update_nodes())
return HttpResponseRedirect(self.update_nodes())
else:
# No way to get here unless you have permissions and manually craft the request
return HttpResponse("No spreadsheet ID defined")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,25 @@ def _append_link_to_page(self, dest, link_text, page):
dest.body.append(('rich_text', RichText(block['value'])))
else:
raise ValueError(f'Unexpected block type {block["type"]}')
dest.body.append(('rich_text', RichText(f'<p><a id="{page.pk}" linktype="page">{link_text}</a></p>')))
dest.body.append(('rich_text', RichText(f'<p><strong>New</strong>: explore the <a id="{page.pk}" linktype="page">{link_text}</a>.</p>')))
dest.save()

def _install_cde_explorer(self, home_page):
self.stdout.write('Installing the official CDE Explorer')

CDEExplorerPage.objects.all().delete()
dest = FlexPage.objects.descendant_of(home_page).filter(slug='labcas-metadata-and-common-data-elements').first()
dest = FlexPage.objects.descendant_of(home_page).filter(slug='cde').first()
assert dest is not None

page = CDEExplorerPage(
title='LabCAS CDEs', live=True, show_in_menus=False,
spreadsheet_id='1xrtQkEO0kkuJQbK7cqQR70sep_prsL_X3vvCU-dT3a0',
search_description='A tree-like explorer of the Common Data Elements (CDEs) of LabCAS.',
title='EDRN Data Model', live=True, show_in_menus=False,
spreadsheet_id='1PAVUvmi0J-j6fK5dpltRIW8vRzVjh4kzpNReGFOQIe4',
search_description='A tree-like explorer of the Common Data Elements (CDEs) of the Early Detection Research Network.',
)
dest.add_child(instance=page)
page.save()
self._append_link_to_page(dest, 'LabCAS CDE Explorer', page)
page.update_nodes()
self._append_link_to_page(dest, 'EDRN Data Model', page)

def handle(self, *args, **options):
self.stdout.write('Installing explorers')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% load wagtailcore_tags edrnsite_content_tags %}
<a class='btn btn-outline-primary btn-sm' data-bs-toggle='offcanvas' href='#{{id}}' role='button'
<a class='btn btn-sm{% if required %} btn-outline-danger{% else %} btn-outline-primary{% endif %}'
data-bs-toggle='offcanvas' href='#{{id}}' role='button'
data-bs-target='#{{id}}' aria-controls='{{id}}'>
{{text}}
{% if required %}<i class='bi bi-key-fill'></i>{% endif %} {{text}}
</a>
{# -*- Django HTML -*- #}
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,14 @@
{% block content %}
<div class='row'>
<div class='col-md-12'>
{% if request.user.is_staff or request.user.is_superuser %}
{% if page.spreadsheet_id %}
<div class='float-end'>
<a href='{{page.url}}?update=true' role='button' class='btn btn-primary'>Update from Google Drive</a>
</div>
{% endif %}
{% endif %}
<h1>{{page.title}}</h1>
</div>
{% if request.user.is_staff or request.user.is_superuser %}
{% if page.spreadsheet_id %}
<div class='row'>
<div class='col-md-12'>
<p>
<a href='{{page.url}}?update=true' role='button' class='btn btn-primary'>Update from Google Drive</a>
<a class='btn btn-primary' data-bs-toggle='collapse' href='#log-file' role='button'
aria-expanded='false' aria-controls='log-file'>
View Update Log
Expand Down Expand Up @@ -57,7 +51,7 @@ <h1>{{page.title}}</h1>
<div class='row mb-3'>
<div id='jstree_goes_here' class='col-sm-6 col-md-6'>
<ul>
{% for root in page.root_objects.all %}
{% for root in root_objects %}
{% render_cde_node root %}
{% endfor %}
</ul>
Expand Down Expand Up @@ -98,6 +92,9 @@ <h1>{{page.title}}</h1>
'search': {
'fuzzy': true
}
})
.bind('loaded.jstree', function(e, data) {
$(this).jstree('open_all');
});
// 🔮 TODO: add search box
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ <h3>{{name}}</h3>
<p class='small'>(No description of this object is available.)</p>
{% endif %}

<h4>Attributes</h4>
{% if attributes %}
<h4>Attributes</h4>
<p class='small'>Attributes shown with <i class='text-danger bi bi-key-fill'></i> are <em>required</em>.</p>
<p style='line-height: 2rem;'>
{% for attribute in attributes %}
{% render_cde_attribute_button attribute %}
{% endfor %}
</p>
{% else %}
<p class='small'>(This object has no attributes defined at this time.)</p>
{% endif %}
</div>
{% if children %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ def render_cde_node(node: CDEExplorerObject) -> dict:
'name': node.name,
'description': node.description,
'attributes': node.attributes.all(),
'children': node.children.all()
'children': node.children.all().order_by('name')
}


@register.inclusion_tag('edrnsite.content/cde-attribute-button.html', takes_context=False)
def render_cde_attribute_button(attribute: CDEExplorerAttribute) -> dict:
return {
'id': f'cde-{slugify(attribute.obj.name)}-{slugify(attribute.text)}',
'text': attribute.text
'text': attribute.text,
'required': attribute.required == 'Required'
}


Expand Down

0 comments on commit f35e547

Please sign in to comment.