Skip to content

Commit c327944

Browse files
mattiagiupponiMalteIwanicki
authored andcommitted
[Fixes GeoNode#10251] improve feedback to the user and UI experience of batch permisisons assignment (GeoNode#10281)
* [Fixes GeoNode#10251] improve feedback to the user and UI experience * [Fixes GeoNode#10251] improve feedback to the user and UI experience * [Fixes GeoNode#10251] improve feedback to the user and UI experience
1 parent 7bbfec1 commit c327944

File tree

6 files changed

+89
-11
lines changed

6 files changed

+89
-11
lines changed

geonode/base/admin.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def set_user_and_group_dataset_permission(modeladmin, request, queryset):
9999
}
100100

101101
form = UserAndGroupPermissionsForm({
102-
'permission_type': 'read',
102+
'permission_type': 'view',
103103
'mode': 'set',
104104
'ids': ids,
105105
})

geonode/base/forms.py

+18-5
Original file line numberDiff line numberDiff line change
@@ -630,21 +630,34 @@ class BatchEditForm(forms.Form):
630630
ids = forms.CharField(required=False, widget=forms.HiddenInput())
631631

632632

633+
def get_user_choices():
634+
try:
635+
return [(x.pk, x.title) for x in Dataset.objects.all().order_by('id')]
636+
except Exception:
637+
return []
638+
639+
633640
class UserAndGroupPermissionsForm(forms.Form):
634641
def __init__(self, *args, **kwargs):
635642
super().__init__(*args, **kwargs)
636643
self.fields['layers'].label_from_instance = self.label_from_instance
637644

638-
layers = forms.ModelMultipleChoiceField(
639-
queryset=Dataset.objects.all(),
640-
required=False)
645+
layers = MultipleChoiceField(
646+
choices=get_user_choices(),
647+
widget=autocomplete.Select2Multiple(
648+
url='datasets_autocomplete'
649+
),
650+
label="Datasets",
651+
required=False,
652+
)
653+
641654
permission_type = forms.ChoiceField(
642655
required=True,
643656
widget=forms.RadioSelect,
644657
choices=(
645-
('read', 'Read'),
658+
('view', 'View'),
659+
('download', 'Download'),
646660
('edit', 'Edit'),
647-
('download', 'Download')
648661
),
649662
)
650663
mode = forms.ChoiceField(

geonode/base/templates/base/user_and_group_permissions.html

+31-1
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,42 @@
88
{% block body_class %}batch edit{% endblock %}
99

1010
{% block body %}
11+
<!-- Required to make select2 fields work for autocomplete -->
12+
<link href="{% static "vendor/select2/dist/css/select2.css" %}" type="text/css" media="screen" rel="stylesheet" />
13+
<link href="{% static "autocomplete_light/select2.css" %}" type="text/css" media="screen" rel="stylesheet" />
14+
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
15+
<script type="text/javascript" src="{% static "autocomplete_light/jquery.init.js" %}"></script>
16+
<script type="text/javascript" src="{% static "vendor/select2/dist/js/select2.full.js" %}"></script>
17+
<script type="text/javascript" src="{% static "vendor/select2/dist/js/i18n/en.js" %}"></script>
18+
<script type="text/javascript" src="{% static "autocomplete_light/autocomplete.init.js" %}"></script>
19+
<script type="text/javascript" src="{% static "autocomplete_light/forward.js" %}"></script>
20+
<script type="text/javascript" src="{% static "autocomplete_light/select2.js" %}"></script>
21+
<script type="text/javascript" src="{% static "autocomplete_light/jquery.post-setup.js" %}"></script>
22+
23+
<script src="{% static "geonode/js/crop_widget/crop_widget_es5.js" %}"></script>
24+
<link rel="stylesheet" href="{% static "geonode/css/crop_widget.css" %}">
25+
1126
<div class="page-header">
1227
<h2 class="page-title">{% trans "Batch Edit" %}</h2>
1328
</div>
1429
<form action="/{{ model|lower }}/dataset/permission/" method="post">
1530
{% csrf_token %}
16-
{{ form|as_bootstrap }}
31+
<div id="layers_multi_select">
32+
<span><label for="{{ form.layers.label }}">{{ form.layers.label }}</label></span>
33+
{{ form.layers }}
34+
</div>
35+
<br>
36+
<div id="perms_multi_select">
37+
<span><label for="{{ form.permission_type.label }}">{{ form.permission_type.label }}</label></span>
38+
{{ form.permission_type }}
39+
</div>
40+
<div id="set_multi_select">
41+
<span><label for="{{ form.mode.label }}">{{ form.mode.label }}</label></span>
42+
{{ form.mode }}
43+
</div>
44+
<div id="id_multi_select">
45+
{{ form.ids }}
46+
</div>
1747
<div>
1848
<input class="btn" type="submit" name="cancel" value="{% trans "Cancel" %}" />
1949
<input class="btn btn-primary" type="submit" value="{% trans "Submit" %}" />

geonode/base/urls.py

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from django.conf.urls import url, include
2020

2121
from .views import (
22+
DatasetsAutocomplete,
2223
resource_clone,
2324
RegionAutocomplete,
2425
ThesaurusAvailable,
@@ -57,6 +58,11 @@
5758
ThesaurusKeywordLabelAutocomplete.as_view(),
5859
name='thesaurus_autocomplete',
5960
),
61+
url(
62+
r'^datasets_autocomplete/$',
63+
DatasetsAutocomplete.as_view(),
64+
name='datasets_autocomplete',
65+
),
6066
url(
6167
r'^resource_rights/(?P<pk>\d+)$',
6268
OwnerRightsRequestView.as_view(),

geonode/base/views.py

+32-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from django.views.generic import FormView
3131
from django.http import HttpResponseRedirect
3232
from django.contrib.auth import get_user_model
33+
from django.contrib import messages
3334
from django.utils.translation import ugettext as _
3435
from django.core.exceptions import PermissionDenied
3536
from django.contrib.auth.decorators import login_required
@@ -95,11 +96,14 @@ def user_and_group_permission(request, model):
9596
return HttpResponseRedirect(
9697
get_url_for_app_model(model, model_class))
9798

99+
users_usernames = None
100+
groups_names = None
101+
98102
if request.method == 'POST':
99103
form = UserAndGroupPermissionsForm(request.POST)
100104
ids = ids.split(",")
101105
if form.is_valid():
102-
resources_names = [layer.title for layer in form.cleaned_data.get('layers')]
106+
resources_names = form.cleaned_data.get('layers')
103107
users_usernames = [user.username for user in model_class.objects.filter(
104108
id__in=ids)] if model == 'profile' else None
105109
groups_names = [group_profile.group.name for group_profile in model_class.objects.filter(
@@ -123,11 +127,22 @@ def user_and_group_permission(request, model):
123127
set_permissions.apply_async(
124128
([permissions_names], resources_names, users_usernames, groups_names, delete_flag))
125129

130+
messages.add_message(
131+
request,
132+
messages.INFO,
133+
f'The asyncronous permissions {form.cleaned_data.get("mode")} request for {", ".join(users_usernames or groups_names)} has been sent'
134+
)
135+
else:
136+
messages.add_message(
137+
request,
138+
messages.ERROR,
139+
f'Some error has occured {form.errors}'
140+
)
126141
return HttpResponseRedirect(
127142
get_url_for_app_model(model, model_class))
128143

129144
form = UserAndGroupPermissionsForm({
130-
'permission_type': 'read',
145+
'permission_type': 'view',
131146
'mode': 'set',
132147
})
133148
return render(
@@ -232,7 +247,7 @@ def __init__(self, *args, **kwargs):
232247
raise AttributeError("SimpleSelect2View missing required 'filter_arg' argument")
233248

234249
def get_queryset(self):
235-
qs = super(views.BaseQuerySetView, self).get_queryset()
250+
qs = super(views.BaseQuerySetView, self).get_queryset().order_by('pk')
236251

237252
if self.q:
238253
qs = qs.filter(**{self.filter_arg: self.q})
@@ -300,6 +315,20 @@ def get_results(self, context):
300315
]
301316

302317

318+
class DatasetsAutocomplete(SimpleSelect2View):
319+
model = Dataset
320+
filter_arg = 'title__icontains'
321+
322+
def get_results(self, context):
323+
return [
324+
{
325+
'id': self.get_result_value(result),
326+
'text': self.get_result_label(result.title),
327+
'selected_text': self.get_selected_result_label(result.title),
328+
} for result in context['object_list']
329+
]
330+
331+
303332
class ThesaurusAvailable(autocomplete.Select2QuerySetView):
304333
def get_queryset(self):
305334

geonode/people/tests.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def setUp(self):
5454
self.layers = Dataset.objects.all()[:3]
5555
self.dataset_ids = [layer.pk for layer in self.layers]
5656
self.user_ids = ",".join(str(element.pk) for element in get_user_model().objects.all()[:3])
57-
self.permission_type = ("read", "download", "edit")
57+
self.permission_type = ("view", "download", "edit")
5858
self.groups = Group.objects.all()[:3]
5959
self.group_ids = ",".join(str(element.pk) for element in self.groups)
6060

0 commit comments

Comments
 (0)