Skip to content
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

Make Create Project Flow descriptions configurable #2198

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
10 changes: 9 additions & 1 deletion physionet-django/console/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.utils import timezone
from google.cloud import storage
from notification.models import News
from physionet.models import FrontPageButton, Section, StaticPage
from physionet.models import FrontPageButton, Section, StaticPage, StepDetails
from project.models import (
ActiveProject,
AccessPolicy,
Expand Down Expand Up @@ -997,3 +997,11 @@ class Meta:
model = CodeOfConduct
fields = ('name', 'version', 'slug', 'html_content')
labels = {'html_content': 'Content'}


class StepDetailsForm(forms.ModelForm):
""" Form for creating a dynamic static page."""

class Meta:
model = StepDetails
fields = ("title", "content", "slug", "tip")
2 changes: 2 additions & 0 deletions physionet-django/console/navbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,5 +216,7 @@ def get_menu_items(self, request):
NavLink(_('Redirects'), 'redirects'),
]),

NavLink(_('Process Pages'), 'process_pages', 'window-minimize'),

NavLink(_('News'), 'news_console', 'newspaper'),
])
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{% extends "console/base_console.html" %}

{% load project_templatetags %}

{% block title %}Process Pages{% endblock %}

{% block content %}
<div class="card mb-3">
<div class="card-header">
Process Pages <span class="badge badge-pill badge-info">{{ pages|length }}</span>
</div>
<div class="card-body">

<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Process</th>
<th class="text-center" colspan=3>Actions</th>
</tr>
</thead>
<tbody>
{% for process in processes %}
<tr>
<td>{{ process.title }}</td>
<td class="text-center">
<a href="{% url 'process_pages_show' process.slug %}" class="btn btn-sm btn-primary" role="button">Manage</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
36 changes: 36 additions & 0 deletions physionet-django/console/templates/console/process_pages/show.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{% extends "console/base_console.html" %}

{% load project_templatetags %}

{% block title %}Static Pages{% endblock %}

{% block content %}
<div class="card mb-3">
<div class="card-header">
{{ process_name }} Flow <span class="badge badge-pill badge-info">{{ pages|length }}</span>
</div>
<div class="card-body">

<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Page</th>
<th class="text-center" colspan=3>Actions</th>
</tr>
</thead>
<tbody>
{% for step in steps %}
<tr>
<td>{{ step.title|title }}</td>
<td class="text-center">
<a href="{% url 'step_details_show' step.pk %}" class="btn btn-sm btn-primary" role="button">Manage</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% extends "console/base_console.html" %}

{% load project_templatetags %}

{% block title %}{{ page.title }} - edit {% endblock %}

{% block content %}
<div class="card mb-3">
<div class="card-header">
{{ step_detail.title }} - edit
</div>
<div class="card-body">
<form method="post" action="{% url 'step_details_edit' step_detail.pk %}">
{% include "inline_form_snippet.html" with form=step_details_form %}
<button class="btn btn-primary btn-fixed" type="submit">Save</button>
</form>
</div>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% extends "console/base_console.html" %}

{% load project_templatetags %}

{% block title %}Static Pages{% endblock %}

{% block content %}
<div class="card mb-3">
<div class="card-header">
{{ step }} <span class="badge badge-pill badge-info">{{ pages|length }}</span>
</div>
<div class="card-body">

<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Page</th>
<th class="text-center" colspan=3>Actions</th>
</tr>
</thead>
<tbody>
{% for detail in step_details %}
<tr>
<td>{{ detail.title|title }}</td>
<td class="text-center">
<a href="{% url 'step_details_edit' detail.pk %}" class="btn btn-sm btn-primary" role="button">Manage</a>
</td>
<td class="text-center">
<form method="post" action="{% url 'step_details_delete' detail.pk %}" onsubmit="return confirm ('Are you sure? ')">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-danger" role="button">Remove</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</div>
<div class="card-body">
<form method="post" action="{% url 'static_page_edit' page.pk %}">
{% include "descriptive_inline_form_snippet.html" with form=static_page_form %}
{% include "inline_form_snippet.html" with form=static_page_form %}
<button class="btn btn-primary btn-fixed" type="submit">Save</button>
</form>
</div>
Expand Down
13 changes: 13 additions & 0 deletions physionet-django/console/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@
views.static_page_sections_edit,
name='static_page_sections_edit',
),

# create project pages
path('process_pages/', views.process_pages, name='process_pages'),
path('process_pages/<process_slug>/show/', views.process_pages_show, name='process_pages_show'),
path('process_pages/step_details/<int:step_pk>/show/', views.step_details_show, name='step_details_show'),
path('process_pages/step_details/<int:step_details_pk>/edit/', views.step_details_edit, name='step_details_edit'),
path('process_pages/step_details/<int:step_details_pk>/delete/',
views.step_details_delete, name='step_details_delete'),

path('licenses/', views.license_list, name='license_list'),
path('licenses/<int:pk>/', views.license_detail, name='license_detail'),
path('licenses/<int:pk>/delete/', views.license_delete, name='license_delete'),
Expand Down Expand Up @@ -181,9 +190,13 @@
'news_id': 1,
'username': 'rgmark',
'news_slug': 'cloud-migration',
'process_slug': 'create_project',
'version': '1.0',
'training_slug': 'world-101-introduction-to-continents-and-countries',
'step_pk': 1,
'step_details_pk': 1,
}

TEST_CASES = {
'manage_published_project': {
'project_slug': 'demoeicu',
Expand Down
72 changes: 71 additions & 1 deletion physionet-django/console/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from physionet.forms import set_saved_fields_cookie
from physionet.middleware.maintenance import ServiceUnavailable
from physionet.utility import paginate
from physionet.models import FrontPageButton, Section, StaticPage
from physionet.models import FrontPageButton, Section, StaticPage, Process, Step, StepDetails
from project import forms as project_forms
from project.models import (
GCP,
Expand Down Expand Up @@ -2861,6 +2861,76 @@ def static_page_sections_edit(request, page_pk, section_pk):
)


@console_permission_required('physionet.change_staticpage')
def process_pages(request):
"""
Display a list of redirected URLs.
"""
# Get the list of all the available process_names
processes = Process.objects.all()
return render(
request,
'console/process_pages/index.html',
{'processes': processes})


@console_permission_required('physionet.change_staticpage')
def process_pages_show(request, process_slug):
"""
Display a list of redirected URLs.
"""
process = Process.objects.get(slug=process_slug)
steps = Step.objects.filter(process=process).order_by('order')
return render(
request,
'console/process_pages/show.html',
{'steps': steps, 'process_name': process.title})


@console_permission_required('physionet.change_staticpage')
def step_details_show(request, step_pk):
"""
Display a list of redirected URLs.
"""
step = get_object_or_404(Step, pk=step_pk)
step_details = StepDetails.objects.filter(step=step)
print(step_details)
return render(
request,
'console/process_pages/step_details/index.html',
{'step': step, 'step_details': step_details})


@console_permission_required('physionet.change_staticpage')
def step_details_edit(request, step_details_pk):
"""
Display a list of redirected URLs.
"""
step_detail = get_object_or_404(StepDetails, pk=step_details_pk)
if request.method == 'POST':
step_details_form = forms.StepDetailsForm(instance=step_detail, data=request.POST)
if step_details_form.is_valid():
step_details_form.save()
messages.success(request, f'The {step_detail} section was successfully edited.')
return HttpResponseRedirect(reverse('process_pages'))
else:
step_details_form = forms.StepDetailsForm(instance=step_detail)

return render(
request,
'console/process_pages/step_details/edit.html',
{'step_detail': step_detail, 'step_details_form': step_details_form})


@console_permission_required('physionet.change_staticpage')
def step_details_delete(request, step_details_pk):
step_detail = get_object_or_404(StepDetails, pk=step_details_pk)
if request.method == 'POST':
step_detail.delete()
messages.success(request, f'The {step_detail} section was successfully deleted.')

return HttpResponseRedirect(reverse('process_pages'))

@console_permission_required('project.add_license')
def license_list(request):
if request.method == 'POST':
Expand Down
1 change: 1 addition & 0 deletions physionet-django/physionet/fixtures/project_copy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"model": "physionet.process", "pk": 1, "fields": {"title": "Create Project", "slug": "create_project", "description": "Create a new project on Health Data Nexus."}}, {"model": "physionet.step", "pk": 1, "fields": {"title": "Overview", "process": 1, "slug": "create_project_overview", "order": 1}}, {"model": "physionet.step", "pk": 2, "fields": {"title": "Authors", "process": 1, "slug": "create_project_authors", "order": 2}}, {"model": "physionet.step", "pk": 3, "fields": {"title": "Content", "process": 1, "slug": "create_project_content", "order": 3}}, {"model": "physionet.step", "pk": 4, "fields": {"title": "Access", "process": 1, "slug": "create_project_access", "order": 4}}, {"model": "physionet.step", "pk": 5, "fields": {"title": "Discovery", "process": 1, "slug": "create_project_discovery", "order": 5}}, {"model": "physionet.step", "pk": 6, "fields": {"title": "Ethics", "process": 1, "slug": "create_project_ethics", "order": 6}}, {"model": "physionet.step", "pk": 7, "fields": {"title": "Files", "process": 1, "slug": "create_project_files", "order": 7}}, {"model": "physionet.step", "pk": 8, "fields": {"title": "Proofread", "process": 1, "slug": "create_project_proofread", "order": 8}}, {"model": "physionet.stepdetails", "pk": 1, "fields": {"title": "Preparing for Submission", "content": "<p>To prepare the project for submission, go through the following steps using the side panel:</p>\n <ol>\n <li>Invite authors to be credited for creating the resource.</li>\n <li>Fill in the descriptive metadata.</li>\n <li>Set the access policy and license.</li>\n <li>Add discovery information.</li>\n <li>Upload the files.</li>\n <li>Proofread the project and make sure it is ready for submission.</li>\n</ol> <p>The full publishing process is described in the\n <a href=\"{% url 'static_view' static_url='publish' %}#author_guidelines\"> author\nguidelines</a>.</p>", "order": 1, "step": 1, "slug": "preparing_for_submission", "tip": false}}, {"model": "physionet.stepdetails", "pk": 2, "fields": {"title": "Project Authors", "content": "<p>The submitting author is responsible for managing co-authors and handling the project\n submission. Co-authors can be invited using the form below. Once the co-author is registered on {{ SITE_NAME }}, \n the invitation will appear on their <a href=\"{% url 'project_home' %}\" target=\"_blank\">project home</a> page. Authors must provide their affiliation on a project-by-project basis.</p>\n", "order": 1, "step": 2, "slug": "project_authors", "tip": false}}, {"model": "physionet.stepdetails", "pk": 3, "fields": {"title": "Corresponding Author", "content": "<p>The corresponding author is responsible for responding to inquiries from users post publication.</p>", "order": 2, "step": 2, "slug": "corresponding_author", "tip": false}}, {"model": "physionet.stepdetails", "pk": 4, "fields": {"title": "Corresponding Email", "content": "<p>You are the selected corresponding author. Choose one of your emails to be listed for correspondence.</p>\n", "order": 3, "step": 2, "slug": "corresponding_email", "tip": false}}, {"model": "physionet.stepdetails", "pk": 5, "fields": {"title": "Your Affiliations", "content": "<p>Set up to three affiliations for your author profile. Note: these fields are not tied to your user profile.</p>\n", "order": 4, "step": 2, "slug": "your_affiliations", "tip": false}}, {"model": "physionet.stepdetails", "pk": 6, "fields": {"title": "Your Affiliations", "content": "Institutions you are affiliated with. Maximum of 3.", "order": 5, "step": 2, "slug": "your_affiliations_tip", "tip": true}}, {"model": "physionet.stepdetails", "pk": 7, "fields": {"title": "Submitting Author", "content": "<p>Only the submitting author of a project is able to edit content.\n You may transfer the role of submitting author to a co-author.\n Choose one of the co-authors below to make them the submitting author for this project.\n Transferring authorship will remove your ability to edit content!</p>", "order": 6, "step": 2, "slug": "submitting_author", "tip": false}}, {"model": "physionet.stepdetails", "pk": 8, "fields": {"title": "Project Content", "content": "<p>Describe the context of your resource, the organization of its files, and how it is to be reused.</p> <br> <p>Please adhere to the standards specified in the helpstrings. Required fields are indicated by a *.", "order": 1, "step": 3, "slug": "project_content", "tip": false}}, {"model": "physionet.stepdetails", "pk": 9, "fields": {"title": "Project Access", "content": "<p>Set the access policy and terms of reuse for your resource. The descriptive metadata of all published projects are publically visible. The following access policies control access to the files:</p>\n\n<ul>\n\t<li><strong>Open</strong>: Anyone can access the files, as long as they conform to the terms of the specified license.</li>\n\t<li><strong>Restricted</strong>: Only logged in users who sign a data use agreement (DUA) for the project can access the files.</li>\n\t<li><strong>Credentialed</strong>: Only Health Data Nexus credentialed users who sign a DUA for the project can access the files. This tier is only for sensitive databases. Please <a href=\"/about/#contact_us\">contact us</a> beforehand if you would like to contribute such a resource.</li>\n</ul>\n\n<p>We strongly encourage selecting the open access policy.</p>", "order": 1, "step": 4, "slug": "project_access", "tip": false}}, {"model": "physionet.stepdetails", "pk": 10, "fields": {"title": "Project Discovery", "content": "<p>Add information to increase your project's discoverability.</p>", "order": 1, "step": 5, "slug": "project_discovery", "tip": false}}, {"model": "physionet.stepdetails", "pk": 11, "fields": {"title": "Ethics", "content": "<p>Please provide an ethics statement following the <a href=\"/about/publish/#author_guidelines\">author guidelines</a>. Statements on ethics approval should appear here. Your statement will be included in the public project description.</p>", "order": 1, "step": 6, "slug": "project_ethics", "tip": false}}, {"model": "physionet.stepdetails", "pk": 12, "fields": {"title": "Supporting Documentation", "content": "<p>You may upload supporting documents here. These documents will be reviewed by our editorial staff, but they will not be shared publicly. For further guidance, please refer to our <a href=\"/about/publish/#author_guidelines\">author guidelines</a>.</p>", "order": 2, "step": 6, "slug": "supporting_documentation", "tip": false}}, {"model": "physionet.stepdetails", "pk": 13, "fields": {"title": "Project Files", "content": "<p>Health Data Nexus resources should be reusable by the greater scientific community. To facilitate the reuse of your content, please adhere to the following reusability guidelines.</p>\n\n<p><strong>General Guidelines</strong></p>\n\n<ul>\n\t<li>Files must contain no&nbsp;<a href=\"https://www.hhs.gov/hipaa/for-professionals/privacy/special-topics/de-identification/index.html\">protected health information</a>.</li>\n\t<li>Files are provided in an open format such as text, csv, or WFDB, rather than a proprietary format.</li>\n\t<li>Code must be provided in source format.</li>\n\t<li>Data files must be machine readable.</li>\n\t<li>Large regularly-sampled time-series data, especially waveforms, are provided in WFDB format.</li>\n\t<li>Filenames must only contain letters, numbers, dashes, underscores, and dots.</li>\n\t<li>If appropriate, provide a csv file named&nbsp;<em>subject-info.csv</em>&nbsp;containing information on all subjects, such as age and gender.</li>\n</ul>\n\n<p><strong>WFDB Files</strong></p>\n\n<ul>\n\t<li>Provide a list of all WFDB format records, named&nbsp;<em>RECORDS</em>.&nbsp;<a href=\"https://storage.googleapis.com/healthdatanexus-prod-hdn-static/published-projects/mitdb/1.0.0/RECORDS\">Example file</a>.&nbsp;<em>If you upload this file, you will see a link to view your project&#39;s waveforms in LightWAVE</em>.</li>\n\t<li>Provide a tab delimited list of all WFDB format annotation files, named&nbsp;<em>ANNOTATORS</em>.&nbsp;<a href=\"https://storage.googleapis.com/healthdatanexus-prod-hdn-static/published-projects/mitdb/1.0.0/ANNOTATORS\">Example file</a>.</li>\n</ul>", "order": 1, "step": 7, "slug": "project_files", "tip": false}}, {"model": "physionet.stepdetails", "pk": 14, "fields": {"title": "Proofread", "content": "<p>Inspect the preview of the published project, and ensure that all authors are satisfied with the content. Any errors that are displayed must be addressed before the project can be submitted for review.</p>", "order": 1, "step": 8, "slug": "project_proofread", "tip": false}}]
22 changes: 22 additions & 0 deletions physionet-django/physionet/fixtures/sections.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"model": "physionet.staticpage",
"pk": 5,
"fields": {
"title": "Create Project Overview",
"url": "/project/:id/overview/",
"nav_bar": false,
"nav_order": 5
}
},
{
"model": "physionet.section",
"pk": 15,
"fields": {
"static_page": 5,
"title": "Preparing for Submission",
"content": "<p>To prepare the project for submission, go through the following steps using the side panel:</p>\n <ol>\n <li>Invite authors to be credited for creating the resource.</li>\n <li>Fill in the descriptive metadata.</li>\n <li>Set the access policy and license.</li>\n <li>Add discovery information.</li>\n <li>Upload the files.</li>\n <li>Proofread the project and make sure it is ready for submission.</li>\n</ol> <p>The full publishing process is described in the\n <a href=\"{% url 'static_view' static_url='publish' %}#author_guidelines\"> author\nguidelines</a>.</p>",
"order": 1
}
}
]
Loading
Loading