diff --git a/rdmo/core/settings.py b/rdmo/core/settings.py index 53293abf6..bd74dd25a 100644 --- a/rdmo/core/settings.py +++ b/rdmo/core/settings.py @@ -209,7 +209,9 @@ 'PROJECT_IMPORTS_LIST', 'PROJECT_SEND_ISSUE', 'PROJECT_QUESTIONS_AUTOSAVE', - 'NESTED_PROJECTS' + 'NESTED_PROJECTS', + 'PROJECT_VIEWS_SYNC', + 'PROJECT_TASKS_SYNC' ] SETTINGS_API = [ diff --git a/rdmo/projects/serializers/v1/__init__.py b/rdmo/projects/serializers/v1/__init__.py index 8e6174819..3a441b089 100644 --- a/rdmo/projects/serializers/v1/__init__.py +++ b/rdmo/projects/serializers/v1/__init__.py @@ -4,6 +4,7 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import serializers +from rest_framework.exceptions import ValidationError from rdmo.questions.models import Catalog from rdmo.services.validators import ProviderValidator @@ -93,6 +94,12 @@ class Meta: ProjectParentValidator() ] + def validate_views(self, value): + """Block updates to views if syncing is enabled.""" + if settings.PROJECT_VIEWS_SYNC and value: + raise ValidationError(_('Updating views is not allowed.')) + return value + class ProjectCopySerializer(ProjectSerializer): diff --git a/rdmo/projects/templates/projects/project_detail_issues.html b/rdmo/projects/templates/projects/project_detail_issues.html index 0e51a4257..9bf77532e 100644 --- a/rdmo/projects/templates/projects/project_detail_issues.html +++ b/rdmo/projects/templates/projects/project_detail_issues.html @@ -21,7 +21,7 @@

{% trans 'Tasks' %}

{% trans 'Time frame' %} {% trans 'Status' %} - {% if can_change_project %} + {% if can_change_project and not settings.PROJECT_TASKS_SYNC %} @@ -67,7 +67,7 @@

{% trans 'Tasks' %}

{% else %} - {% if can_change_project %} + {% if can_change_project and not settings.PROJECT_TASKS_SYNC %}

diff --git a/rdmo/projects/templates/projects/project_detail_views.html b/rdmo/projects/templates/projects/project_detail_views.html index ae3ce20fa..09f9915cf 100644 --- a/rdmo/projects/templates/projects/project_detail_views.html +++ b/rdmo/projects/templates/projects/project_detail_views.html @@ -19,7 +19,7 @@

{% trans 'Views' %}

{% trans 'View' %} {% trans 'Description' %} - {% if can_change_project %} + {% if can_change_project and not settings.PROJECT_VIEWS_SYNC %} @@ -45,7 +45,7 @@

{% trans 'Views' %}

{% else %} - {% if can_change_project %} + {% if can_change_project and not settings.PROJECT_VIEWS_SYNC %}

diff --git a/rdmo/projects/tests/test_viewset_project.py b/rdmo/projects/tests/test_viewset_project.py index f45351743..0b51f5972 100644 --- a/rdmo/projects/tests/test_viewset_project.py +++ b/rdmo/projects/tests/test_viewset_project.py @@ -429,6 +429,20 @@ def test_update_parent(db, client, username, password, project_id): assert Project.objects.get(pk=project_id).parent == project.parent +def test_update_project_views_not_allowed(db, client, settings): + assert settings.PROJECT_VIEWS_SYNC + client.login(username='owner', password='owner') + + url = reverse(urlnames['detail'], args=[project_id]) + data = { + 'views': [1] + } + response = client.put(url, data, content_type='application/json') + + assert response.status_code == 400 + assert 'Updating views is not allowed' in ' '.join(response.json()['views']) + + @pytest.mark.parametrize('username,password', users) @pytest.mark.parametrize('project_id', projects) def test_delete(db, client, username, password, project_id): diff --git a/rdmo/projects/views/project.py b/rdmo/projects/views/project.py index 9760fbd3b..6eade947a 100644 --- a/rdmo/projects/views/project.py +++ b/rdmo/projects/views/project.py @@ -64,11 +64,20 @@ def get_context_data(self, **kwargs): context['catalogs'] = Catalog.objects.filter_current_site() \ .filter_group(self.request.user) \ .filter_availability(self.request.user) - context['tasks_available'] = Task.objects.filter_current_site() \ + + if settings.PROJECT_TASKS_SYNC: + # tasks should be synced, the user can not change them + context['tasks_available'] = project.tasks.exists() + else: + context['tasks_available'] = Task.objects.filter_current_site() \ .filter_catalog(self.object.catalog) \ .filter_group(self.request.user) \ .filter_availability(self.request.user).exists() - context['views_available'] = View.objects.filter_current_site() \ + if settings.PROJECT_VIEWS_SYNC: + # views should be synced, the user can not change them + context['views_available'] = project.views.exists() + else: + context['views_available'] = View.objects.filter_current_site() \ .filter_catalog(self.object.catalog) \ .filter_group(self.request.user) \ .filter_availability(self.request.user).exists()