From 0ef64e6e88362d4a342e5fe64e853d02c1059637 Mon Sep 17 00:00:00 2001 From: matkaczmarek Date: Fri, 23 Feb 2024 14:37:36 +0100 Subject: [PATCH 01/10] Create PoC solution [T-CAIREM 1137] --- physionet-django/console/forms.py | 10 +- physionet-django/console/navbar.py | 2 + .../console/process_pages/index.html | 42 +++++ .../templates/console/process_pages/show.html | 42 +++++ .../process_pages/step_details/edit.html | 19 +++ .../process_pages/step_details/index.html | 42 +++++ .../templates/console/static_page/edit.html | 2 +- physionet-django/console/urls.py | 7 + physionet-django/console/views.py | 57 ++++++- .../physionet/fixtures/sections.json | 22 +++ .../physionet/fixtures/steps.json | 160 ++++++++++++++++++ ..._step_alter_section_options_stepdetails.py | 47 +++++ physionet-django/physionet/models.py | 45 ++++- .../templates/project/project_authors.html | 2 +- .../templates/project/project_overview.html | 16 +- physionet-django/project/views.py | 10 +- .../commands/test_add_new_sections.py | 34 ++++ 17 files changed, 541 insertions(+), 18 deletions(-) create mode 100644 physionet-django/console/templates/console/process_pages/index.html create mode 100644 physionet-django/console/templates/console/process_pages/show.html create mode 100644 physionet-django/console/templates/console/process_pages/step_details/edit.html create mode 100644 physionet-django/console/templates/console/process_pages/step_details/index.html create mode 100644 physionet-django/physionet/fixtures/sections.json create mode 100644 physionet-django/physionet/fixtures/steps.json create mode 100644 physionet-django/physionet/migrations/0008_step_alter_section_options_stepdetails.py create mode 100644 physionet-django/user/management/commands/test_add_new_sections.py diff --git a/physionet-django/console/forms.py b/physionet-django/console/forms.py index 943bd5c33f..b07dff1dcc 100644 --- a/physionet-django/console/forms.py +++ b/physionet-django/console/forms.py @@ -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, @@ -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", "tip") diff --git a/physionet-django/console/navbar.py b/physionet-django/console/navbar.py index 00ab1a0843..99199e41ee 100644 --- a/physionet-django/console/navbar.py +++ b/physionet-django/console/navbar.py @@ -214,5 +214,7 @@ def get_menu_items(self, request): NavLink(_('Redirects'), 'redirects'), ]), + NavLink(_('Process Pages'), 'process_pages', 'window-minimize'), + NavLink(_('News'), 'news_console', 'newspaper'), ]) diff --git a/physionet-django/console/templates/console/process_pages/index.html b/physionet-django/console/templates/console/process_pages/index.html new file mode 100644 index 0000000000..051de66673 --- /dev/null +++ b/physionet-django/console/templates/console/process_pages/index.html @@ -0,0 +1,42 @@ +{% extends "console/base_console.html" %} + +{% load project_templatetags %} + +{% block title %}Create Project Pages{% endblock %} + +{% block content %} +
+
+ Create Project Pages {{ pages|length }} +
+
+ +
+ + + + + + + + + {% for process in processes %} + + + + + + {% endfor %} + +
PageActions
{{ process.process_name|title }} + Manage + +
+ {% csrf_token %} + +
+
+
+
+
+{% endblock %} diff --git a/physionet-django/console/templates/console/process_pages/show.html b/physionet-django/console/templates/console/process_pages/show.html new file mode 100644 index 0000000000..1f3275a75e --- /dev/null +++ b/physionet-django/console/templates/console/process_pages/show.html @@ -0,0 +1,42 @@ +{% extends "console/base_console.html" %} + +{% load project_templatetags %} + +{% block title %}Static Pages{% endblock %} + +{% block content %} +
+
+ {{ process_name }} {{ pages|length }} +
+
+ +
+ + + + + + + + + {% for step in steps %} + + + + + + {% endfor %} + +
PageActions
{{ step.title|title }} + Manage + +
+ {% csrf_token %} + +
+
+
+
+
+{% endblock %} diff --git a/physionet-django/console/templates/console/process_pages/step_details/edit.html b/physionet-django/console/templates/console/process_pages/step_details/edit.html new file mode 100644 index 0000000000..d734a85951 --- /dev/null +++ b/physionet-django/console/templates/console/process_pages/step_details/edit.html @@ -0,0 +1,19 @@ +{% extends "console/base_console.html" %} + +{% load project_templatetags %} + +{% block title %}{{ page.title }} - edit {% endblock %} + +{% block content %} +
+
+ {{ step_detail.title }} - edit +
+
+
+ {% include "inline_form_snippet.html" with form=step_details_form %} + +
+
+
+{% endblock %} diff --git a/physionet-django/console/templates/console/process_pages/step_details/index.html b/physionet-django/console/templates/console/process_pages/step_details/index.html new file mode 100644 index 0000000000..cde979a444 --- /dev/null +++ b/physionet-django/console/templates/console/process_pages/step_details/index.html @@ -0,0 +1,42 @@ +{% extends "console/base_console.html" %} + +{% load project_templatetags %} + +{% block title %}Static Pages{% endblock %} + +{% block content %} +
+
+ Static Pages {{ pages|length }} +
+
+ +
+ + + + + + + + + {% for detail in step_details %} + + + + + + {% endfor %} + +
PageActions
{{ detail.title|title }} + Manage + +
+ {% csrf_token %} + +
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/physionet-django/console/templates/console/static_page/edit.html b/physionet-django/console/templates/console/static_page/edit.html index 3bbee2d1ee..c9db0948e8 100644 --- a/physionet-django/console/templates/console/static_page/edit.html +++ b/physionet-django/console/templates/console/static_page/edit.html @@ -11,7 +11,7 @@
- {% include "descriptive_inline_form_snippet.html" with form=static_page_form %} + {% include "inline_form_snippet.html" with form=static_page_form %}
diff --git a/physionet-django/console/urls.py b/physionet-django/console/urls.py index dd0533d6b7..22cd5853f2 100644 --- a/physionet-django/console/urls.py +++ b/physionet-django/console/urls.py @@ -128,6 +128,13 @@ 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//show/', views.process_pages_show, name='process_pages_show'), + path('process_pages/step_details//show/', views.step_details_show, name='step_details_show'), + path('process_pages/step_details//edit/', views.step_details_edit, name='step_details_edit'), + path('licenses/', views.license_list, name='license_list'), path('licenses//', views.license_detail, name='license_detail'), path('licenses//delete/', views.license_delete, name='license_delete'), diff --git a/physionet-django/console/views.py b/physionet-django/console/views.py index c036a3a21c..c2d7ab89ff 100644 --- a/physionet-django/console/views.py +++ b/physionet-django/console/views.py @@ -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, Step, StepDetails from project import forms as project_forms from project.models import ( GCP, @@ -2850,6 +2850,61 @@ def static_page_sections_edit(request, page_pk, section_pk): {'section_form': section_form, 'page': static_page, 'section': section}, ) +@console_permission_required('physionet.change_staticpage') +def process_pages(request): + """ + Display a list of redirected URLs. + """ + processes_name = Step.objects.all().distinct('process_name').order_by('process_name') + return render( + request, + 'console/process_pages/index.html', + {'processes': processes_name}) + +@console_permission_required('physionet.change_staticpage') +def process_pages_show(request, step_pk): + """ + Display a list of redirected URLs. + """ + step = get_object_or_404(Step, pk=step_pk) + steps = Step.objects.filter(process_name=step.process_name) + return render( + request, + 'console/process_pages/show.html', + {'steps': steps, 'process_name': step.process_name}) + +@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, "The static page was successfully edited.") + return HttpResponseRedirect(reverse('static_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('project.add_license') def license_list(request): diff --git a/physionet-django/physionet/fixtures/sections.json b/physionet-django/physionet/fixtures/sections.json new file mode 100644 index 0000000000..47d7c6d837 --- /dev/null +++ b/physionet-django/physionet/fixtures/sections.json @@ -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": "

To prepare the project for submission, go through the following steps using the side panel:

\n
    \n
  1. Invite authors to be credited for creating the resource.
  2. \n
  3. Fill in the descriptive metadata.
  4. \n
  5. Set the access policy and license.
  6. \n
  7. Add discovery information.
  8. \n
  9. Upload the files.
  10. \n
  11. Proofread the project and make sure it is ready for submission.
  12. \n

The full publishing process is described in the\n author\nguidelines.

", + "order": 1 + } +} +] \ No newline at end of file diff --git a/physionet-django/physionet/fixtures/steps.json b/physionet-django/physionet/fixtures/steps.json new file mode 100644 index 0000000000..dba752a08a --- /dev/null +++ b/physionet-django/physionet/fixtures/steps.json @@ -0,0 +1,160 @@ +[ +{ + "model": "physionet.step", + "pk": 1, + "fields": { + "title": "Overview", + "process_name": "Create Project", + "order": 1 + } +}, +{ + "model": "physionet.step", + "pk": 2, + "fields": { + "title": "Authors", + "process_name": "Create Project", + "order": 2 + } +}, +{ + "model": "physionet.step", + "pk": 3, + "fields": { + "title": "Content", + "process_name": "Create Project", + "order": 3 + } +}, +{ + "model": "physionet.step", + "pk": 4, + "fields": { + "title": "Access", + "process_name": "Create Project", + "order": 4 + } +}, +{ + "model": "physionet.step", + "pk": 5, + "fields": { + "title": "Discovery", + "process_name": "Create Project", + "order": 5 + } +}, +{ + "model": "physionet.step", + "pk": 6, + "fields": { + "title": "Ethics", + "process_name": "Create Project", + "order": 6 + } +}, +{ + "model": "physionet.step", + "pk": 7, + "fields": { + "title": "Files", + "process_name": "Create Project", + "order": 7 + } +}, +{ + "model": "physionet.step", + "pk": 8, + "fields": { + "title": "Proofread", + "process_name": "Create Project", + "order": 8 + } +}, +{ + "model": "physionet.step", + "pk": 9, + "fields": { + "title": "Submission", + "process_name": "Create Project", + "order": 9 + } +}, +{ + "model": "physionet.stepdetails", + "pk": 1, + "fields": { + "step": 1, + "title": "Preparing for Submission", + "content": "

To prepare the project for submission, go through the following steps using the side panel:

\n
    \n
  1. Invite authors to be credited for creating the resource.
  2. \n
  3. Fill in the descriptive metadata.
  4. \n
  5. Set the access policy and license.
  6. \n
  7. Add discovery information.
  8. \n
  9. Upload the files.
  10. \n
  11. Proofread the project and make sure it is ready for submission.
  12. \n

The full publishing process is described in the\n author\nguidelines.

", + "order": 1, + "tip": false + } +}, +{ + "model": "physionet.stepdetails", + "pk": 2, + "fields": { + "step": 2, + "title": "1. Project Authors", + "content": "

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 project home page. Authors must provide their affiliation on a project-by-project basis.

\n", + "order": 1, + "tip": false + } +}, +{ + "model": "physionet.stepdetails", + "pk": 3, + "fields": { + "step": 2, + "title": "Corresponding Author", + "content": "

The corresponding author is responsible for responding to inquiries from users post publication.

", + "order": 2, + "tip": false + } +}, +{ + "model": "physionet.stepdetails", + "pk": 4, + "fields": { + "step": 2, + "title": "Corresponding Email", + "content": "

You are the the selected corresponding author. Choose one of your emails to be listed for correspondence.

\n", + "order": 3, + "tip": false + } +}, +{ + "model": "physionet.stepdetails", + "pk": 5, + "fields": { + "step": 2, + "title": "Your Affiliations", + "content": "

Set up to three affiliations for your author profile. Note: these fields are not tied to your user profile.

\n", + "order": 4, + "tip": false + } +}, +{ + "model": "physionet.stepdetails", + "pk": 6, + "fields": { + "step": 2, + "title": "Your Affiliations", + "content": "Institutions you are affiliated with. Maximum of 3.", + "order": 5, + "tip": true + } +}, +{ + "model": "physionet.stepdetails", + "pk": 7, + "fields": { + "step": 2, + "title": "Submitting Author", + "content": "

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!

", + "order": 6, + "tip": false + } +} +] \ No newline at end of file diff --git a/physionet-django/physionet/migrations/0008_step_alter_section_options_stepdetails.py b/physionet-django/physionet/migrations/0008_step_alter_section_options_stepdetails.py new file mode 100644 index 0000000000..53212bed97 --- /dev/null +++ b/physionet-django/physionet/migrations/0008_step_alter_section_options_stepdetails.py @@ -0,0 +1,47 @@ +# Generated by Django 4.1.13 on 2024-02-23 13:00 + +from django.db import migrations, models +import django.db.models.deletion +import project.modelcomponents.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('physionet', '0007_frontpagebutton'), + ] + + operations = [ + migrations.CreateModel( + name='Step', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=64)), + ('process_name', models.CharField(max_length=64)), + ('order', models.PositiveSmallIntegerField(default=0)), + ], + options={ + 'ordering': ('order',), + 'default_permissions': (), + }, + ), + migrations.AlterModelOptions( + name='section', + options={'default_permissions': ()}, + ), + migrations.CreateModel( + name='StepDetails', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=64)), + ('content', project.modelcomponents.fields.SafeHTMLField(blank=True)), + ('order', models.PositiveSmallIntegerField(default=0)), + ('tip', models.BooleanField(default=False)), + ('step', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='physionet.step')), + ], + options={ + 'default_permissions': (), + 'unique_together': {('step', 'order')}, + }, + ), + ] diff --git a/physionet-django/physionet/models.py b/physionet-django/physionet/models.py index da5a4cf057..4f82add2da 100644 --- a/physionet-django/physionet/models.py +++ b/physionet-django/physionet/models.py @@ -59,18 +59,24 @@ def delete(self, *args, **kwargs): page.save() -class Section(models.Model): +class AbstractSection(models.Model): + title = models.CharField(max_length=64) + content = SafeHTMLField(blank=True) + order = models.PositiveSmallIntegerField(default=0) + + class Meta: + abstract = True + ordering = ('order',) + + +class Section(AbstractSection): """ Holds sections of content for StaticPage. """ static_page = models.ForeignKey(StaticPage, on_delete=models.CASCADE) - title = models.CharField(max_length=64) - content = SafeHTMLField(blank=True) - order = models.PositiveSmallIntegerField(default=0) class Meta: default_permissions = () - ordering = ('order',) unique_together = (('static_page', 'order'),) def __str__(self): @@ -147,3 +153,32 @@ def move_down(self): self.order = order + 1 self.save() + +class Step(models.Model): + """ + Holds sections of content for StaticPage. + """ + title = models.CharField(max_length=64) + process_name = models.CharField(max_length=64) + order = models.PositiveSmallIntegerField(default=0) + + class Meta: + default_permissions = () + ordering = ('order',) + + def __str__(self): + return f"{self.process_name}: {self.title}" + +class StepDetails(AbstractSection): + """ + Holds sections of content for StaticPage. + """ + step = models.ForeignKey(Step, on_delete=models.CASCADE) + tip = models.BooleanField(default=False) + + class Meta: + default_permissions = () + unique_together = (('step', 'order'),) + + def __str__(self): + return self.title diff --git a/physionet-django/project/templates/project/project_authors.html b/physionet-django/project/templates/project/project_authors.html index 60ebdf8a80..a35689d69e 100644 --- a/physionet-django/project/templates/project/project_authors.html +++ b/physionet-django/project/templates/project/project_authors.html @@ -32,7 +32,7 @@ {% block main_content %} - +
{% include "about/authors.html" %}
diff --git a/physionet-django/project/templates/project/project_overview.html b/physionet-django/project/templates/project/project_overview.html index 99aaf6a319..b4c024d24e 100644 --- a/physionet-django/project/templates/project/project_overview.html +++ b/physionet-django/project/templates/project/project_overview.html @@ -28,14 +28,14 @@


-

Preparing for Submission

- -

To prepare the project for submission, go through the following steps using the side panel:

- -{% include "about/preparation_checklist.html" %} -

The full publishing process is described in the - author -guidelines.

+{% for step in steps_details %} +
+

{{ step.title }}

+
+ {{ step.content|safe }} +
+
+{% endfor %}
{% if is_submitting %}
diff --git a/physionet-django/project/views.py b/physionet-django/project/views.py index f66e803e7a..308ff30256 100644 --- a/physionet-django/project/views.py +++ b/physionet-django/project/views.py @@ -23,6 +23,7 @@ from django.utils.html import format_html, format_html_join from physionet.forms import set_saved_fields_cookie from physionet.middleware.maintenance import ServiceUnavailable +from physionet.models import Step, StepDetails from physionet.storage import generate_signed_url_helper from physionet.utility import serve_file from project import forms, utility @@ -403,10 +404,14 @@ def project_overview(request, project_slug, **kwargs): project.archive(archive_reason=1, clear_files=True) return redirect('delete_project_success') + project_overview_step = Step.objects.get(process_name='Create Project', title="Overview") + project_overview_step_details = StepDetails.objects.filter(step=project_overview_step) + return render(request, 'project/project_overview.html', {'project':project, 'is_submitting':is_submitting, 'under_submission':under_submission, - 'submitting_author':kwargs['authors'].get(is_submitting=True)}) + 'submitting_author':kwargs['authors'].get(is_submitting=True), + 'steps_details': project_overview_step_details}) @login_required @@ -640,6 +645,8 @@ def project_authors(request, project_slug, **kwargs): authors = project.get_author_info() invitations = project.authorinvitations.filter(is_active=True) edit_affiliations_url = reverse('edit_affiliation', args=[project.slug]) + project_authors_step = Step.objects.get(process_name='Create Project', title="Authors") + project_authors_step_details = StepDetails.objects.filter(step=project_authors_step) return render( request, "project/project_authors.html", @@ -655,6 +662,7 @@ def project_authors(request, project_slug, **kwargs): "add_item_url": edit_affiliations_url, "remove_item_url": edit_affiliations_url, "is_submitting": is_submitting, + "step_details": project_authors_step_details }, ) diff --git a/physionet-django/user/management/commands/test_add_new_sections.py b/physionet-django/user/management/commands/test_add_new_sections.py new file mode 100644 index 0000000000..5137026bf8 --- /dev/null +++ b/physionet-django/user/management/commands/test_add_new_sections.py @@ -0,0 +1,34 @@ +""" +Command to: +- load all fixtures named 'demo-*.*' +- create copy the demo media files + +This should only be called in a clean database, such as after +`resetdb` is run. This should generally only be used in +development environments. + +""" +import os + +from django.conf import settings +from django.core.management import call_command +from django.core.management.base import BaseCommand + +class Command(BaseCommand): + + def handle(self, *args, **options): + # If not in development, prompt warning messages twice + if 'development' not in settings.ENVIRONMENT: + warning_messages = ['You are NOT in the development environment. Are you sure you want to insert demo data? [y/n]', + 'The demo data will be mixed with existing data. Are you sure? [y/n]', + 'Final warning. Are you ABSOLUTELY SURE? [y/n]'] + for i in range(3): + choice = input(warning_messages[i]).lower() + if choice != 'y': + sys.exit('Exiting from load. No actions applied.') + print('Continuing loading demo data') + + # Load licences and software languages + sections_fixtures = os.path.join(settings.BASE_DIR, 'physionet', + 'fixtures', 'steps.json') + call_command('loaddata', sections_fixtures, verbosity=1) \ No newline at end of file From d4014eb4c66ef0b19446019c196c100fb7d38a16 Mon Sep 17 00:00:00 2001 From: matkaczmarek Date: Thu, 29 Feb 2024 14:52:51 +0100 Subject: [PATCH 02/10] Add `slug` and add defaults if step is not in database [T-CAIREM 1137] --- physionet-django/console/forms.py | 2 +- .../physionet/fixtures/steps.json | 18 +++- ..._step_alter_section_options_stepdetails.py | 4 +- physionet-django/physionet/models.py | 2 + .../templates/project/project_authors.html | 86 ++++++++++++++----- .../templates/project/project_overview.html | 26 ++++-- physionet-django/project/views.py | 12 ++- 7 files changed, 113 insertions(+), 37 deletions(-) diff --git a/physionet-django/console/forms.py b/physionet-django/console/forms.py index b07dff1dcc..e35188c7d6 100644 --- a/physionet-django/console/forms.py +++ b/physionet-django/console/forms.py @@ -1004,4 +1004,4 @@ class StepDetailsForm(forms.ModelForm): class Meta: model = StepDetails - fields = ("title", "content", "tip") + fields = ("title", "content", "slug", "tip") diff --git a/physionet-django/physionet/fixtures/steps.json b/physionet-django/physionet/fixtures/steps.json index dba752a08a..6dac090251 100644 --- a/physionet-django/physionet/fixtures/steps.json +++ b/physionet-django/physionet/fixtures/steps.json @@ -4,6 +4,7 @@ "pk": 1, "fields": { "title": "Overview", + "slug": "create_project_overview", "process_name": "Create Project", "order": 1 } @@ -13,6 +14,7 @@ "pk": 2, "fields": { "title": "Authors", + "slug": "create_project_authors", "process_name": "Create Project", "order": 2 } @@ -22,6 +24,7 @@ "pk": 3, "fields": { "title": "Content", + "slug": "create_project_content", "process_name": "Create Project", "order": 3 } @@ -31,6 +34,7 @@ "pk": 4, "fields": { "title": "Access", + "slug": "create_project_access", "process_name": "Create Project", "order": 4 } @@ -40,6 +44,7 @@ "pk": 5, "fields": { "title": "Discovery", + "slug": "create_project_discovery", "process_name": "Create Project", "order": 5 } @@ -49,6 +54,7 @@ "pk": 6, "fields": { "title": "Ethics", + "slug": "create_project_ethics", "process_name": "Create Project", "order": 6 } @@ -58,6 +64,7 @@ "pk": 7, "fields": { "title": "Files", + "slug": "create_project_files", "process_name": "Create Project", "order": 7 } @@ -67,6 +74,7 @@ "pk": 8, "fields": { "title": "Proofread", + "slug": "create_project_proofread", "process_name": "Create Project", "order": 8 } @@ -76,6 +84,7 @@ "pk": 9, "fields": { "title": "Submission", + "slug": "create_project_submission", "process_name": "Create Project", "order": 9 } @@ -86,6 +95,7 @@ "fields": { "step": 1, "title": "Preparing for Submission", + "slug": "preparing_for_submission", "content": "

To prepare the project for submission, go through the following steps using the side panel:

\n
    \n
  1. Invite authors to be credited for creating the resource.
  2. \n
  3. Fill in the descriptive metadata.
  4. \n
  5. Set the access policy and license.
  6. \n
  7. Add discovery information.
  8. \n
  9. Upload the files.
  10. \n
  11. Proofread the project and make sure it is ready for submission.
  12. \n

The full publishing process is described in the\n author\nguidelines.

", "order": 1, "tip": false @@ -97,6 +107,7 @@ "fields": { "step": 2, "title": "1. Project Authors", + "slug": "project_authors", "content": "

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 project home page. Authors must provide their affiliation on a project-by-project basis.

\n", "order": 1, "tip": false @@ -108,6 +119,7 @@ "fields": { "step": 2, "title": "Corresponding Author", + "slug": "corresponding_author", "content": "

The corresponding author is responsible for responding to inquiries from users post publication.

", "order": 2, "tip": false @@ -119,7 +131,8 @@ "fields": { "step": 2, "title": "Corresponding Email", - "content": "

You are the the selected corresponding author. Choose one of your emails to be listed for correspondence.

\n", + "slug": "corresponding_email", + "content": "

You are the selected corresponding author. Choose one of your emails to be listed for correspondence.

\n", "order": 3, "tip": false } @@ -130,6 +143,7 @@ "fields": { "step": 2, "title": "Your Affiliations", + "slug": "your_affiliations", "content": "

Set up to three affiliations for your author profile. Note: these fields are not tied to your user profile.

\n", "order": 4, "tip": false @@ -141,6 +155,7 @@ "fields": { "step": 2, "title": "Your Affiliations", + "slug": "your_affiliations_tip", "content": "Institutions you are affiliated with. Maximum of 3.", "order": 5, "tip": true @@ -152,6 +167,7 @@ "fields": { "step": 2, "title": "Submitting Author", + "slug": "submitting_author", "content": "

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!

", "order": 6, "tip": false diff --git a/physionet-django/physionet/migrations/0008_step_alter_section_options_stepdetails.py b/physionet-django/physionet/migrations/0008_step_alter_section_options_stepdetails.py index 53212bed97..af830e1035 100644 --- a/physionet-django/physionet/migrations/0008_step_alter_section_options_stepdetails.py +++ b/physionet-django/physionet/migrations/0008_step_alter_section_options_stepdetails.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.13 on 2024-02-23 13:00 +# Generated by Django 4.1.13 on 2024-02-29 09:28 from django.db import migrations, models import django.db.models.deletion @@ -18,6 +18,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=64)), ('process_name', models.CharField(max_length=64)), + ('slug', models.CharField(max_length=64)), ('order', models.PositiveSmallIntegerField(default=0)), ], options={ @@ -36,6 +37,7 @@ class Migration(migrations.Migration): ('title', models.CharField(max_length=64)), ('content', project.modelcomponents.fields.SafeHTMLField(blank=True)), ('order', models.PositiveSmallIntegerField(default=0)), + ('slug', models.CharField(max_length=64)), ('tip', models.BooleanField(default=False)), ('step', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='physionet.step')), ], diff --git a/physionet-django/physionet/models.py b/physionet-django/physionet/models.py index 4f82add2da..f98f5fedc6 100644 --- a/physionet-django/physionet/models.py +++ b/physionet-django/physionet/models.py @@ -160,6 +160,7 @@ class Step(models.Model): """ title = models.CharField(max_length=64) process_name = models.CharField(max_length=64) + slug = models.CharField(max_length=64) order = models.PositiveSmallIntegerField(default=0) class Meta: @@ -174,6 +175,7 @@ class StepDetails(AbstractSection): Holds sections of content for StaticPage. """ step = models.ForeignKey(Step, on_delete=models.CASCADE) + slug = models.CharField(max_length=64) tip = models.BooleanField(default=False) class Meta: diff --git a/physionet-django/project/templates/project/project_authors.html b/physionet-django/project/templates/project/project_authors.html index a35689d69e..3675291600 100644 --- a/physionet-django/project/templates/project/project_authors.html +++ b/physionet-django/project/templates/project/project_authors.html @@ -31,11 +31,19 @@ {% block main_content %} - - -
-{% include "about/authors.html" %} -
+{% with step_detail=step_details_dict.project_authors %} + {% if step_detail %} + +
+ {{ step_detail.content|safe }} +
+ {% else %} + +
+ {% include "about/authors.html" %} +
+ {% endif %} +{% endwith %} {% if not project.author_editable %}
@@ -75,17 +83,30 @@

Outstanding Author Invitations

{% if is_submitting %}
-

Invite Author

- + {% with step_detail=step_details_dict.invite_author %} + {% if step_detail %} +

{{ step_detail.title }}

+ {% else %} +

Invite Author

+ {% endif %} + + {% endwith %}

-

Corresponding Author

-

The corresponding author is responsible for responding to inquiries from users post publication.

+ {% with step_detail=step_details_dict.corresponding_author %} + {% if step_detail %} +

{{ step_detail.title }}

+ {{ step_detail.content|safe }} + {% else %} +

Corresponding Author

+

The corresponding author is responsible for responding to inquiries from users post publication.

+ {% endif %} + {% endwith %}