diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 97d583bd8490a181dc88cc8b2f8502e7d64ab1b0..0000000000000000000000000000000000000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -*.min.js -**/esm/*.js diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 083be93dbb5da9ec45642c65412921b87d0cb122..6e674e488a98ea9983310411d40b22107ab2d201 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -5,6 +5,11 @@ env: browser: true commonjs: true es6: true + +ignorePatterns: + - "*.min.js" + - "**/esm/*.js" + globals: jQuery: true rules: diff --git a/.github/workflows/hypha-ci.yml b/.github/workflows/hypha-ci.yml index de307b73d9d9219d19ae40fa8635b37a85c867c2..83c2bc8feecf38b6b3713b99ac08e319e833a18d 100644 --- a/.github/workflows/hypha-ci.yml +++ b/.github/workflows/hypha-ci.yml @@ -88,7 +88,7 @@ jobs: - name: Install python dependencies run: pip install `grep -E "ruff|djhtml|black" requirements-dev.txt` - name: Run ruff - run: ruff --format github . + run: ruff check --output-format=github . - name: Run black run: black . --check - name: Run djhtml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bae644a7a23de9f059891b70a198054b537bad8c..db4a02c90fa323608f3cf817b191fea663fa3e2c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.280 + rev: v0.1.1 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 23.10.0 hooks: - id: black # It is recommended to specify the latest version of Python @@ -19,6 +19,6 @@ repos: - id: djhtml files: .*/templates/.*\.html$ - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0 # Use the sha or tag you want to point at + rev: v3.0.3 # Use the sha or tag you want to point at hooks: - id: prettier diff --git a/Makefile b/Makefile index 0f28276fb3ea563061eed8e4f33408c7f6b9bdac..e9c5c50a18097b855c342dee89ec0c3e2f724ce7 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ endif .PHONY: lint lint: @echo "Checking python code style with ruff" - ruff . + ruff check . black . --check @echo "Checking html file indendation." djhtml hypha/ --check diff --git a/docs/assets/extra.css b/docs/assets/extra.css index 7a6cfc2fc515534f8dc5564d9095fc65867ba6c0..6a252eaba867ef589d8cd98ed1f9f8c89c28db51 100644 --- a/docs/assets/extra.css +++ b/docs/assets/extra.css @@ -1,3 +1,7 @@ +:root { + --md-primary-fg-color: #1269a1; +} + [dir="ltr"] .md-header__title { margin-left: 0.2rem; } diff --git a/hypha/apply/activity/adapters/activity_feed.py b/hypha/apply/activity/adapters/activity_feed.py index df1ceb22ddeeff41cac54cbe97cc57a7248ce717..bbf0ff947f91e1c40b59da3c6944f5918f25d0bd 100644 --- a/hypha/apply/activity/adapters/activity_feed.py +++ b/hypha/apply/activity/adapters/activity_feed.py @@ -48,7 +48,7 @@ class ActivityAdapter(AdapterBase): "Lead changed from {old_lead} to {source.lead}" ), MESSAGES.SEND_FOR_APPROVAL: _("Requested approval"), - MESSAGES.APPROVE_PAF: _("PAF assigned to {user}"), + MESSAGES.APPROVE_PAF: "handle_paf_assignment", MESSAGES.APPROVE_PROJECT: _("Approved"), MESSAGES.REQUEST_PROJECT_CHANGE: _( 'Requested changes for acceptance: "{comment}"' @@ -105,7 +105,6 @@ class ActivityAdapter(AdapterBase): MESSAGES.APPROVE_CONTRACT, MESSAGES.UPLOAD_CONTRACT, MESSAGES.SUBMIT_CONTRACT_DOCUMENTS, - MESSAGES.UPDATE_INVOICE_STATUS, MESSAGES.DELETE_INVOICE, MESSAGES.CREATE_INVOICE, ]: @@ -122,6 +121,7 @@ class ActivityAdapter(AdapterBase): invoice = kwargs.get("invoice", None) if invoice and not is_invoice_public_transition(invoice): return {"visibility": TEAM} + return {"visibility": APPLICANT} return {} def reviewers_updated(self, added=None, removed=None, **kwargs): @@ -168,6 +168,20 @@ class ActivityAdapter(AdapterBase): title=submissions_text ) + def handle_paf_assignment(self, source, paf_approvals, **kwargs): + if hasattr(paf_approvals, "__iter__"): # paf_approvals has to be iterable + users = ", ".join( + [ + paf_approval.user.full_name + if paf_approval.user.full_name + else paf_approval.user.username + for paf_approval in paf_approvals + ] + ) + users_sentence = " and".join(users.rsplit(",", 1)) + return _("PAF assigned to {}").format(users_sentence) + return None + def handle_transition(self, old_phase, source, **kwargs): submission = source base_message = _("Progressed from {old_display} to {new_display}") diff --git a/hypha/apply/activity/adapters/base.py b/hypha/apply/activity/adapters/base.py index 0afd30e84fa4aa944be82914817fb1a1efb87f1e..d04e4d70b92de2da49b81c57004d369ab2ae5440 100644 --- a/hypha/apply/activity/adapters/base.py +++ b/hypha/apply/activity/adapters/base.py @@ -24,6 +24,7 @@ neat_related = { MESSAGES.EDIT_REVIEW: "review", MESSAGES.CREATED_PROJECT: "submission", MESSAGES.PROJECT_TRANSITION: "old_stage", + MESSAGES.APPROVE_PAF: "paf_approvals", # expect a list MESSAGES.UPDATE_PROJECT_LEAD: "old_lead", MESSAGES.APPROVE_CONTRACT: "contract", MESSAGES.UPLOAD_CONTRACT: "contract", diff --git a/hypha/apply/activity/adapters/emails.py b/hypha/apply/activity/adapters/emails.py index 0c999af3bbb247a4bd988e4d92b77f7f49533fb3..5cb58291827aa748e8cf7870b2fd8a9b985124e7 100644 --- a/hypha/apply/activity/adapters/emails.py +++ b/hypha/apply/activity/adapters/emails.py @@ -56,7 +56,6 @@ class EmailAdapter(AdapterBase): MESSAGES.CREATED_PROJECT: "handle_project_created", MESSAGES.UPDATED_VENDOR: "handle_vendor_updated", MESSAGES.SENT_TO_COMPLIANCE: "messages/email/sent_to_compliance.html", - MESSAGES.SEND_FOR_APPROVAL: "messages/email/paf_for_approval.html", MESSAGES.REQUEST_PROJECT_CHANGE: "messages/email/project_request_change.html", MESSAGES.ASSIGN_PAF_APPROVER: "messages/email/assign_paf_approvers.html", MESSAGES.APPROVE_PAF: "messages/email/paf_for_approval.html", @@ -94,7 +93,6 @@ class EmailAdapter(AdapterBase): elif message_type in [ MESSAGES.SENT_TO_COMPLIANCE, MESSAGES.APPROVE_PAF, - MESSAGES.SEND_FOR_APPROVAL, ]: subject = _("Project is waiting for approval: {source.title}").format( source=source @@ -297,7 +295,7 @@ class EmailAdapter(AdapterBase): partners = kwargs["added"] return [partner.email for partner in partners] - if message_type in [MESSAGES.SEND_FOR_APPROVAL, MESSAGES.APPROVE_PAF]: + if message_type == MESSAGES.APPROVE_PAF: from hypha.apply.projects.models.project import ProjectSettings # notify the assigned approvers @@ -393,6 +391,10 @@ class EmailAdapter(AdapterBase): ) if source.status == CONTRACTING: + if settings.STAFF_UPLOAD_CONTRACT: + return get_compliance_email( + target_user_gps=[CONTRACTING_GROUP_NAME, STAFF_GROUP_NAME] + ) return get_compliance_email(target_user_gps=[CONTRACTING_GROUP_NAME]) if source.status == INVOICING_AND_REPORTING: return [source.user.email] diff --git a/hypha/apply/activity/adapters/utils.py b/hypha/apply/activity/adapters/utils.py index 98f95af826163c5b59edc738bd0eb1396d8eb45b..0e2bd8eb2af2f14da264c1eb51688488043d5b64 100644 --- a/hypha/apply/activity/adapters/utils.py +++ b/hypha/apply/activity/adapters/utils.py @@ -12,6 +12,7 @@ from hypha.apply.projects.models.payment import ( CHANGES_REQUESTED_BY_STAFF, DECLINED, PAID, + PAYMENT_FAILED, RESUBMITTED, SUBMITTED, ) @@ -62,6 +63,7 @@ def is_invoice_public_transition(invoice): APPROVED_BY_FINANCE_2, DECLINED, PAID, + PAYMENT_FAILED, ]: return True if not settings.INVOICE_EXTENDED_WORKFLOW and invoice.status == APPROVED_BY_FINANCE: diff --git a/hypha/apply/categories/blocks.py b/hypha/apply/categories/blocks.py index 6f67aea3c6f88ee3923ee514b3f813bf60f6f196..1b129363c50e9550fcc5f58a7e1a9950e13895e7 100644 --- a/hypha/apply/categories/blocks.py +++ b/hypha/apply/categories/blocks.py @@ -94,7 +94,7 @@ class CategoryQuestionBlock(OptionalFormFieldBlock): for field in category_fields.keys(): if not value.get(field): category = value["category"] - if isinstance(category, int): + if isinstance(category, int) or isinstance(category, str): category = self.get_instance(id=category) value[field] = getattr(category, category_fields[field]) return super().render(value, context) diff --git a/hypha/apply/dashboard/templates/dashboard/applicant_dashboard.html b/hypha/apply/dashboard/templates/dashboard/applicant_dashboard.html index b83e83de14f7608334e91eb15d7a1fb20c2d8a6f..2cf78fcb209b0ba60300976dbb1395f6da148738 100644 --- a/hypha/apply/dashboard/templates/dashboard/applicant_dashboard.html +++ b/hypha/apply/dashboard/templates/dashboard/applicant_dashboard.html @@ -1,6 +1,6 @@ {% extends "base-apply.html" %} {% load render_table from django_tables2 %} -{% load i18n static wagtailcore_tags workflow_tags statusbar_tags heroicons %} +{% load i18n static wagtailcore_tags workflow_tags statusbar_tags heroicons dashboard_statusbar_tags %} {% block title %}{% trans "Dashboard" %}{% endblock %} @@ -16,57 +16,59 @@ </div> {% endadminbar %} - <div class="wrapper wrapper--large wrapper--inner-space-medium mb-4"> - <h2 class="text-xl mb-2"> - {% trans "Your active submissions" %} - </h2> - <div class=""> - {% for submission in my_active_submissions %} - <div class="wrapper wrapper--status-bar-outer"> - <div class="wrapper wrapper--status-bar-inner"> - <div class="flex max-w-sm sm:max-w-lg flex-col gap-2 md:flex-row md:justify-between md:w-full md:max-w-none lg:flex-col lg:justify-start lg:w-auto lg:max-w-sm"> - <div> - <h3 class="heading heading--no-margin text-base font-bold"> - <a class="link link--underlined" href="{% url 'funds:submissions:detail' submission.id %}"> - {{ submission.title }} - </a> - </h3> - <p class="heading heading--no-margin text-fg-muted text-sm"> - {% trans "Submitted" %}: {{ submission.submit_time.date }} {% trans "by" %} {{ submission.user.get_full_name }} - </p> + <div class="wrapper wrapper--large wrapper--inner-space-medium"> + {% if my_active_submissions %} + <div class="mb-10"> + <div class="flex"> + <h2 class="font-light flex-1">{% trans "My active submissions" %}</h2> + </div> + {% for submission in my_active_submissions %} + <div class="wrapper wrapper--status-bar-outer"> + <div class="wrapper wrapper--status-bar-inner"> + <div class="mt-5 ml-4"> + <h4 class="heading mb-2 font-bold"><a class="link link--underlined" href="{% url 'funds:submissions:detail' submission.id %}">{{ submission.title }}</a></h4> + <p class="m-0 text-gray-400">{% trans "Submitted on " %} {{ submission.submit_time.date }} {% trans "by" %} {{ submission.user.get_full_name }}</p> </div> - {% if request.user|has_edit_perm:submission %} - <div> - <a class="button button--primary" href="{% url 'funds:submissions:edit' submission.id %}"> - {% if submission.status == 'draft_proposal' %} - {% trans "Start your" %} {{ submission.stage }} {% trans "application" %} - {% else %} - <span class="whitespace-nowrap"> - {% heroicon_mini "pencil-square" size=18 class="inline mr-1 align-text-bottom" aria_hidden=true %} - {% trans "Edit" %} - </span> - {% endif %} - </a> - </div> - {% endif %} - + {% status_bar submission.workflow submission.phase request.user css_class="status-bar--small" %} </div> - {% status_bar submission.workflow submission.phase request.user css_class="status-bar--small" %} + {% if request.user|has_edit_perm:submission %} + <a class="button button--primary ml-4" href="{% url 'funds:submissions:edit' submission.id %}"> + {% if submission.status == 'draft_proposal' %} + {% trans "Start your" %} {{ submission.stage }} {% trans "application" %} + {% else %} + {% trans "Edit" %} + {% endif %} + </a> + {% endif %} </div> + {% empty %} + {% trans "No active submissions" %} + {% endfor %} + </div> + {% endif %} + + {% if active_projects.count %} + <div class="mb-10"> + <div class="flex"> + <h2 class="font-light flex-1">{% trans "My active projects" %}</h2> </div> - {% empty %} - {% trans "No active submissions" %} - {% endfor %} - </div> + {% for project in active_projects.data %} + <div class="wrapper wrapper--status-bar-outer"> + <div class="wrapper wrapper--status-bar-inner"> + <div class="mt-5 ml-4"> + <h4 class="heading mb-2 font-bold"><a class="link link--underlined" href="{% url 'apply:projects:detail' project.id %}">{{ project.title }}</a></h4> + <p class="m-0 text-gray-400">{% trans "Project start date: " %} {{ project.created_at.date }}</p> + </div> + {% project_status_bar project.status request.user css_class="status-bar--small" %} + </div> + </div> + {% empty %} + {% trans "No active projects" %} + {% endfor %} + </div> + {% endif %} </div> - {% if active_projects.count %} - <div class="wrapper wrapper--large wrapper--inner-space-medium mb-8"> - <h2 class="text-xl mb-2">{% trans "Your active projects" %}</h2> - {% render_table active_projects.table %} - </div> - {% endif %} - {% if historical_submissions.count %} <div class="wrapper wrapper--large wrapper--inner-space-medium mb-8"> <h2 class="text-xl mb-2">{% trans "Submission history" %}</h3> diff --git a/hypha/apply/dashboard/templates/dashboard/includes/project_status_bar.html b/hypha/apply/dashboard/templates/dashboard/includes/project_status_bar.html new file mode 100644 index 0000000000000000000000000000000000000000..47ca9d6e8cbb9b0387a9923b4b63a6f8161a60ac --- /dev/null +++ b/hypha/apply/dashboard/templates/dashboard/includes/project_status_bar.html @@ -0,0 +1,18 @@ +{% load dashboard_statusbar_tags %} +<div class="status-bar {{ class }}"> + {% for status, text in statuses %} + {% if forloop.counter0 == current_status_index %} + {% include "funds/includes/status_bar_item.html" with is_current=True is_complete=False label=text %} + {% elif forloop.counter0 < current_status_index %} + {% include "funds/includes/status_bar_item.html" with is_current=False is_complete=True label=text %} + {% else %} + {% include "funds/includes/status_bar_item.html" with is_current=False is_complete=False label=text %} + {% endif %} + {% endfor %} +</div> + +<div class="status-bar--mobile"> + <h6 class="status-bar__subheading"> + {{ object.get_status_display }} + </h6> +</div> diff --git a/hypha/apply/dashboard/templatetags/dashboard_statusbar_tags.py b/hypha/apply/dashboard/templatetags/dashboard_statusbar_tags.py new file mode 100644 index 0000000000000000000000000000000000000000..c60f8e1f44825c8aa4e10deb9683131b030810f1 --- /dev/null +++ b/hypha/apply/dashboard/templatetags/dashboard_statusbar_tags.py @@ -0,0 +1,26 @@ +from django import template + +from hypha.apply.projects.models.project import ( + PROJECT_PUBLIC_STATUSES, + PROJECT_STATUS_CHOICES, +) + +register = template.Library() + + +@register.inclusion_tag("dashboard/includes/project_status_bar.html") +def project_status_bar(current_status, user, author=False, css_class=""): + is_applicant = user == author if author else user.is_applicant + + statuses = PROJECT_STATUS_CHOICES + + if is_applicant: + statuses = PROJECT_PUBLIC_STATUSES + + return { + "statuses": statuses, + "current_status_index": [status for status, _ in PROJECT_STATUS_CHOICES].index( + current_status + ), + "class": css_class, + } diff --git a/hypha/apply/dashboard/views.py b/hypha/apply/dashboard/views.py index a50fda04765e1a6965bd8c4273759efba8324bf4..04d50285406ee4aaaeb2fc2d1771d08037972443 100644 --- a/hypha/apply/dashboard/views.py +++ b/hypha/apply/dashboard/views.py @@ -789,11 +789,14 @@ class ApplicantDashboardView(TemplateView): def active_project_data(self): active_projects = ( - Project.objects.filter(user=self.request.user).active().for_table() + Project.objects.filter(user=self.request.user) + .active() + .order_by("-created_at") + .for_table() ) return { "count": active_projects.count(), - "table": ProjectsDashboardTable(data=active_projects), + "data": active_projects, } def my_active_submissions(self, user): diff --git a/hypha/apply/determinations/templates/determinations/batch_determination_form.html b/hypha/apply/determinations/templates/determinations/batch_determination_form.html index 77a17247c3bc801925bc9faab148a0aa1f1c574d..f8d67720b3759043484ff8b84d3d2c901e7253cb 100644 --- a/hypha/apply/determinations/templates/determinations/batch_determination_form.html +++ b/hypha/apply/determinations/templates/determinations/batch_determination_form.html @@ -7,11 +7,9 @@ {% endblock %} {% block header %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h2 class="heading heading--no-margin">{% trans "Add Batch Determination" %} - {{ action_name }}</h2> - </div> - </div> + {% adminbar %} + {% slot header %}{% trans "Add Batch Determination" %} - {{ action_name }}{% endslot %} + {% endadminbar %} {% endblock %} {% block determination_information %} diff --git a/hypha/apply/determinations/templates/determinations/determination_detail.html b/hypha/apply/determinations/templates/determinations/determination_detail.html index 68f9e113220c686dfbeb02791dee3dc919f0e1f8..a6cef47d48bbd84843ce4b9e92804f9815c7850e 100644 --- a/hypha/apply/determinations/templates/determinations/determination_detail.html +++ b/hypha/apply/determinations/templates/determinations/determination_detail.html @@ -30,7 +30,7 @@ {% endif %} </div> - <div class="rich-text rich-text--answers"> + <div class="rich-text rich-text--answers prose"> <h4>{% trans "Determination message" %}</h4> {{ determination.message|bleach }} {% for group in determination.detailed_data.values %} diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_confirm_delete.html b/hypha/apply/funds/templates/funds/applicationsubmission_confirm_delete.html index a8be354ec1ef3fc4a8bdcf7d4470ac1e260d2044..e939a5eb8b20aa2dd3434984c6b6b34b4d538fe1 100644 --- a/hypha/apply/funds/templates/funds/applicationsubmission_confirm_delete.html +++ b/hypha/apply/funds/templates/funds/applicationsubmission_confirm_delete.html @@ -4,11 +4,10 @@ {% block title %}{% trans "Deleting" %}: {{object.title }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h2 class="heading heading--no-margin">{% trans "Deleting" %}: {{ object.title }}</h2> - </div> - </div> + + {% adminbar %} + {% slot header %}{% trans "Deleting" %}: {{ object.title }}{% endslot %} + {% endadminbar %} <div class="wrapper wrapper--light-grey-bg wrapper--form wrapper--sidebar"> <div class="wrapper--sidebar--inner"> diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html index 90bfd445751be9ac966710c27c6f4d01894b6007..2ab22c2a9de8f1b3fb0bc89b87e5e6578c167047 100644 --- a/hypha/apply/funds/templates/funds/applicationsubmission_detail.html +++ b/hypha/apply/funds/templates/funds/applicationsubmission_detail.html @@ -22,8 +22,8 @@ {% trans "Back to submissions" %} </a> {% endif %} - <h1 class="mb-0 mt-2 font-normal">{{ object.title }} <span class="heading--number">#{{ object.id }}</span></h1> - <div class="heading heading--meta text-sm mt-1"> + <h1 class="mb-0 mt-2 font-medium">{{ object.title }} <span class="heading--number">#{{ object.id }}</span></h1> + <div class="heading heading--meta text-sm mt-1 font-medium"> <span>{{ object.stage }}</span> <span>{{ object.page }}</span> {% if request.user.is_apply_staff and object.round %} diff --git a/hypha/apply/funds/templates/funds/submission_sealed.html b/hypha/apply/funds/templates/funds/submission_sealed.html index 4db73b2332965098a4e3279daf3649ae6d979383..af8755414d96925bf76b44ee5a9a24ad97d994ef 100644 --- a/hypha/apply/funds/templates/funds/submission_sealed.html +++ b/hypha/apply/funds/templates/funds/submission_sealed.html @@ -6,7 +6,7 @@ {% block content %} <div class="admin-bar"> <div class="admin-bar__inner"> - <h1 class="beta heading heading--no-margin heading--bold">{{ object.title }}</h1> + <h1 class="text-2xl mb-2 font-medium md:text-3xl md:m-0">{{ object.title }}</h1> <h5 class="heading heading--meta"> <span>{{ object.stage }}</span> <span>{{ object.page }}</span> diff --git a/hypha/apply/projects/permissions.py b/hypha/apply/projects/permissions.py index 87b22573d090bd26ae258622e6f1d3308b5a3710..83462d9c42d0172a304c15a7f8e6187eb06183bc 100644 --- a/hypha/apply/projects/permissions.py +++ b/hypha/apply/projects/permissions.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.core.exceptions import PermissionDenied from hypha.apply.activity.adapters.utils import get_users_for_groups @@ -52,6 +53,9 @@ def can_upload_contract(user, project, **kwargs): if user.is_contracting: return True, "Contracting team can upload the contract" + if user.is_apply_staff and settings.STAFF_UPLOAD_CONTRACT: + return True, "Staff can upload contract as set in settings" + return False, "Forbidden Error" diff --git a/hypha/apply/projects/templates/application_projects/includes/contracting_documents.html b/hypha/apply/projects/templates/application_projects/includes/contracting_documents.html index dcb9d04df217d041cb4a9acc1fa9fdaf790c8b03..ebaaee5287f6f34f5287fac8ed071798f2a02fe6 100644 --- a/hypha/apply/projects/templates/application_projects/includes/contracting_documents.html +++ b/hypha/apply/projects/templates/application_projects/includes/contracting_documents.html @@ -81,7 +81,8 @@ {% if not contract.uploaded_by_contractor_at %}{% trans "Pending signed contract by " %}{% else %}{% trans "Signed contract by " %}{% endif %}{% if user == object.user %}{{ ORG_SHORT_NAME }}{% else %}{% trans "Contracting team " %} {% endif %} <i>{% if contract.uploaded_by_contractor_at %}({{ contract.uploaded_by_contractor_at }}){% endif %}</i></p> </div> - {% if can_upload_contract and user.is_contracting %} + {% user_can_initiate_contract user as can_initiate_contract %} + {% if can_upload_contract and can_initiate_contract %} <div class="docs-block__row-inner docs-block__row-inner__contract-upload-row"> <a data-fancybox class="font-bold flex items-center w-auto text-left bg-light-blue text-white mr-0 p-2.5 border-none" href="#" data-src="#upload-contract"> <svg class="icon icon--arrow-up-short-bar icon--arrow-up-short-bar--contract-upload"><use xlink:href="#arrow-up-short-bar"></use></svg> diff --git a/hypha/apply/projects/templates/application_projects/invoice_confirm_delete.html b/hypha/apply/projects/templates/application_projects/invoice_confirm_delete.html index 12136e3e88fd2ec8e18b0f3cbd75b2d6668f855e..53dc93b079e66969965fe842bc86d78777f71ae4 100644 --- a/hypha/apply/projects/templates/application_projects/invoice_confirm_delete.html +++ b/hypha/apply/projects/templates/application_projects/invoice_confirm_delete.html @@ -4,15 +4,16 @@ {% block title %} {% trans "Invoice" %}: {{ object.project.title }}{% endblock %} {% block content %} {% display_invoice_status_for_user user object as invoice_status %} - <div class="admin-bar"> - <div class="admin-bar__inner"> + + {% adminbar %} + {% slot back_link %} <a class="simplified__projects-link" href="{{ object.project.get_absolute_url }}"> {% trans "View project page" %} </a> - <h2 class="heading heading--no-margin">{% trans "Delete Invoice" %}</h2> - <h5 class="heading heading--no-margin">{% trans "For" %}: {{ object.project.title }}</h5> - </div> - </div> + {% endslot %} + {% slot header %}{% trans "Delete Invoice" %}{% endslot %} + {% slot sub_heading %}{% trans "For" %}: {{ object.project.title }}{% endslot %} + {% endadminbar %} <div class="wrapper wrapper--sidebar wrapper--outer-space-medium"> <div class="wrapper--sidebar--inner"> diff --git a/hypha/apply/projects/templates/application_projects/invoice_detail.html b/hypha/apply/projects/templates/application_projects/invoice_detail.html index edf5fa4d9a052b5374f2bf72b3be8b3ddf454b25..4739e8100e53cf40f0958d0f8c2e43008d06d1b5 100644 --- a/hypha/apply/projects/templates/application_projects/invoice_detail.html +++ b/hypha/apply/projects/templates/application_projects/invoice_detail.html @@ -4,15 +4,16 @@ {% block title %}{% trans "Invoice" %}: {{ object.project.title }}{% endblock %} {% block content %} {% display_invoice_status_for_user user object as invoice_status %} - <div class="admin-bar"> - <div class="admin-bar__inner"> + + {% adminbar %} + {% slot back_link %} <a class="simplified__projects-link" href="{{ object.project.get_absolute_url }}"> {% trans "View project page" %} </a> - <h2 class="heading heading--no-margin">{% trans "Invoice" %}</h2> - <h5 class="heading heading--no-margin">{% trans "For" %}: {{ object.project.title }}</h5> - </div> - </div> + {% endslot %} + {% slot header %}{% trans "Invoice" %}{% endslot %} + {% slot sub_heading %}{% trans "For" %}: {{ object.project.title }}{% endslot %} + {% endadminbar %} <div class="wrapper wrapper--sidebar wrapper--outer-space-medium"> <div class="wrapper--sidebar--inner"> diff --git a/hypha/apply/projects/templates/application_projects/invoice_form.html b/hypha/apply/projects/templates/application_projects/invoice_form.html index 7f75f6141891cd48b2e4acf6660eb26ef36a695d..eaa62c3b92bfda61594c4c86a702b50cdebbd202 100644 --- a/hypha/apply/projects/templates/application_projects/invoice_form.html +++ b/hypha/apply/projects/templates/application_projects/invoice_form.html @@ -3,15 +3,29 @@ {% block title %}{% if object %}{% trans "Edit" %}{% else %}{% trans "Add" %}{% endif %} {% trans "Invoice" %}: {% if object %}{{ object.project.title }}{% else %}{{ project.title }}{% endif %}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> + + {% adminbar %} + {% slot back_link %} <a class="simplified__projects-link" href="{{ project.get_absolute_url }}"> {% trans "View project page" %} </a> - <h2 class="heading heading--no-margin">{% if object %}{% trans "Editing" %}{% else %}{% trans "Add" %}{% endif %} {% trans "Invoice" %}</h2> - <h5 class="heading heading--no-margin">{% if object %}{{ object.project.title }}{% else %}{% trans "For" %}: {{ project.title }}{% endif %}</h5> - </div> - </div> + {% endslot %} + {% slot header %} + {% if object %} + {% trans "Editing" %} + {% else %} + {% trans "Add" %} + {% endif %} + {% trans "Invoice" %} + {% endslot %} + {% slot sub_heading %} + {% if object %} + {{ object.project.title }} + {% else %} + {% trans "For" %}: {{ project.title }} + {% endif %} + {% endslot %} + {% endadminbar %} {% include "forms/includes/form_errors.html" with form=form %} diff --git a/hypha/apply/projects/templates/application_projects/project_approval_form.html b/hypha/apply/projects/templates/application_projects/project_approval_form.html index e127b9860e37a209ccddd653dc71707bbbef09dc..234a84f7f977b7af2018f748a9d057e21d152f19 100644 --- a/hypha/apply/projects/templates/application_projects/project_approval_form.html +++ b/hypha/apply/projects/templates/application_projects/project_approval_form.html @@ -2,14 +2,15 @@ {% load i18n static %} {% block title %}{% trans "Editing" %}: {{object.title }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> + + {% adminbar %} + {% slot back_link %} <a class="simplified__projects-link" href="{{ object.get_absolute_url }}"> {% trans "View project page" %} </a> - <h2 class="heading heading--no-margin">{% trans "Editing" %}: {{ object.title }}</h2> - </div> - </div> + {% endslot %} + {% slot header %}{% trans "Editing" %}: {{ object.title }}{% endslot %} + {% endadminbar %} {% if approval_form_exists %} diff --git a/hypha/apply/projects/templates/application_projects/project_detail.html b/hypha/apply/projects/templates/application_projects/project_detail.html index 8d1626d4b30de70f09e6bd4f9ae5a72dcc9746e0..bc2b26c4cf128d709898e6a1728b868af8ad47a3 100644 --- a/hypha/apply/projects/templates/application_projects/project_detail.html +++ b/hypha/apply/projects/templates/application_projects/project_detail.html @@ -16,8 +16,8 @@ {% endif %} <div class="admin-bar"> <div class="admin-bar__inner"> - <h1 class="mb-0">{{ object.title }}</h1> - <div class="heading heading--meta text-sm mt-1"> + <h1 class="mb-0 font-medium">{{ object.title }}</h1> + <div class="heading heading--meta text-sm mt-1 font-medium"> <span>{{ object.submission.page }}</span> diff --git a/hypha/apply/projects/templates/application_projects/project_form.html b/hypha/apply/projects/templates/application_projects/project_form.html index 24ab8c832cb58b0d0449f528ea7e758b7f611b11..12a807df17b8a96ba01d0a0550cbd0d6f8775669 100644 --- a/hypha/apply/projects/templates/application_projects/project_form.html +++ b/hypha/apply/projects/templates/application_projects/project_form.html @@ -5,11 +5,10 @@ {% block title %}{% trans "Editing" %}: {{ object.title }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h2 class="heading heading--no-margin">{% trans "Editing" %}: {{ object.title}}</h2> - </div> - </div> + + {% adminbar %} + {% slot header %}{% trans "Editing" %}: {{ object.title}}{% endslot %} + {% endadminbar %} {% include "forms/includes/form_errors.html" with form=form %} diff --git a/hypha/apply/projects/templates/application_projects/report_detail.html b/hypha/apply/projects/templates/application_projects/report_detail.html index 25c9650fc74e4fce24fd2e68be94cea128cfa9e7..77cdde428681dddb2ab80d9048383ece6f701898 100644 --- a/hypha/apply/projects/templates/application_projects/report_detail.html +++ b/hypha/apply/projects/templates/application_projects/report_detail.html @@ -4,15 +4,16 @@ {% block title %}{% trans "Report" %} | {{ object.project.title }}{% endblock %} {% block body_class %}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> + + {% adminbar %} + {% slot back_link %} <a class="admin-bar__back-link" href="{{ object.project.get_absolute_url }}"> {% trans "View project page" %} </a> - <h2 class="heading heading--no-margin">{{ object.project.title }}</h2> - <h5 class="heading heading--no-margin">{% trans "View report" %}</h5> - </div> - </div> + {% endslot %} + {% slot header %}{{ object.project.title }}{% endslot %} + {% slot sub_heading %}{% trans "View report" %}{% endslot %} + {% endadminbar %} <div class="wrapper wrapper--sidebar wrapper--outer-space-medium"> <div class="wrapper--sidebar--inner"> diff --git a/hypha/apply/projects/templates/application_projects/report_form.html b/hypha/apply/projects/templates/application_projects/report_form.html index 00fab9e021299b7e91d5dab62724479d6b88a4fc..92a295b71b919eb65abac3e5830666674b67e886 100644 --- a/hypha/apply/projects/templates/application_projects/report_form.html +++ b/hypha/apply/projects/templates/application_projects/report_form.html @@ -8,15 +8,16 @@ {% block title %}{% trans "Edit Report" %} | {{ object.project.title }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> + + {% adminbar %} + {% slot back_link %} <a class="admin-bar__back-link" href="{{ object.project.get_absolute_url }}"> {% trans "View project page" %} </a> - <h2 class="heading heading--no-margin">{{ object.project.title }}</h2> - <h5 class="heading heading--no-margin">{% trans "Submit a report" %}</h5> - </div> - </div> + {% endslot %} + {% slot header %}{{ object.project.title }}{% endslot %} + {% slot sub_heading %}{% trans "Submit a report" %}{% endslot %} + {% endadminbar %} {% include "forms/includes/form_errors.html" with form=form %} diff --git a/hypha/apply/projects/templates/application_projects/vendor_detail.html b/hypha/apply/projects/templates/application_projects/vendor_detail.html index 5dedc1eacbef8af5cd077b741d20f626ac4c56fb..df79cf14dd0a9a59a99139a61acdb0238523f213 100644 --- a/hypha/apply/projects/templates/application_projects/vendor_detail.html +++ b/hypha/apply/projects/templates/application_projects/vendor_detail.html @@ -4,14 +4,15 @@ {% block title %}{% trans "Contracting Information for" %} {{ project.title }} {% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> + + {% adminbar %} + {% slot back_link %} <a class="simplified__projects-link" href="{{ project.get_absolute_url }}"> {% trans "View project page" %} </a> - <h2 class="heading heading--no-margin">{% trans "Contracting Information for" %} {{ project.title }}</h2> - </div> - </div> + {% endslot %} + {% slot header %}{% trans "Contracting Information for" %} {{ project.title }}{% endslot %} + {% endadminbar %} <div class="grid"> <div> diff --git a/hypha/apply/projects/templates/application_projects/vendor_form.html b/hypha/apply/projects/templates/application_projects/vendor_form.html index b14651f71f9d07e3a613855856dc76b41d1e0460..055b1ffd717ba53ea84b5ca340d4f66ef411f10e 100644 --- a/hypha/apply/projects/templates/application_projects/vendor_form.html +++ b/hypha/apply/projects/templates/application_projects/vendor_form.html @@ -3,11 +3,10 @@ {% block title %}{% trans "Update Contracting Information" %}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h2 class="heading heading--no-margin">{% trans "Update Contracting Information" %}</h2> - </div> - </div> + + {% adminbar %} + {% slot header %}{% trans "Update Contracting Information" %}{% endslot %} + {% endadminbar %} {% include "forms/includes/form_errors.html" with form=form %} diff --git a/hypha/apply/projects/templates/application_projects/vendor_success.html b/hypha/apply/projects/templates/application_projects/vendor_success.html index 8eccfba26cb0beb58ea863ed4fbd51e4d7ad33af..d6b079b4ffcf636f3419e45d648788233ecaa199 100644 --- a/hypha/apply/projects/templates/application_projects/vendor_success.html +++ b/hypha/apply/projects/templates/application_projects/vendor_success.html @@ -3,11 +3,11 @@ {% block title %}{% trans "Contractor Setup Completed" %}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h2 class="heading heading--no-margin">{% trans "Contractor Setup Completed" %}</h2> - </div> - </div> + + {% adminbar %} + {% slot header %}{% trans "Contractor Setup Completed" %}{% endslot %} + {% endadminbar %} + <div class="wrapper wrapper--small"> <h3>{% trans "Thank you for submitting your information." %}</h3> <p>{% trans "Your {{ ORG_SHORT_NAME }} Programme Manager will be in touch with you if there are any issues." %}</p> diff --git a/hypha/apply/projects/templatetags/contract_tools.py b/hypha/apply/projects/templatetags/contract_tools.py index 6373b9ab89d1f99cba9fc96f1458991f576e5ba3..ade13e0daa4f5567cde49efc3736cb78b182f80f 100644 --- a/hypha/apply/projects/templatetags/contract_tools.py +++ b/hypha/apply/projects/templatetags/contract_tools.py @@ -1,4 +1,5 @@ from django import template +from django.conf import settings from hypha.apply.projects.models.project import CONTRACTING @@ -59,6 +60,15 @@ def user_can_upload_contract(project, user): return can_upload +@register.simple_tag +def user_can_initiate_contract(user): + if user.is_contracting: + return True + if user.is_apply_staff and settings.STAFF_UPLOAD_CONTRACT: + return True + return False + + @register.simple_tag def show_contract_upload_row(project, user): if project.status != CONTRACTING: diff --git a/hypha/apply/projects/utils.py b/hypha/apply/projects/utils.py index b367f0ea5a08a754c0c7ac86bab50a1872d216f1..52718af26c9e78a8fe4f622157ce2a31450e9d97 100644 --- a/hypha/apply/projects/utils.py +++ b/hypha/apply/projects/utils.py @@ -11,6 +11,7 @@ from .models.payment import ( CHANGES_REQUESTED_BY_STAFF, DECLINED, PAID, + PAYMENT_FAILED, RESUBMITTED, SUBMITTED, ) @@ -136,6 +137,8 @@ def get_invoice_public_status(invoice_status): return _("Declined") if invoice_status == PAID: return _("Paid") + if invoice_status == PAYMENT_FAILED: + return _("Payment failed") def get_project_status_display_value(project_status): diff --git a/hypha/apply/projects/views/project.py b/hypha/apply/projects/views/project.py index fb0521ec9779db0fb6740ccb4017d864daa3fd5a..eb200582d09bcb29c1605753eb783b1e3c1bfb5e 100644 --- a/hypha/apply/projects/views/project.py +++ b/hypha/apply/projects/views/project.py @@ -123,6 +123,13 @@ class SendForApprovalView(DelegatedViewMixin, UpdateView): user=self.request.user, source=self.object, ) + messenger( + MESSAGES.APPROVE_PAF, + request=self.request, + user=self.request.user, + source=self.object, + related=[paf_approvals.first()], + ) else: messenger( MESSAGES.ASSIGN_PAF_APPROVER, @@ -138,6 +145,13 @@ class SendForApprovalView(DelegatedViewMixin, UpdateView): user=self.request.user, source=self.object, ) + messenger( + MESSAGES.APPROVE_PAF, + request=self.request, + user=self.request.user, + source=self.object, + related=paf_approvals.filter(user__isnull=False), + ) if paf_approvals.filter(user__isnull=True).exists(): messenger( MESSAGES.ASSIGN_PAF_APPROVER, @@ -643,12 +657,16 @@ class ChangePAFStatusView(DelegatedViewMixin, UpdateView): if project_settings.paf_approval_sequential: # notify next approver if self.object.paf_approvals.filter(approved=False).exists(): - if self.object.paf_approvals.filter(approved=False).first().user: + next_paf_approval = self.object.paf_approvals.filter( + approved=False + ).first() + if next_paf_approval.user: messenger( MESSAGES.APPROVE_PAF, request=self.request, user=self.request.user, source=self.object, + related=[next_paf_approval], ) else: messenger( @@ -776,6 +794,7 @@ class UpdateAssignApproversView(DelegatedViewMixin, UpdateView): request=self.request, user=self.request.user, source=self.object, + related=[paf_approval], ) else: messenger( @@ -831,6 +850,7 @@ class UpdatePAFApproversView(DelegatedViewMixin, UpdateView): request=self.request, user=self.request.user, source=self.object, + related=[paf_approvals.first()], ) elif not user: messenger( @@ -846,6 +866,7 @@ class UpdatePAFApproversView(DelegatedViewMixin, UpdateView): request=self.request, user=self.request.user, source=self.object, + related=paf_approvals.filter(user__isnull=False), ) if paf_approvals.filter(user__isnull=True).exists(): messenger( @@ -861,6 +882,7 @@ class UpdatePAFApproversView(DelegatedViewMixin, UpdateView): request=self.request, user=self.request.user, source=self.object, + related=paf_approvals.filter(user__isnull=False), ) if paf_approvals.filter(user__isnull=True).exists(): messenger( diff --git a/hypha/apply/review/templates/review/review_confirm_delete.html b/hypha/apply/review/templates/review/review_confirm_delete.html index 21238b428002c3a7369f43027bbbb54dae56fe34..93649eacf87f3e22f2665b56d112a035550ddc8c 100644 --- a/hypha/apply/review/templates/review/review_confirm_delete.html +++ b/hypha/apply/review/templates/review/review_confirm_delete.html @@ -4,11 +4,10 @@ {% block title %}{% trans "Deleting" %}: {{ object }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h2 class="heading heading--no-margin">{% trans "Deleting" %}: {{ object }}</h2> - </div> - </div> + + {% adminbar %} + {% slot header %}{% trans "Deleting" %}: {{ object }}{% endslot %} + {% endadminbar %} <div class="wrapper wrapper--light-grey-bg wrapper--form wrapper--sidebar"> <div class="wrapper--sidebar--inner"> diff --git a/hypha/apply/review/templates/review/review_detail.html b/hypha/apply/review/templates/review/review_detail.html index 0378a705845cf1834a6ee587f41b0df832602ea1..5295084938a74ce9279935ad97c0e748e5018279 100644 --- a/hypha/apply/review/templates/review/review_detail.html +++ b/hypha/apply/review/templates/review/review_detail.html @@ -2,17 +2,20 @@ {% load i18n bleach_tags submission_tags %} {% block title %}{% trans "Review for" %} {{ review.submission.title }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> + + {% adminbar %} + {% slot back_link %} <a class="simplified__submissions-link" href="{{ review.submission.get_absolute_url }}"> - {% trans "Back to submission" %} + {% trans "View submission" %} </a> - <h1 class="beta heading heading--no-margin heading--bold">{% trans "Review" %}</h1> - <h5>{% trans "For" %}: {{ review.submission.title }} {% trans "by" %} {{ review.author }} {% trans "at" %} {{ review.created_at|date:"SHORT_DATE_FORMAT" }} {% if review.is_updated %}<small>({% trans "Last updated" %}: {{ review.updated_at|date:"SHORT_DATE_FORMAT" }})</small>{% endif %}</h5> + {% endslot %} + {% slot header %}{% trans "Review" %}{% endslot %} + {% slot sub_heading %} + {% trans "For" %}: {{ review.submission.title }} {% trans "by" %} {{ review.author }} {% trans "at" %} {{ review.created_at|date:"SHORT_DATE_FORMAT" }} {% if review.is_updated %}<small>({% trans "Last updated" %}: {{ review.updated_at|date:"SHORT_DATE_FORMAT" }})</small>{% endif %} + {% endslot %} - {% include 'review/includes/review_opinions_list.html' with opinions=review.opinions.all %} - </div> - </div> + {% include 'review/includes/review_opinions_list.html' with opinions=review.opinions.all %} + {% endadminbar %} <div style="display: flex; gap: 2rem; padding-top: 2rem;"> <div> @@ -57,7 +60,9 @@ <div class="rich-text rich-text--answers"> {{ object.get_comments_display|submission_links }} - {{ object.output_answers|submission_links }} + <div class="prose"> + {{ object.output_answers|submission_links }} + </div> </div> {% if form %} diff --git a/hypha/apply/review/templates/review/review_edit_form.html b/hypha/apply/review/templates/review/review_edit_form.html index 5bff82873b6eebc2e8fb0d516d5afc5036f3ddee..c8581d99d9c3227baaf28aff27938adbf1d48616 100644 --- a/hypha/apply/review/templates/review/review_edit_form.html +++ b/hypha/apply/review/templates/review/review_edit_form.html @@ -2,12 +2,13 @@ {% load i18n static %} {% block title %}{{ title }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h1 class="beta heading heading--no-margin heading--bold">{{ title }}</h1> - <h5>{% trans "For" %} <a href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title }}</a></h5> - </div> - </div> + + {% adminbar %} + {% slot header %}{{ title }}{% endslot %} + {% slot sub_heading %} + {% trans "For" %} <a class="text-blue-300 hover:underline" href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title }}</a> + {% endslot %} + {% endadminbar %} {% include "forms/includes/form_errors.html" with form=form %} diff --git a/hypha/apply/review/templates/review/review_form.html b/hypha/apply/review/templates/review/review_form.html index b91b617680d0db5c599d697d998f9469c773a2d8..971ede53b234284774ea9c27e06867afdadfbda3 100644 --- a/hypha/apply/review/templates/review/review_form.html +++ b/hypha/apply/review/templates/review/review_form.html @@ -2,12 +2,13 @@ {% load i18n static %} {% block title %}{{ title }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h1 class="beta heading heading--no-margin heading--bold">{{ title }}</h1> - <h5>{% trans "For" %} <a href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title }}</a></h5> - </div> - </div> + + {% adminbar %} + {% slot header %}{{ title }}{% endslot %} + {% slot sub_heading %} + {% trans "For" %} <a href="{% url "funds:submissions:detail" submission.id %}">{{ submission.title }}</a> + {% endslot %} + {% endadminbar %} {% include "forms/includes/form_errors.html" with form=form %} diff --git a/hypha/apply/review/templates/review/reviewopinion_confirm_delete.html b/hypha/apply/review/templates/review/reviewopinion_confirm_delete.html index 21238b428002c3a7369f43027bbbb54dae56fe34..93649eacf87f3e22f2665b56d112a035550ddc8c 100644 --- a/hypha/apply/review/templates/review/reviewopinion_confirm_delete.html +++ b/hypha/apply/review/templates/review/reviewopinion_confirm_delete.html @@ -4,11 +4,10 @@ {% block title %}{% trans "Deleting" %}: {{ object }}{% endblock %} {% block content %} - <div class="admin-bar"> - <div class="admin-bar__inner"> - <h2 class="heading heading--no-margin">{% trans "Deleting" %}: {{ object }}</h2> - </div> - </div> + + {% adminbar %} + {% slot header %}{% trans "Deleting" %}: {{ object }}{% endslot %} + {% endadminbar %} <div class="wrapper wrapper--light-grey-bg wrapper--form wrapper--sidebar"> <div class="wrapper--sidebar--inner"> diff --git a/hypha/apply/stream_forms/templates/stream_forms/render_field.html b/hypha/apply/stream_forms/templates/stream_forms/render_field.html index a6bb449491145120bdcdcb42e1bbf4f153c01ada..89c950364e1bbff6ae253d49caa3c6d999ec3c31 100644 --- a/hypha/apply/stream_forms/templates/stream_forms/render_field.html +++ b/hypha/apply/stream_forms/templates/stream_forms/render_field.html @@ -1,9 +1,9 @@ {% if include_question %} - <section> - <h4 class="question">{{ value.field_label }}</h4> + <section class=""> + <h4 class="question text-xl font-bold border-b mb-2 py-2">{{ value.field_label }}</h4> {% endif %} -<div class="answer"> +<div class="answer prose max-w-none"> {% block data_display %}<p>{{ data }}</p>{% endblock %} </div> diff --git a/hypha/apply/templates/forms/includes/field.html b/hypha/apply/templates/forms/includes/field.html index aa2d7f8a8118ea64051b15f16163ad171b16f054..fe0d83a34d330a9dfb4b10c33630f1248686f496 100644 --- a/hypha/apply/templates/forms/includes/field.html +++ b/hypha/apply/templates/forms/includes/field.html @@ -1,12 +1,15 @@ {% load i18n util_tags %} -{% load bleach_tags markdown_tags %} +{% load bleach_tags markdown_tags heroicons %} {% with widget_type=field|widget_type field_type=field|field_type %} <div class="form__group {{ field.id_for_label }} form__group--{{ widget_type }} {% if widget_type == 'checkbox_input' %} form__group--checkbox{% endif %}{% if widget_type == 'clearable_file_input' or widget_type == 'multi_file_input' or widget_type == 'single_file_field_widget' or widget_type == 'multi_file_field_widget' %} form__group--file{% endif %}{% if field.help_text %} form__group--wrap{% endif %}{% if field.errors %} form__error{% endif %}{% if is_application and field.field.group_number > 1 %} field-group field-group-{{ field.field.group_number }}{% endif %}{% if is_application and field.field.grouper_for %} form-fields-grouper{% endif %}"{% if is_application and field.field.grouper_for %}data-grouper-for="{{ field.field.grouper_for }}" data-toggle-on="{{ field.field.choices.0.0 }}" data-toggle-off="{{ field.field.choices.1.0 }}"{% endif %}{% if is_application and field.field.group_number > 1 %} data-hidden="{% if not show_all_group_fields and not field.field.visible %}true{% else %}false{% endif %}" data-required="{{ field.field.required_when_visible }}"{% endif %}{% if field.field.word_limit %} data-word-limit="{{ field.field.word_limit }}"{% endif %}> {% if widget_type == 'clearable_file_input' or widget_type == 'multi_file_input' or widget_type == 'single_file_field_widget' or widget_type == 'multi_file_field_widget'%} <span class="form__question form__file-label">{{ field.label }}</span> - <label for="{{ field.id_for_label }}" class="form__question form__question--{{ field_type }} {{ widget_type }}" {% if field.field.required %}required{% endif %}> - <span>{% trans "Upload" %}</span> + <label for="{{ field.id_for_label }}" class="mb-2 form__question form__question--{{ field_type }} {{ widget_type }}" {% if field.field.required %}required{% endif %}> + <span class="whitespace-nowrap"> + {% heroicon_mini "arrow-up-tray" size=18 class="inline mr-1" aria_hidden="true" %} + {% trans "Upload" %} + </span> {% if field.field.required %} <span class="form__required">*</span> {% endif %} diff --git a/hypha/apply/users/templates/wagtailusers/users/results.html b/hypha/apply/users/templates/wagtailusers/users/results.html index 3b350343fb6ceb8ab7a528c2472ead0fb3c4609c..255e85b59a185d3818f8d4b5230becb6078f638a 100644 --- a/hypha/apply/users/templates/wagtailusers/users/results.html +++ b/hypha/apply/users/templates/wagtailusers/users/results.html @@ -17,7 +17,7 @@ {% include "wagtailusers/users/list.html" %} {# call pagination_nav with no linkurl, to generate general-purpose links like <a href="?p=2"> #} - {% include "wagtailadmin/shared/pagination_nav.html" with items=page_obj %} + {% include "wagtailadmin/shared/pagination_nav.html" with items=users %} {% else %} {% if is_searching %} <h2 role="alert">{% blocktrans trimmed %}Sorry, no users match "<em>{{ query_string }}</em>"{% endblocktrans %}</h2> diff --git a/hypha/core/templates/components/admin_bar.html b/hypha/core/templates/components/admin_bar.html index 05b8a1e632801fa31be0b5b815eb6a29fb903a98..4c8d138fa1b318b300d02601831099961f858c46 100644 --- a/hypha/core/templates/components/admin_bar.html +++ b/hypha/core/templates/components/admin_bar.html @@ -4,7 +4,7 @@ <div class="admin-bar__inner items-center md:flex md:justify-between"> <div> {% render_slot slots.back_link %} - <h1 class="text-2xl mb-0 md:text-3xl md:m-0">{% render_slot slots.header %}</h1> + <h1 class="text-2xl mb-2 font-medium md:text-3xl md:m-0">{% render_slot slots.header %}</h1> {% if slots.sub_heading %}<p class="text-sm hidden md:block m-0">{% render_slot slots.sub_heading %}</p>{% endif %} </div> diff --git a/hypha/public/utils/migrations/0008_systemmessagessettings_nav_content.py b/hypha/public/utils/migrations/0008_systemmessagessettings_nav_content.py new file mode 100644 index 0000000000000000000000000000000000000000..3f2e607e93cbd999ca05093f97dddf7d72d7ab3c --- /dev/null +++ b/hypha/public/utils/migrations/0008_systemmessagessettings_nav_content.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.20 on 2023-10-06 15:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("utils", "0007_remove_systemmessagessettings_site"), + ] + + operations = [ + migrations.AddField( + model_name="systemmessagessettings", + name="nav_content", + field=models.TextField( + blank=True, + help_text="This will overwrite the default front page navigation bar, html tags is allowed.", + verbose_name="Front page navigation content", + ), + ), + ] diff --git a/hypha/public/utils/models.py b/hypha/public/utils/models.py index 54c27900b258d0109e0ecfdb4844b92844ec488d..f98c22130e43b1e56322fa5534cd2257f8450703 100644 --- a/hypha/public/utils/models.py +++ b/hypha/public/utils/models.py @@ -320,6 +320,14 @@ class SystemMessagesSettings(BaseGenericSetting): ), ) + nav_content = models.TextField( + "Front page navigation content", + help_text=_( + "This will overwrite the default front page navigation bar, html tags is allowed." + ), + blank=True, + ) + footer_content = models.TextField( "Footer content", default="<p>Configure this text in Wagtail admin -> Settings -> System settings.</p>", @@ -345,6 +353,7 @@ class SystemMessagesSettings(BaseGenericSetting): ], "Site logo", ), + FieldPanel("nav_content"), FieldPanel("footer_content"), MultiFieldPanel( [ diff --git a/hypha/settings/base.py b/hypha/settings/base.py index 6b18d44ff5c083ad9c95c3c44839557664a172a7..02a406f429c0016cc1f68080f1ccdb3832c63c30 100644 --- a/hypha/settings/base.py +++ b/hypha/settings/base.py @@ -88,6 +88,9 @@ SHOW_APPLY_BUTTON_ON_HOME = env.bool("SHOW_APPLY_BUTTON_ON_HOME", True) # If automatic e-mails should be sent out to reviewers when submissions are ready for review. SEND_READY_FOR_REVIEW = env.bool("SEND_READY_FOR_REVIEW", True) +# Staff can upload the contract +STAFF_UPLOAD_CONTRACT = env.bool("STAFF_UPLOAD_CONTRACT", False) + # Slack settings. SLACK_TOKEN = env.str("SLACK_TOKEN", None) SLACK_USERNAME = env.str("SLACK_USERNAME", "Hypha") diff --git a/hypha/static_src/src/javascript/apply/determination-template.js b/hypha/static_src/src/javascript/apply/determination-template.js index 979535ff38d50fde5af5d61152a20926f5e8e89a..59df5e50936eb32720b12d4ed814d9d438759b95 100644 --- a/hypha/static_src/src/javascript/apply/determination-template.js +++ b/hypha/static_src/src/javascript/apply/determination-template.js @@ -69,6 +69,9 @@ new DeterminationCopy(el); }); window.addEventListener("load", function (event) { - document.querySelector("#id_proposal_form").disabled = true; + const proposal_form_field = document.querySelector("#id_proposal_form"); + if (!proposal_form_field.value) { + proposal_form_field.disabled = true; + } }); })(); diff --git a/hypha/static_src/src/sass/apply/abstracts/_mixins.scss b/hypha/static_src/src/sass/apply/abstracts/_mixins.scss index 20d7fe93e608107988dea61c807af82753a92ceb..36660810b28f278076114b1630d7c3683993456e 100644 --- a/hypha/static_src/src/sass/apply/abstracts/_mixins.scss +++ b/hypha/static_src/src/sass/apply/abstracts/_mixins.scss @@ -95,7 +95,7 @@ @include media-query(mob-landscape) { width: auto; - text-align: left; + // text-align: left; } &:hover, diff --git a/hypha/static_src/src/sass/apply/components/_file-form.scss b/hypha/static_src/src/sass/apply/components/_file-form.scss deleted file mode 100644 index acce1c118be87927ec75f44f231806e9e7605690..0000000000000000000000000000000000000000 --- a/hypha/static_src/src/sass/apply/components/_file-form.scss +++ /dev/null @@ -1,4 +0,0 @@ -.dff-uploader .dff-files .dff-delete { - margin: 8px; - color: $color--tomato; -} diff --git a/hypha/static_src/src/sass/apply/components/_form.scss b/hypha/static_src/src/sass/apply/components/_form.scss index 7be96f9f9a6e5f69af687c547c1657c2a9b53f25..2e6b4a99c97128ca398af7c061670869747aa714 100644 --- a/hypha/static_src/src/sass/apply/components/_form.scss +++ b/hypha/static_src/src/sass/apply/components/_form.scss @@ -120,10 +120,8 @@ &--single_file_field, &--file_field { @include button($color--light-blue, $color--darkest-blue); - max-width: 290px; + max-width: 15rem; text-align: center; - background: url("./../../images/upload.svg") $color--light-blue - no-repeat 20px center; border: 0; .no-js & { @@ -135,9 +133,6 @@ } &:hover { - background: url("./../../images/upload.svg") $color--dark-blue - no-repeat 20px center; - .no-js & { background: none; } diff --git a/hypha/static_src/src/sass/apply/components/_rich-text.scss b/hypha/static_src/src/sass/apply/components/_rich-text.scss index 8b6e35aa7edf17345cccb44fe3ea23c20ba9fcc4..313ff3b329f5798f76f7abb5b90b0c82b1ba2d26 100644 --- a/hypha/static_src/src/sass/apply/components/_rich-text.scss +++ b/hypha/static_src/src/sass/apply/components/_rich-text.scss @@ -18,25 +18,38 @@ } h1 { - font-size: 20px; - font-family: $font--primary; + font-size: 1.296rem; + margin-bottom: 1em; + font-weight: 600; + line-height: 1.3333; + } + + h1:not(:first-child) { + margin-top: 2em; } h2 { - font-size: 18px; - font-family: $font--primary; + font-size: 1.215rem; + margin-top: 1.6em; + margin-bottom: 0.6em; + line-height: 1.6; + font-weight: 600; } h3, - h4:not(.question), - h5, - h6 { - font-size: 16px; - font-family: $font--primary; + h4:not(.question) { + font-size: 1.138rem; + margin-top: 1.5em; + margin-bottom: 0.5em; + line-height: 1.5; } - .question { - margin: 0; + h5, + h6 { + font-size: 1.067rem; + margin-top: 1.4em; + margin-bottom: 0.4em; + line-height: 1.4; } &--hidden { @@ -47,23 +60,26 @@ } } + // This is a hack to make sure a copy pasted table with width property on it + // doesn't break the layout. The margin from the table is removed and transferred + // to the parent element, because the table is wrapped in a div with overflow: auto &__table { overflow: auto; + margin-top: 1.25em; + margin-bottom: 1.25em; + + > table { + margin-top: 0; + margin-bottom: 0; + } } ul { - padding-left: 20px; - list-style: outside disc; - &.remove-list-style { padding: 0; list-style: none; } } - - ol { - list-style: inside decimal; - } } .tox-statusbar { diff --git a/hypha/static_src/src/sass/apply/components/_status-bar.scss b/hypha/static_src/src/sass/apply/components/_status-bar.scss index c39210ab5b08630a42a545135996482f6aa880fe..fbbdb8c6fdaab92f58192065a439209b13eca169 100644 --- a/hypha/static_src/src/sass/apply/components/_status-bar.scss +++ b/hypha/static_src/src/sass/apply/components/_status-bar.scss @@ -19,7 +19,6 @@ width: 100%; max-width: 800px; margin-right: 40px; - color: $color--white; } &__subheading { @@ -139,7 +138,7 @@ width: 20px; height: 20px; border-radius: 50%; - opacity: 0; + opacity: 1; transition: opacity $transition; .status-bar__item:first-of-type & { @@ -150,15 +149,12 @@ opacity: 1; } - // triangle &::before { - @include triangle(top, $color--error, 5px); - position: absolute; - bottom: -10px; - left: 5px; - - .status-bar__item--is-complete & { - @include triangle(top, $color--primary, 5px); + .status-bar__item--is-current & { + @include triangle(top, $color--error, 5px); + position: absolute; + bottom: -10px; + left: 5px; } } @@ -167,6 +163,7 @@ position: absolute; top: 30px; left: -25px; + text-align: center; display: block; padding: 5px 10px; font-size: 12px; @@ -196,13 +193,20 @@ } } + .status-bar__item & { + background-color: inherit; + color: $color--mid-grey; + } + .status-bar__item--is-complete & { - background-color: $color--primary; + background-color: inherit; + color: $color--primary; } - } - &:hover { - opacity: 1; + .status-bar__item--is-current & { + background-color: $color--tomato; + color: $color--white; + } } } } diff --git a/hypha/static_src/src/sass/apply/main.scss b/hypha/static_src/src/sass/apply/main.scss index 2f7b7945dfc4385e9e292f432d1432dd89088a42..40ed6f1c793e4f81f83f4ba159437811792b7889 100644 --- a/hypha/static_src/src/sass/apply/main.scss +++ b/hypha/static_src/src/sass/apply/main.scss @@ -71,7 +71,6 @@ @import "components/activity-notifications"; @import "components/dropdown"; @import "components/banner"; -@import "components/file-form"; // Layout @import "layout/header"; diff --git a/hypha/static_src/src/tailwind/components/django-file-field.css b/hypha/static_src/src/tailwind/components/django-file-field.css new file mode 100644 index 0000000000000000000000000000000000000000..568c295e27ed276b7af1bcb3aa354a89feeaa68f --- /dev/null +++ b/hypha/static_src/src/tailwind/components/django-file-field.css @@ -0,0 +1,15 @@ +.dff-uploader .dff-files { + @apply !m-0 shadow-inner !outline-dashed rounded-sm; +} + +.dff-uploader .dff-files .dff-filesize { + @apply text-fg-muted text-sm; +} + +.dff-uploader .dff-files.dff-dropping { + @apply !ring-2 ring-offset-4; +} + +.dff-uploader .dff-files .dff-delete { + @apply !text-red-500 font-medium before:content-['•'] before:mr-2; +} diff --git a/hypha/static_src/src/tailwind/main.css b/hypha/static_src/src/tailwind/main.css index ea30c4c211e6005b01d9cc797c6e57ed3bac61ef..568910496723771fa9aaa41343eca98da20c3745 100644 --- a/hypha/static_src/src/tailwind/main.css +++ b/hypha/static_src/src/tailwind/main.css @@ -6,6 +6,7 @@ @import "tailwindcss/components"; @import "./components/choices.css"; @import "./components/daterangepicker.css"; +@import "./components/django-file-field.css"; @import "tailwindcss/utilities"; /* @import "./custom-utilities.css"; */ diff --git a/hypha/templates/base-apply.html b/hypha/templates/base-apply.html index 4a77b1cb89232cefda582ca6b2c670ff7cdd93d4..7036e103cecb5ce824ab2c218e4aa2a126d907c0 100644 --- a/hypha/templates/base-apply.html +++ b/hypha/templates/base-apply.html @@ -102,7 +102,12 @@ </div> <section class="header__menus header__menus--desktop"> - {% include "navigation/primarynav-apply.html" %} + {% if settings.utils.SystemMessagesSettings.nav_content %} + {{ settings.utils.SystemMessagesSettings.nav_content|safe }} + {% else %} + {% include "navigation/primarynav-apply.html" %} + {% endif %} + </section> <section class="header__menus header__menus--mobile"> @@ -122,7 +127,11 @@ </div> </div> - {% include "navigation/primarynav-apply.html" %} + {% if settings.utils.SystemMessagesSettings.nav_content %} + {{ settings.utils.SystemMessagesSettings.nav_content|safe }} + {% else %} + {% include "navigation/primarynav-apply.html" %} + {% endif %} {% if request.user.is_authenticated %} <a href="{% url 'users:account' %}" class="link link--button-transparent link--mobile-standout"> diff --git a/hypha/templates/base.html b/hypha/templates/base.html index 2f0d3bdae52fe92e2b3ef724b14b147e34530f8a..ea509f1602f7b998ee6566620e4d2e74510ae8c7 100644 --- a/hypha/templates/base.html +++ b/hypha/templates/base.html @@ -111,10 +111,13 @@ </div> <section class="header__menus header__menus--desktop"> - {% cache 3600 navigation__primary current_site %} - {% primarynav %} - {% endcache %} - + {% if settings.utils.SystemMessagesSettings.nav_content %} + {{ settings.utils.SystemMessagesSettings.nav_content|safe }} + {% else %} + {% cache 3600 navigation__primary current_site %} + {% primarynav %} + {% endcache %} + {% endif %} <button class="button button--contains-icons button--left-space js-search-toggle" aria-haspopup="true" aria-label="Toggle desktop search"> <svg class="header__icon header__icon--open-search icon"><use xlink:href="#magnifying-glass"></use></svg> <svg class="header__icon header__icon--close-search icon"><use xlink:href="#cross"></use></svg> @@ -140,9 +143,13 @@ </button> </div> </div> - {% cache 3600 navigation__primary current_site %} - {% primarynav %} - {% endcache %} + {% if settings.utils.SystemMessagesSettings.nav_content %} + {{ settings.utils.SystemMessagesSettings.nav_content|safe }} + {% else %} + {% cache 3600 navigation__primary current_site %} + {% primarynav %} + {% endcache %} + {% endif %} </section> <div class="header__button-container"> diff --git a/mkdocs.yml b/mkdocs.yml index 3683b649747a136bcfd4e482ca9dc49a6d0de8e6..5607f87c902120705ffbbb6b0661a874e83cbac4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,8 +47,8 @@ markdown_extensions: - admonition - attr_list - pymdownx.emoji: - emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg - md_in_html - def_list - footnotes diff --git a/package-lock.json b/package-lock.json index 853ea3238ecb056bb54763c741295162d524a398..e026de4a06db354d4ef3dc33eb76bdae998fc9e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -108,12 +108,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -159,12 +160,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz", - "integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -273,22 +274,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -451,9 +452,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -498,13 +499,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -512,9 +513,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz", - "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1719,33 +1720,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz", - "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.7", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/types": "^7.22.5", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1754,13 +1755,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -4559,9 +4560,9 @@ } }, "node_modules/postcss": { - "version": "8.4.25", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz", - "integrity": "sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "dev": true, "funding": [ { diff --git a/requirements-dev.txt b/requirements-dev.txt index 9299effe6f78c5aa0ae0b22ded44f5c3ad5758fb..e527803d11cc0f65a91342c8c45e732edfb6610e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,20 +1,20 @@ -r requirements.txt -black==23.7.0 -coverage==6.4.4 -django-browser-reload==1.6.0 -django-coverage-plugin==2.0.3 -django-debug-toolbar==3.8.1 +black==23.10.0 +coverage==7.3.2 +django-browser-reload==1.12.0 +django-coverage-plugin==3.1.0 +django-debug-toolbar==4.2.0 djhtml==3.0.6 dslr==0.4.0 factory_boy==3.2.1 model-bakery==1.10.1 pre-commit==3.3.3 -pytest-cov==4.0.0 +pytest-cov==4.1.0 pytest-django==4.5.2 -pytest-split==0.8.0 -pytest-xdist[psutil]==3.1.0 -responses==0.22.0 -ruff==0.0.263 +pytest-split==0.8.1 +pytest-xdist[psutil]==3.3.1 +responses==0.23.3 +ruff==0.1.1 wagtail-factories==2.1.0 -Werkzeug==2.2.3 +Werkzeug==3.0.1 diff --git a/requirements-docs.txt b/requirements-docs.txt index 6cecfdc6c7dc516a2024e5d919b4854df6646401..6b8036460bb243d69998c0d655a0cf8e3aea2b68 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -1,3 +1,3 @@ -mkdocs-material==9.0.12 -mkdocs-awesome-pages-plugin==2.8.0 -mkdocs-git-revision-date-localized-plugin +mkdocs-material==9.4.6 +mkdocs-awesome-pages-plugin==2.9.2 +mkdocs-git-revision-date-localized-plugin==1.2.1 diff --git a/requirements.txt b/requirements.txt index f04bb7ca56db8e9e54823f73e2cac966b356d9d9..2f143c9ec5d1d91f72cfffbc63e43625099754f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,23 +5,23 @@ sentry-sdk==1.16.0 # Production dependencies Babel==2.11.0 bleach==5.0.0 -boto3==1.26.57 +boto3==1.28.68 celery==5.2.7 -click==8.1.3 dj-database-url==0.5.0 +click==8.1.7 django-anymail==9.0 django-basic-auth-ip-whitelist==0.3.4 django-bleach==3.0.1 -django-countries==7.5 +django-countries==7.5.1 django-elevate==2.0.3 -django-extensions==3.2.1 +django-extensions==3.2.3 django-file-form==3.4.3 django-filter==2.4.0 django-formtools==2.4.1 django-fsm==2.8.1 django-heroku==0.3.1 django-hijack==3.2.6 -django-htmx==1.13.0 +django-htmx==1.17.0 django-pagedown==2.2.1 django-pwned-passwords==4.1.0 django-ratelimit==4.0.0 @@ -33,30 +33,31 @@ django-tables2==2.5.1 django-tinymce==3.5.0 django-two-factor-auth==1.14.0 django-web-components==0.1.1 -django==3.2.22 +django==3.2.23 djangorestframework-api-key==2.3.0 djangorestframework==3.14.0 drf-nested-routers==0.93.4 drf-yasg==1.21.4 environs==9.5.0 gunicorn==20.1.0 -heroicons==2.2.0 +heroicons==2.5.0 +python-docx<1.0.0 htmldocx==0.0.6 -lark==1.1.5 +lark==1.1.7 mailchimp3==3.0.17 mistune==2.0.4 more-itertools==9.0.0 -phonenumberslite==8.13.4 +phonenumberslite==8.13.23 Pillow==9.4.0 psycopg2-binary qrcode==7.4.2 reportlab==3.6.13 social_auth_app_django==5.0.0 -tablib==3.3.0 +tablib==3.5.0 tomd==0.1.3 wagtail-cache==2.2.0 wagtail-purge==0.2 wagtail==4.2.2 whitenoise==5.3.0 -xhtml2pdf==0.2.8 +xhtml2pdf==0.2.11 xmltodict==0.13.0