diff --git a/src/c3nav/editor/forms.py b/src/c3nav/editor/forms.py index 8f0e0fa1..83c5c9e1 100644 --- a/src/c3nav/editor/forms.py +++ b/src/c3nav/editor/forms.py @@ -3,7 +3,7 @@ import operator import os from functools import reduce from itertools import chain -from operator import attrgetter +from operator import attrgetter, itemgetter from django.conf import settings from django.core.cache import cache @@ -398,7 +398,7 @@ class EditorFormBase(I18nModelFormMixin, ModelForm): def create_editor_form(editor_model): possible_fields = [ - 'slug', 'name', 'title', 'title_plural', 'help_text', 'position_secret', 'icon', 'join_edges', + 'slug', 'name', 'title', 'title_plural', 'help_text', 'position_secret', 'icon', 'join_edges', 'todo', 'up_separate', 'bssid', 'main_point', 'external_url', 'external_url_label', 'hub_import_type', 'walk', 'ordering', 'category', 'width', 'groups', 'height', 'color', 'in_legend', 'priority', 'hierarchy', 'icon_name', 'base_altitude', 'intermediate', 'waytype', 'access_restriction', 'default_height', 'door_height', 'outside', @@ -493,3 +493,39 @@ class GraphEditorActionForm(Form): def clean_clicked_position(self): return GeometryField(geomtype='point').to_python(self.cleaned_data['clicked_position']) + + +class DoorGraphForm(Form): + def __init__(self, *args, request, spaces, nodes, edges, **kwargs): + self.request = request + self.edges = edges + self.restrictions = {a.pk: a for a in AccessRestriction.qs_for_request(request)} + super().__init__(*args, **kwargs) + + choices = ( + (-1, '--- no edge'), + (0, '--- edge without restriction'), + *((pk, restriction.title) for pk, restriction in self.restrictions.items()) + ) + + for (from_node, to_node), edge in sorted(edges.items(), key=itemgetter(0)): + self.fields[f'edge_{from_node}_{to_node}'] = ChoiceField( + choices=choices, + label=f'{spaces[nodes[from_node].space_id]} → {spaces[nodes[to_node].space_id]}', + initial=-1 if edge is None else (edge.access_restriction_id or 0), + ) + + def save(self): + for (from_node, to_node), edge in self.edges.items(): + cleaned_value = int(self.cleaned_data[f'edge_{from_node}_{to_node}']) + if edge is None: + if cleaned_value == -1: + continue + GraphEdge.objects.create(from_node_id=from_node, to_node_id=to_node, + access_restriction_id=(cleaned_value or None)) + else: + if cleaned_value == -1: + edge.delete() + elif edge.access_restriction_id != (cleaned_value or None): + edge.access_restriction_id = (cleaned_value or None) + edge.save() diff --git a/src/c3nav/editor/templates/editor/edit.html b/src/c3nav/editor/templates/editor/edit.html index 54bae714..ff9b8c7c 100644 --- a/src/c3nav/editor/templates/editor/edit.html +++ b/src/c3nav/editor/templates/editor/edit.html @@ -23,6 +23,24 @@