diff --git a/arches/app/media/css/arches.css b/arches/app/media/css/arches.css index 911d481ab66..9e12e5cf162 100644 --- a/arches/app/media/css/arches.css +++ b/arches/app/media/css/arches.css @@ -9155,6 +9155,24 @@ a.clear-geojson-button:hover { top: 6px } +.msm-list-filter { + display: flex; + padding: 10px; +} + +.msm-list-filter-input { + padding-left: 15px; + width: 250px; + height: 35px; + position: relative; +} + +.msm-list-filter-input .clear-node-search { + top: 9px; + right: 10px; +} + + /* End Function Manager Page */ .category-header { @@ -10583,10 +10601,6 @@ a.search-facet-item.disabled { background: #fafafa; } -.mobile-project-manager-editor .clear-node-search { - top: 50px; -} - .mobile-project-manager-editor .card-nav-container { margin-bottom: 0; } diff --git a/arches/app/media/js/views/mobile-survey-manager.js b/arches/app/media/js/views/mobile-survey-manager.js index fb3d55e685c..c680aba3b4e 100644 --- a/arches/app/media/js/views/mobile-survey-manager.js +++ b/arches/app/media/js/views/mobile-survey-manager.js @@ -11,9 +11,8 @@ define([ ], function(_, ko, BaseManagerView, MobileSurveyManagerViewModel, AlertViewModel, MobileSurveyModel, data, arches) { var viewModel = new MobileSurveyManagerViewModel(data); - + viewModel.arches = arches; viewModel.saveMobileSurvey = function() { - var self = this; this.loading(true); var addMobileSurvey = !this.selectedMobileSurvey().get('id'); this.selectedMobileSurvey().save(function(data) { diff --git a/arches/app/templates/javascript.htm b/arches/app/templates/javascript.htm index fb72da96e06..0d96be79cad 100644 --- a/arches/app/templates/javascript.htm +++ b/arches/app/templates/javascript.htm @@ -218,7 +218,8 @@ export_mapping_file: function(graphid){return "{% url 'export_mapping_file' 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' %}".replace('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', graphid)}, add_resource: function(graphid){return "{% url 'add_resource' 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' %}".replace('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', graphid)}, function_manager: function(graphid){return "{% url 'function_manager' 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' %}".replace('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', graphid)}, - mobile_survey_resources: function(surveyid){return "{% url 'mobile_survey_resources' 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' %}".replace('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', surveyid)}, + mobile_survey_resources: function(surveyid){return "{% url 'mobile_survey_resources' 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' %}".replace('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', surveyid)}, + mobile_survey_editor: function(surveyid){return "{% url 'mobile_survey_editor' 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' %}".replace('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', surveyid)}, mobile_survey: "{% url 'mobile_survey_manager' %}", help_template: "{% url 'help_templates' %}" }, diff --git a/arches/app/templates/views/mobile-survey-editor.htm b/arches/app/templates/views/mobile-survey-editor.htm new file mode 100644 index 00000000000..b3c6cad002f --- /dev/null +++ b/arches/app/templates/views/mobile-survey-editor.htm @@ -0,0 +1,860 @@ + +{% extends "base-manager.htm" %} +{% load staticfiles %} +{% load i18n %} + + +{% block title %} +{{ block.super }} +{% trans "Mobile Survey Manager" %} +{% endblock title %} + + +{% block main_content %} +
+
+ +
+ + +
+
+ + +
+ + + +
+ + +
+
+ +
+
+
+{% endblock main_content %} + +{% block tabs %}{% endblock tabs %} + +{% block pre_require_js %} +{{block.super}} + +{% endblock pre_require_js %} diff --git a/arches/app/templates/views/mobile-survey-manager.htm b/arches/app/templates/views/mobile-survey-manager.htm index 8e7d08285f5..58539006ff3 100644 --- a/arches/app/templates/views/mobile-survey-manager.htm +++ b/arches/app/templates/views/mobile-survey-manager.htm @@ -30,26 +30,46 @@
- -
- -
-
- -
-
-

{% trans 'Surveys' %}

- -
- +
+ + +
{% trans "Mobile Data Collection" %}
+
{% trans "Arches allows you to define data collection surveys to collect data in the field" %}
+ + + + + +
{% trans "Arches allows you to create and edit data in the field using mobile devices such as" %}
+
{% trans "Android and iOS phones or tablets. Surveys are a way to define the time, location, content, and" %}
+
{% trans "participants of a field data collection effort" %}
+ + + + +
- - -
+ + +
+ +
+ + +
+
+
+ +
+
+ + +
-
+
+
@@ -65,9 +85,10 @@

{% trans 'Surveys' %}

-
+
-
+ +
@@ -75,818 +96,14 @@

{% trans 'Surveys' %}

{% trans 'delete' %}
+
- -
-
- - -
- - - -
- - -
-
+
{% endblock main_content %} diff --git a/arches/app/views/mobile_survey.py b/arches/app/views/mobile_survey.py index 0eca2c973a9..44ee1582c64 100644 --- a/arches/app/views/mobile_survey.py +++ b/arches/app/views/mobile_survey.py @@ -42,11 +42,35 @@ from arches.app.models.card import Card from arches.app.models.mobile_survey import MobileSurvey from arches.app.models.system_settings import settings +from arches.app.views.base import BaseManagerView from arches.app.views.base import MapBaseManagerView import arches.app.views.search as search + @method_decorator(group_required('Application Administrator'), name='dispatch') -class MobileSurveyManagerView(MapBaseManagerView): +class MobileSurveyListView(BaseManagerView): + + def get_survey_resources(self, mobile_survey_models): + graphs = models.GraphModel.objects.filter(isresource=True).exclude(graphid=settings.SYSTEM_SETTINGS_RESOURCE_MODEL_ID) + resources = [] + mobile_surveys = [] + all_ordered_card_ids = [] + + for mobile_survey in mobile_survey_models: + survey = MobileSurvey.objects.get(id=mobile_survey.id) + mobile_survey_dict = survey.serialize() + all_ordered_card_ids += mobile_survey_dict['cards'] + mobile_surveys.append(mobile_survey_dict) + + active_graphs = set([unicode(card.graph_id) for card in models.CardModel.objects.filter(cardid__in=all_ordered_card_ids)]) + + for i, graph in enumerate(graphs): + cards = [] + if i == 0 or unicode(graph.graphid) in active_graphs: + cards = [Card.objects.get(pk=card.cardid) for card in models.CardModel.objects.filter(graph=graph)] + resources.append({'name': graph.name, 'id': graph.graphid, 'subtitle': graph.subtitle, 'iconclass': graph.iconclass, 'cards': cards}) + + return mobile_surveys, resources def get(self, request): @@ -115,6 +139,105 @@ def get_last_login(date): return render(request, 'views/mobile-survey-manager.htm', context) + def delete(self, request): + mobile_survey_id = None + try: + mobile_survey_id = JSONDeserializer().deserialize(request.body)['id'] + except Exception as e: + print e + + try: + connection_error = False + with transaction.atomic(): + if mobile_survey_id is not None: + ret = MobileSurvey.objects.get(pk=mobile_survey_id) + ret.delete() + return JSONResponse({'success': True}) + except Exception as e: + if connection_error == False: + error_title = _('Unable to delete survey') + if e.strerror == 'Connection refused': + error_message = "Unable to connect to CouchDB" + else: + error_message = e.message + connection_error = JSONResponse({'success':False,'message': error_message,'title': error_title}, status=500) + return connection_error + + return HttpResponseNotFound() + + +@method_decorator(group_required('Application Administrator'), name='dispatch') +class MobileSurveyManagerView(MapBaseManagerView): + + def get(self, request, surveyid): + + print "Surveyid", surveyid + + def get_last_login(date): + result = _("Not yet logged in") + try: + if date is not None: + result = datetime.strftime(date, '%Y-%m-%d %H:%M') + except TypeError as e: + print e + return result + + identities = [] + for group in Group.objects.all(): + users = group.user_set.all() + if len(users) > 0: + groupUsers = [{'id': user.id, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email, 'last_login': get_last_login(user.last_login), 'username': user.username, 'groups': [g.id for g in user.groups.all()], 'group_names': ', '.join([g.name for g in user.groups.all()]) } for user in users] + identities.append({'name': group.name, 'type': 'group', 'id': group.pk, 'users': groupUsers, 'default_permissions': group.permissions.all()}) + for user in User.objects.filter(): + groups = [] + group_ids = [] + default_perms = [] + for group in user.groups.all(): + groups.append(group.name) + group_ids.append(group.id) + default_perms = default_perms + list(group.permissions.all()) + identities.append({'name': user.email or user.username, 'groups': ', '.join(groups), 'type': 'user', 'id': user.pk, 'default_permissions': set(default_perms), 'is_superuser':user.is_superuser, 'group_ids': group_ids, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email}) + + map_layers = models.MapLayer.objects.all() + map_markers = models.MapMarker.objects.all() + map_sources = models.MapSource.objects.all() + geocoding_providers = models.Geocoder.objects.all() + + mobile_survey_models = models.MobileSurveyModel.objects.order_by('name') + mobile_surveys, resources = self.get_survey_resources(mobile_survey_models) + + for mobile_survey in mobile_surveys: + try: + mobile_survey['datadownloadconfig'] = json.loads(mobile_survey['datadownloadconfig']) + mobile_survey['onlinebasemaps'] = json.loads(mobile_survey['onlinebasemaps']) + except TypeError: + pass + multipart = mobile_survey['bounds'] + singlepart = GeoUtils().convert_multipart_to_singlepart(multipart) + mobile_survey['bounds'] = singlepart + + serializer = JSONSerializer() + context = self.get_context_data( + map_layers=map_layers, + map_markers=map_markers, + map_sources=map_sources, + geocoding_providers=geocoding_providers, + mobile_surveys=serializer.serialize(mobile_surveys, sort_keys=False), + identities=serializer.serialize(identities, sort_keys=False), + resources=serializer.serialize(resources, sort_keys=False), + resource_download_limit=settings.MOBILE_DOWNLOAD_RESOURCE_LIMIT, + main_script='views/mobile-survey-manager', + ) + + context['nav']['title'] = _('Mobile Survey Manager') + context['nav']['icon'] = 'fa-server' + context['nav']['help'] = { + 'title': _('Mobile Survey Manager'), + 'template': 'mobile-survey-manager-help', + } + + return render(request, 'views/mobile-survey-editor.htm', context) + def delete(self, request): mobile_survey_id = None try: diff --git a/arches/urls.py b/arches/urls.py index 6277050dd95..c3d678def65 100644 --- a/arches/urls.py +++ b/arches/urls.py @@ -30,7 +30,7 @@ from arches.app.views.user import UserManagerView from arches.app.views.tile import TileData from arches.app.views.map import MapLayerManagerView -from arches.app.views.mobile_survey import MobileSurveyManagerView, MobileSurveyResources +from arches.app.views.mobile_survey import MobileSurveyManagerView, MobileSurveyResources, MobileSurveyListView from arches.app.views.auth import LoginView, SignupView, ConfirmSignupView, ChangePasswordView, GetTokenView, GetClientIdView from arches.app.models.system_settings import settings from arches.app.utils.forms import ArchesPasswordResetForm @@ -136,8 +136,9 @@ url(r'^feature_popup_content$', main.feature_popup_content, name="feature_popup_content"), url(r'^user$', UserManagerView.as_view(), name="user_profile_manager"), url(r'^user/get_user_names$', UserManagerView.as_view(action='get_user_names'), name="get_user_names"), + url(r'^mobile_survey_manager/*', MobileSurveyListView.as_view(), name="mobile_survey_manager"), + url(r'^mobile_survey_editor/(?P%s)$' % uuid_regex, MobileSurveyManagerView.as_view(), name='mobile_survey_editor'), url(r'^mobile_survey_resources/(?P%s)/resources$' % uuid_regex, MobileSurveyResources.as_view(), name='mobile_survey_resources'), - url(r'^mobile_survey_manager/*', MobileSurveyManagerView.as_view(), name="mobile_survey_manager"), url(r'^couchdb/(?P.*)$', api.CouchdbProxy.as_view()), url(r'^surveys$', api.Surveys.as_view(), name='surveys'), url(r'^sync/(?P%s|())$' % uuid_regex, api.Sync.as_view(), name='sync'),