diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..fc30a2c1307a3f7d91142902220e934416c21a62 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Django", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/manage.py", + "args": [ + "runserver", + "0.0.0.0:8090" + ], + "django": true + } + ] +} diff --git a/hypha/apply/activity/adapters/__init__.py b/hypha/apply/activity/adapters/__init__.py index 629cb18a20e8327a409eff477c7c9c92d75b1372..8e827dad2220209cc1e812174d2e85497096c7ef 100644 --- a/hypha/apply/activity/adapters/__init__.py +++ b/hypha/apply/activity/adapters/__init__.py @@ -5,9 +5,9 @@ from .emails import EmailAdapter from .slack import SlackAdapter __all__ = [ - AdapterBase, - ActivityAdapter, - DjangoMessagesAdapter, - EmailAdapter, - SlackAdapter, + "AdapterBase", + "ActivityAdapter", + "DjangoMessagesAdapter", + "EmailAdapter", + "SlackAdapter", ] diff --git a/hypha/apply/activity/context_processors.py b/hypha/apply/activity/context_processors.py index 975680a3c1a58d4bec894d1d395eb519410fe01c..1522f47ea37d6e69bca5c8a995e141513a205e78 100644 --- a/hypha/apply/activity/context_processors.py +++ b/hypha/apply/activity/context_processors.py @@ -5,5 +5,5 @@ def notification_context(request): context_data = dict() if hasattr(request, 'user'): if request.user.is_authenticated and request.user.is_apply_staff: - context_data['latest_notifications'] = Activity.objects.latest().order_by('-timestamp')[:5] + context_data['latest_notifications'] = Activity.objects.filter(current=True).latest().order_by('-timestamp')[:5] return context_data diff --git a/hypha/apply/activity/messaging.py b/hypha/apply/activity/messaging.py index 74d095ed15d3b9ee7d5ca38f7de2a59e9404bbf0..571cc5c58d245089b352b9f958241cb8d4ab542a 100644 --- a/hypha/apply/activity/messaging.py +++ b/hypha/apply/activity/messaging.py @@ -11,8 +11,8 @@ from .options import MESSAGES # noqa class MessengerBackend: - def __init__(self, *adpaters): - self.adapters = adpaters + def __init__(self, *adapters): + self.adapters = adapters def __call__(self, *args, related=None, **kwargs): return self.send(*args, related=related, **kwargs) diff --git a/hypha/apply/activity/templates/messages/email/submission_confirmation.html b/hypha/apply/activity/templates/messages/email/submission_confirmation.html index 24ab2d9fde1f29b1efc32941aa46cb63fd85c8c8..84c1eea07c54f89546c5ebf7ac0a886f2f1f9aa2 100644 --- a/hypha/apply/activity/templates/messages/email/submission_confirmation.html +++ b/hypha/apply/activity/templates/messages/email/submission_confirmation.html @@ -1,7 +1,9 @@ {% extends "messages/email/base.html" %} {% load i18n %} -{% block content %}{% blocktrans with title=source.title %}We appreciate your {{ title }} application submission to the {{ ORG_LONG_NAME }}. We will review and reply to your submission as quickly as possible.{% endblocktrans %} +{% block content %}{% blocktrans with title=source.title %}We appreciate your {{ title }} application submission to the {{ ORG_LONG_NAME }}.{% endblocktrans %} + +{% if source.is_draft %}{% trans "Please note that it is not submitted for review because it's still in draft." %} {% trans "You can access the draft at" %}: {{ request.scheme }}://{{ request.get_host }}{{ source.get_absolute_url }}{% else %}{% trans "We will review and reply to your submission as quickly as possible." %}{% endif %} {% trans "If you have any questions, please submit them here" %}: {{ request.scheme }}://{{ request.get_host }}{{ source.get_absolute_url }}#communications diff --git a/hypha/apply/activity/views.py b/hypha/apply/activity/views.py index 0af55e2b554adbd9aa64bce00b9415388a0cdf3c..1a1be200ff95ef1f74e4b8afec919bb099955455 100644 --- a/hypha/apply/activity/views.py +++ b/hypha/apply/activity/views.py @@ -70,7 +70,7 @@ class NotificationsView(ListView): def get_queryset(self): # List only last 30 days' activities - queryset = Activity.objects.latest() + queryset = Activity.objects.filter(current=True).latest() self.filterset = self.filterset_class(self.request.GET, queryset=queryset) return self.filterset.qs.distinct().order_by('-timestamp') diff --git a/hypha/apply/funds/files.py b/hypha/apply/funds/files.py index b5ee6c23ea36005f9d54691068f70c10d2500d62..1862c800f3b13e2da23f1d6c61f120a6541f3089 100644 --- a/hypha/apply/funds/files.py +++ b/hypha/apply/funds/files.py @@ -14,20 +14,23 @@ def generate_submission_file_path(submission_id, field_id, file_name): class SubmissionStreamFieldFile(StreamFieldFile): - def generate_filename(self): + + def get_submission_id(self): from hypha.apply.funds.models.submissions import ApplicationRevision submission_id = self.instance.pk if isinstance(self.instance, ApplicationRevision): submission_id = self.instance.submission.pk + return submission_id - return generate_submission_file_path(submission_id, self.field.id, self.name) + def generate_filename(self): + return generate_submission_file_path(self.get_submission_id(), self.field.id, self.name) @property def url(self): return reverse( 'apply:submissions:serve_private_media', kwargs={ - 'pk': self.instance.pk, + 'pk': self.get_submission_id(), 'field_id': self.field.id, 'file_name': self.basename, } diff --git a/hypha/apply/funds/models/submissions.py b/hypha/apply/funds/models/submissions.py index de5089145b41f0006039c276ae2f3afe62bedff3..ca9df897b964850ba32e4da407a86c67958e6b96 100644 --- a/hypha/apply/funds/models/submissions.py +++ b/hypha/apply/funds/models/submissions.py @@ -484,7 +484,7 @@ class ApplicationSubmission( submit_time = models.DateTimeField(verbose_name=_('submit time'), auto_now_add=False) - is_draft = False + _is_draft = False live_revision = models.OneToOneField( 'ApplicationRevision', @@ -506,6 +506,10 @@ class ApplicationSubmission( objects = ApplicationSubmissionQueryset.as_manager() + @property + def is_draft(self): + return self.status == DRAFT_STATE + def not_progressed(self): return not self.next @@ -613,12 +617,12 @@ class ApplicationSubmission( submission_in_db.save() def new_data(self, data): - self.is_draft = False + self._is_draft = False self.form_data = data return self def from_draft(self): - self.is_draft = True + self._is_draft = True self.form_data = self.deserialised_data(self, self.draft_revision.form_data, self.form_fields) return self @@ -665,7 +669,7 @@ class ApplicationSubmission( elif skip_custom: return super().save(*args, **kwargs) - if self.is_draft: + if self._is_draft: raise ValueError('Cannot save with draft data') creating = not self.id diff --git a/hypha/apply/funds/models/utils.py b/hypha/apply/funds/models/utils.py index 85fa9a2c2eae79aa6694a239d7c9e8b3e9e04bb5..e01b098b9282bdff0440491157c336aca973e7e1 100644 --- a/hypha/apply/funds/models/utils.py +++ b/hypha/apply/funds/models/utils.py @@ -10,7 +10,8 @@ from wagtail.admin.panels import ( ) from wagtail.contrib.forms.models import AbstractEmailForm -from hypha.apply.activity.messaging import MESSAGES, messenger +from hypha.apply.activity.messaging import messenger +from hypha.apply.activity.options import MESSAGES from hypha.apply.stream_forms.models import AbstractStreamForm from hypha.apply.users.groups import ( COMMUNITY_REVIEWER_GROUP_NAME, @@ -104,13 +105,13 @@ class WorkflowStreamForm(WorkflowHelpers, AbstractStreamForm): # type: ignore def render_landing_page(self, request, form_submission=None, *args, **kwargs): # We only reach this page after creation of a new submission # Hook in to notify about new applications - if not form_submission.status == DRAFT_STATE: - messenger( - MESSAGES.NEW_SUBMISSION, - request=request, - user=form_submission.user, - source=form_submission, - ) + messenger( + MESSAGES.NEW_SUBMISSION, + request=request, + user=form_submission.user, + source=form_submission, + ) + return super().render_landing_page(request, form_submission, *args, **kwargs) content_panels = AbstractStreamForm.content_panels + [ diff --git a/hypha/apply/funds/notificaitons.py b/hypha/apply/funds/notificaitons.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/hypha/apply/funds/templates/funds/applicationsubmission_form.html b/hypha/apply/funds/templates/funds/applicationsubmission_form.html index 8520b225d9c2a2e2a4d861e873aac9898ee9c2d4..7f41d66c57c5b4523daeecd67c879d425415940b 100644 --- a/hypha/apply/funds/templates/funds/applicationsubmission_form.html +++ b/hypha/apply/funds/templates/funds/applicationsubmission_form.html @@ -44,7 +44,6 @@ {% endblock %} {% block extra_js %} - <script src="{% static 'js/apply/list-input-files.js' %}"></script> <script src="{% static 'js/apply/tinymce-word-count.js' %}"></script> <script src="{% static 'js/apply/multi-input-fields.js' %}"></script> <script src="{% static 'js/apply/submission-form-copy.js' %}"></script> diff --git a/hypha/apply/funds/tests/test_models.py b/hypha/apply/funds/tests/test_models.py index 65435aa448ed2d9eadc18164484313dd10e4a016..ed4662fe5c853cccac3acfa2785b156a269b6501 100644 --- a/hypha/apply/funds/tests/test_models.py +++ b/hypha/apply/funds/tests/test_models.py @@ -12,7 +12,7 @@ from django.urls import reverse from hypha.apply.funds.blocks import EmailBlock, FullNameBlock from hypha.apply.funds.models import ApplicationSubmission, Reminder -from hypha.apply.funds.workflow import Request +from hypha.apply.funds.workflow import DRAFT_STATE, Request from hypha.apply.review.options import MAYBE, NO from hypha.apply.review.tests.factories import ReviewFactory, ReviewOpinionFactory from hypha.apply.users.tests.factories import StaffFactory @@ -464,6 +464,10 @@ class TestApplicationSubmission(TestCase): self.assertEqual(submission.revisions.count(), 1) self.assertDictEqual(submission.live_revision.form_data, submission.form_data) + def test_is_draft_property(self): + submission = ApplicationSubmissionFactory(status=DRAFT_STATE) + self.assertTrue(submission.is_draft, True) + def test_can_get_draft_data(self): submission = ApplicationSubmissionFactory() title = 'My new title' @@ -474,7 +478,7 @@ class TestApplicationSubmission(TestCase): draft_submission = submission.from_draft() self.assertDictEqual(draft_submission.form_data, submission.form_data) self.assertEqual(draft_submission.title, title) - self.assertTrue(draft_submission.is_draft, True) + self.assertTrue(draft_submission._is_draft, True) with self.assertRaises(ValueError): draft_submission.save() diff --git a/hypha/apply/projects/templates/application_projects/invoice_form.html b/hypha/apply/projects/templates/application_projects/invoice_form.html index abab3377be16270f7731535426e359220ab9725e..d790ff7445339bdc8d683dfccf04e833ab11b698 100644 --- a/hypha/apply/projects/templates/application_projects/invoice_form.html +++ b/hypha/apply/projects/templates/application_projects/invoice_form.html @@ -30,7 +30,3 @@ </div> </div> {% endblock %} - -{% block extra_js %} -<script src="{% static 'js/apply/list-input-files.js' %}"></script> -{% endblock %} 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 9aff608a378ff7720330bf0204e53c52cbc98ddb..1fc5cb378269e2ba0571de0dee42d7b509e0df85 100644 --- a/hypha/apply/projects/templates/application_projects/project_approval_form.html +++ b/hypha/apply/projects/templates/application_projects/project_approval_form.html @@ -44,7 +44,6 @@ {% endblock %} {% block extra_js %} - <script src="{% static 'js/apply/list-input-files.js' %}"></script> <script src="{% static 'js/apply/tinymce-word-count.js' %}"></script> <script src="{% static 'js/apply/multi-input-fields.js' %}"></script> <script src="{% static 'js/apply/application-form-links-new-window.js' %}"></script> diff --git a/hypha/apply/projects/templates/application_projects/project_detail.html b/hypha/apply/projects/templates/application_projects/project_detail.html index cd389392d59631408cab39bdc2a694beea46ea49..beffef711d3e46655f0bbc4692d225aff0feaf66 100644 --- a/hypha/apply/projects/templates/application_projects/project_detail.html +++ b/hypha/apply/projects/templates/application_projects/project_detail.html @@ -243,6 +243,7 @@ {% block extra_js %} <script src="{% static 'js/apply/tabs.js' %}"></script> + <script src="{% static 'js/apply/edit-comment.js' %}"></script> <script src="{% static 'js/apply/toggle-payment-block.js' %}"></script> <script src="{% static 'js/apply/past-reports-pagination.js' %}"></script> <script src="{% static 'js/apply/report-calculator.js' %}"></script> diff --git a/hypha/apply/projects/templates/application_projects/report_form.html b/hypha/apply/projects/templates/application_projects/report_form.html index f43bac4b2a4d9b680005ea2f27208f02ec661df8..b6a3cbc54d132bfa59fe1ca0e651a2c5114cf0d8 100644 --- a/hypha/apply/projects/templates/application_projects/report_form.html +++ b/hypha/apply/projects/templates/application_projects/report_form.html @@ -73,6 +73,5 @@ {% block extra_js %} <script src="{% static 'js/apply/jquery.fancybox.min.js' %}"></script> -<script src="{% static 'js/apply/list-input-files.js' %}"></script> <script src="{% static 'js/apply/fancybox-global.js' %}"></script> {% endblock %} diff --git a/hypha/apply/projects/templates/application_projects/vendor_form.html b/hypha/apply/projects/templates/application_projects/vendor_form.html index 6fcdd52daf36828dc1dcb0ebcede75214784725e..e6079e0c85850cec480c84985c7d8fe2545ee9a8 100644 --- a/hypha/apply/projects/templates/application_projects/vendor_form.html +++ b/hypha/apply/projects/templates/application_projects/vendor_form.html @@ -36,5 +36,4 @@ {% block extra_js %} {{ form.media.js }} - <script src="{% static 'js/apply/list-input-files.js' %}"></script> {% endblock %} diff --git a/hypha/apply/projects/templates/application_projects/vendor_success.html b/hypha/apply/projects/templates/application_projects/vendor_success.html index c74ffd41bce33e6a75bfaba296cbfece1a51803e..297b4a6f0d560f139427971846e5d57de1495ca2 100644 --- a/hypha/apply/projects/templates/application_projects/vendor_success.html +++ b/hypha/apply/projects/templates/application_projects/vendor_success.html @@ -18,7 +18,3 @@ <a href="{% url 'apply:projects:detail' pk=project.pk %}">{% trans "Visit Project Detail Page" %}</a> </div> {% endblock %} - -{% block extra_js %} -<script src="{% static 'js/apply/list-input-files.js' %}"></script> -{% endblock %} diff --git a/hypha/apply/stream_forms/testing/factories.py b/hypha/apply/stream_forms/testing/factories.py index 4fc5c050a2b5ad72134352ef82a1c435f92da779..2a9c5dba21f840a652ff2cef838ab0385219f1c7 100644 --- a/hypha/apply/stream_forms/testing/factories.py +++ b/hypha/apply/stream_forms/testing/factories.py @@ -94,7 +94,9 @@ class ParagraphBlockFactory(wagtail_factories.blocks.BlockFactory): class FormFieldBlockFactory(wagtail_factories.StructBlockFactory): default_value = factory.Faker('sentence') field_label = factory.Faker('sentence') - help_text = factory.LazyAttribute(lambda o: str(o._Resolver__step.builder.factory_meta.model)) + help_text = factory.LazyAttribute( + lambda o: f"Help text for {o._Resolver__step.builder.factory_meta.model.__name__}" + ) class Meta: model = stream_blocks.FormFieldBlock diff --git a/hypha/static_src/src/javascript/apply/list-input-files.js b/hypha/static_src/src/javascript/apply/list-input-files.js deleted file mode 100644 index 4ac805e779cd581d1d8cb1d4bcb8552dcebbde75..0000000000000000000000000000000000000000 --- a/hypha/static_src/src/javascript/apply/list-input-files.js +++ /dev/null @@ -1,20 +0,0 @@ -(function ($) { - - 'use strict'; - - function listInputFiles() { - $('input[type=file]').change(function () { - // remove any existing files first - $(this).siblings('.form__file').remove(); - for (let i = 0; i < $(this)[0].files.length; ++i) { - $(this).parents('.form__item').prepend(` - <p class="form__file">${$(this)[0].files[i].name}</p> - `); - } - }); - } - - // Show list of selected files for upload on input[type=file] - listInputFiles(); - -})(jQuery); diff --git a/requirements.txt b/requirements.txt index a51a87d53db5a43f96066e60018e143200adf740..6f4c49bb3e8bba3bf233f25584cffc373bd37ce5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,8 @@ django-basic-auth-ip-whitelist==0.3.4 django-bleach==3.0.0 django-countries==7.2.1 django-extensions==3.1.5 -django-file-form==3.3.0 +# django-file-form==3.3.0 +git+https://github.com/theskumar/django-file-form.git@feature/error-message-invalid-files django-filter==2.4.0 django-fsm==2.8.0 django-heroku==0.3.1