editor: restoring editing functionality (for sections for now)

This commit is contained in:
Laura Klünder 2017-05-16 14:10:50 +02:00
parent cb761d08f3
commit a16696a941
13 changed files with 84 additions and 207 deletions

View file

@ -1,5 +1,4 @@
import json
import time
from collections import OrderedDict
from django.conf import settings
@ -15,21 +14,10 @@ class MapitemFormMixin(ModelForm):
super().__init__(*args, **kwargs)
creating = not self.instance.pk
# disable name on non-direct editing
if not creating and not settings.DIRECT_EDITING:
self.fields['name'].disabled = True
if creating:
self.fields['name'].initial = hex(int(time.time()*1000000))[2:]
if 'section' in self.fields:
# hide section widget
self.fields['section'].widget = HiddenInput()
if 'groups' in self.fields:
# set field_name
self.fields['groups'].to_field_name = 'name'
if 'geometry' in self.fields:
# hide geometry widget
self.fields['geometry'].widget = HiddenInput()
@ -65,18 +53,18 @@ class MapitemFormMixin(ModelForm):
super().clean()
def create_editor_form(mapitemtype):
def create_editor_form(editor_model):
possible_fields = ['section', 'space', 'name', 'public', 'altitude', 'geometry', 'width', 'groups', 'color',
'location_type', 'can_search', 'can_describe', 'routing_inclusion', 'compiled_room', 'bssids',
'category', 'level']
existing_fields = [field.name for field in mapitemtype._meta.get_fields() if field.name in possible_fields]
existing_fields = [field.name for field in editor_model._meta.get_fields() if field.name in possible_fields]
class EditorForm(MapitemFormMixin, ModelForm):
class Meta:
model = mapitemtype
model = editor_model
fields = existing_fields
mapitemtype.EditorForm = EditorForm
editor_model.EditorForm = EditorForm
def create_editor_forms():

View file

@ -1,11 +1,11 @@
{% load bootstrap3 %}
<h3>Delete {{ mapitem_type.title }}</h3>
<h3>Delete {{ model_title }}</h3>
<form action="{{ path }}" method="post">
{% csrf_token %}
<p>Please confirm deleting: {{ name }}</p>
<p>Please confirm deleting: {{ title }}</p>
<input type="hidden" name="delete" value="1">
<input type="hidden" name="name" value="{{ name }}">
<input type="hidden" name="pk" value="{{ pk }}">
{% buttons %}
<button class="invisiblesubmit" type="submit"></button>
<a class="btn btn-default" href="{% url 'editor.mapitems.level' mapitem_type=mapitem_type level='LEVEL' %}" data-insert-level>

View file

@ -1,21 +1,30 @@
{% load bootstrap3 %}
{% load i18n %}
<h3>{% if new %}New{% else %}Edit{% endif %} {{ title }}</h3>
<form action="{{ path }}" method="post" data-mapitem-type="{{ mapitem_type }}"{% if new %} data-new{% endif %}{% if not new %} data-name="{{ name }}"{% elif geomtype %} data-geomtype="{{ geomtype }}"{% endif %}>
{% include 'editor/fragment_sections.html' %}
<a class="btn btn-sm {% if new %}btn-danger{% else %}btn-default{% endif %} pull-right" href="{{ back_url }}">
Cancel
</a>
{% if new %}
<h3>{% blocktrans %}New {{ model_title }}{% endblocktrans %}</h3>
{% else %}
<h3>{% blocktrans %}Edit {{ model_title }}{% endblocktrans %}</h3>
{% endif %}
<form action="{{ path }}" method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button class="invisiblesubmit" type="submit"></button>
{% if not new %}
<button type="submit" name="delete" value="1" class="btn btn-danger">
Delete
{% trans 'Delete' %}
</button>
{% endif %}
<button type="submit" accesskey="m" class="btn btn-primary pull-right">
Save
{% trans 'Save' %}
</button>
<a class="btn {% if new %}btn-danger{% else %}btn-default pull-right{% endif %} cancel-btn"
href="{% url 'editor.mapitems.level' mapitem_type=mapitem_type level='LEVEL' %}" data-insert-level>
<a class="btn {% if new %}btn-danger{% else %}btn-default pull-right{% endif %} cancel-btn" href="{{ back_url }}">
Cancel
</a>
{% endbuttons %}

View file

@ -2,12 +2,12 @@
<ul data-sections>
{% for s in sections %}
<li>
<a href="{% url section_url section=s.id %}"{% if section == s %} class="current"{% endif %}>{{ s.title }}</a>
<a href="{% url section_url pk=s.id %}"{% if section == s %} class="current"{% endif %}>{{ s.title }}</a>
</li>
{% endfor %}
</ul>
{% elif section %}
<ul data-sections>
<li class="current"><a href="{% url section_url section=section.id %}">{{ section.title }}</a></li>
<li><a href="" class="current">{{ section.title }}</a></li>
</ul>
{% endif %}

View file

@ -4,7 +4,7 @@
<h3>{% trans 'Sections' %}</h3>
<div class="list-group">
{% for s in sections %}
<a href="{% url 'editor.section' section=s.id %}" class="list-group-item">
<a href="{% url 'editor.section' pk=s.pk %}" class="list-group-item">
{{ s.title }}
</a>
{% endfor %}

View file

@ -13,8 +13,6 @@
{% block content %}
<div id="map"></div>
<div id="sidebar" class="loading">
<div class="content">
<span data-level-switch="{% url 'editor.mapitemtypes' level='LEVEL' %}"></span>
</div>
<div class="content"></div>
</div>
{% endblock %}

View file

@ -1,2 +0,0 @@
{% load static %}
<span data-redirect="{% url 'editor.mapitems.level' mapitem_type=mapitem_type level='LEVEL' %}"></span>

View file

@ -1,45 +0,0 @@
{% load bootstrap3 %}
<a class="btn btn-default btn-sm pull-right" accesskey="n" href="{% url 'editor.mapitems.add' mapitem_type=mapitem_type %}">Add new</a>
<h3>{{ title }}{% if has_level %} <small>on level {{ level }}</small>{% endif %}</h3>
<table class="table table-condensed itemtable" data-mapitem-type="{{ mapitem_type }}">
<tbody>
{% for item in items %}
{% if forloop.counter0|divisibleby:10 %}
<tr>
<td><a href="{% url 'editor.mapitemtypes' level='LEVEL' %}" data-insert-level>&laquo; Back</a></td>
<td></td>
</tr>
{% endif %}
<tr data-name="{{ item.name }}">
<td>{% if item.title != item.name %}{{ item.title }} <small>{{ item.name }}</small>{% else %}{{ item.name }}{% endif %}</td>
{% if has_elevator %}
<td><a href="{% url 'editor.mapitems.edit' mapitem_type='elevator' name=item.elevator.name %}">{{ item.elevator }}</a></td>
<td>{{ item.button }}</td>
<td>{% if item.override_altitude %}{{ item.override_altitude }} m{% endif %}</td>
{% endif %}
{% if has_levels %}
<td>{% for level in item.levels.all %}{% if not forloop.first %}, {% endif %}<a href="" data-level-link="{{ level.name }}">{{ level.name }}</a>{% endfor %}</td>
{% endif %}
{% if has_altitude %}
<td>{{ item.altitude }} m</td>
{% endif %}
{% if has_intermediate %}
<td>{% if item.intermediate %}intermediate{% endif %}</td>
{% endif %}
<td><a href="{% url 'editor.mapitems.edit' mapitem_type=mapitem_type name=item.name %}">Edit</a></td>
</tr>
{% endfor %}
<tr>
<td><a href="{% url 'editor.mapitemtypes' level='LEVEL' %}" data-insert-level>&laquo; Back</a></td>
<td></td>
</tr>
</tbody>
</table>
{% if has_level %}
<span data-level-switch="{% url 'editor.mapitems.level' mapitem_type=mapitem_type level='LEVEL' %}"></span>
{% else %}
<span data-level-switch></span>
{% endif %}

View file

@ -1,19 +0,0 @@
{% load bootstrap3 %}
<h3>Mapitem types</h3>
<div class="list-group">
{% for mapitemtype in mapitemtypes %}
{% if mapitemtype.has_level %}
{% url 'editor.mapitems.level' mapitem_type=mapitemtype.name level=level as list_url %}
{% else %}
{% url 'editor.mapitems' mapitem_type=mapitemtype.name as list_url %}
{% endif %}
<a href="{{ list_url }}" class="list-group-item">
{% if mapitemtype.has_level %}<span class="badge">{{ mapitemtype.count }}</span>{% endif %}
{{ mapitemtype.title }}
</a>
{% endfor %}
</div>
<span data-level-switch="{% url 'editor.mapitemtypes' level='LEVEL' %}"></span>

View file

@ -1 +1 @@
<span data-redirect="{{ target }}"></span>
<span data-redirect="{% if target %}{{ target }}{% elif back_url %}{{ back_url }}{% endif %}"></span>

View file

@ -2,7 +2,7 @@
{% load i18n %}
{% include 'editor/fragment_sections.html' %}
<a class="btn btn-default btn-sm pull-right" accesskey="n" href="{% url 'editor.section.edit' section=section.id %}">{% trans 'Edit Section' %}</a>
<a class="btn btn-default btn-sm pull-right" accesskey="n" href="{% url 'editor.section.edit' pk=section.id %}">{% trans 'Edit Section' %}</a>
<h3>{{ section.title }}</h3>
<p>
<a href="{% url 'editor.index' %}">&laquo; {% trans 'Back to overview' %}</a>

View file

@ -1,14 +1,9 @@
from django.conf.urls import url
from c3nav.editor.views import edit_mapitem, list_mapitems, list_mapitemtypes, main_index, section_detail
from c3nav.editor.views import edit, main_index, section_detail
urlpatterns = [
url(r'^$', main_index, name='editor.index'),
url(r'^sections/(?P<section>[0-9]+)/$', section_detail, name='editor.section'),
url(r'^sections/(?P<section>[0-9]+)/edit$', section_detail, name='editor.section.edit'),
url(r'^mapitemtypes/(?P<level>[^/]+)/$', list_mapitemtypes, name='editor.mapitemtypes'),
url(r'^mapitems/(?P<mapitem_type>[^/]+)/list/$', list_mapitems, name='editor.mapitems'),
url(r'^mapitems/(?P<mapitem_type>[^/]+)/list/(?P<sectionl>[0-9]+)/$', list_mapitems, name='editor.mapitems.level'),
url(r'^mapitems/(?P<mapitem_type>[^/]+)/add/$', edit_mapitem, name='editor.mapitems.add'),
url(r'^mapitems/(?P<mapitem_type>[^/]+)/edit/(?P<id>[^/]+)/$', edit_mapitem, name='editor.mapitems.edit'),
url(r'^sections/(?P<pk>[0-9]+)/$', section_detail, name='editor.section'),
url(r'^sections/(?P<pk>[0-9]+)/edit$', edit, name='editor.section.edit', kwargs={'model': 'Section'}),
]

View file

@ -2,8 +2,7 @@ from functools import wraps
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.http.response import Http404
from django.shortcuts import get_object_or_404, redirect, render
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views.decorators.cache import never_cache
@ -21,142 +20,96 @@ def sidebar_view(func):
@sidebar_view
def main_index(request, section=None):
def main_index(request):
return render(request, 'editor/index.html', {
'sections': Section.objects.all(),
})
@sidebar_view
def section_detail(request, section):
section = get_object_or_404(Section, pk=section)
def section_detail(request, pk):
pk = get_object_or_404(Section, pk=pk)
return render(request, 'editor/section.html', {
'sections': Section.objects.all(),
'section': section,
'section': pk,
'section_url': 'editor.section',
})
def list_mapitemtypes(request, section):
section = get_object_or_404(Section, pk=section)
@sidebar_view
def edit(request, pk=None, model=None):
model = EDITOR_FORM_MODELS[model]
def get_item_count(mapitemtype):
if hasattr(mapitemtype, 'section'):
return filter_queryset_by_access(request, mapitemtype.objects.filter(section=section)).count()
return 0
return render(request, 'editor/mapitemtypes.html', {
'section': section,
'mapitemtypes': [
{
'name': name,
'title': mapitemtype._meta.verbose_name_plural,
'has_section': hasattr(mapitemtype, 'section'),
'count': get_item_count(mapitemtype),
} for name, mapitemtype in EDITOR_FORM_MODELS.items()
],
})
def list_mapitems(request, mapitem_type, section=None):
mapitemtype = EDITOR_FORM_MODELS.get(mapitem_type)
if mapitemtype is None:
raise Http404('Unknown mapitemtype.')
has_section = hasattr(mapitemtype, 'section')
if has_section and section is None:
raise Http404('Missing section.')
elif not has_section and section is not None:
return redirect('editor.mapitems', mapitem_type=mapitem_type)
queryset = mapitemtype.objects.all().order_by('name')
if section is not None:
section = get_object_or_404(Section, section)
if hasattr(mapitemtype, 'section'):
queryset = queryset.filter(section=section)
queryset = filter_queryset_by_access(request, queryset)
if issubclass(mapitemtype, AreaLocation):
queryset = sorted(queryset, key=AreaLocation.get_sort_key)
return render(request, 'editor/mapitems.html', {
'mapitem_type': mapitem_type,
'title': mapitemtype._meta.verbose_name_plural,
'has_section': section is not None,
'has_altitude': hasattr(mapitemtype, 'altitude'),
'section': section.id,
'items': queryset,
})
def edit_mapitem(request, mapitem_type, name=None):
mapitemtype = EDITOR_FORM_MODELS.get(mapitem_type)
if mapitemtype is None:
raise Http404()
mapitem = None
if name is not None:
obj = None
if pk is not None:
# Edit existing map item
mapitem = get_object_or_404(mapitemtype, name=name)
if not can_access(request, mapitem):
obj = get_object_or_404(model, pk=pk)
if False: # todo can access
raise PermissionDenied
new = mapitem is None
orig_name = mapitem.name if mapitem is not None else None
new = obj is None
# noinspection PyProtectedMember
ctx = {
'path': request.path,
'pk': pk,
'model_title': model._meta.verbose_name,
'model_name': model.__name__.lower(),
'new': new,
'title': obj.title if obj else None,
}
if isinstance(obj, Section):
ctx.update({
'section': obj,
'back_url': reverse('editor.index') if new else reverse('editor.section', kwargs={'pk': pk}),
})
elif hasattr(obj, 'section'):
ctx.update({
'section': obj.section,
'back_url': reverse('editor.space', kwargs={'pk': pk}),
})
elif hasattr(obj, 'space'):
ctx.update({
'section': obj.space.section,
'back_url': reverse('editor.space', kwargs={'pk': obj.space.pk}),
})
if request.method == 'POST':
if mapitem is not None and request.POST.get('delete') == '1':
if obj is not None and request.POST.get('delete') == '1':
# Delete this mapitem!
if request.POST.get('delete_confirm') == '1':
if not settings.DIRECT_EDITING:
# todo: suggest changes
raise NotImplementedError
# obj.delete()
return render(request, 'editor/redirect.html', ctx)
return render(request, 'editor/delete.html', ctx)
mapitem.delete()
return render(request, 'editor/mapitem_success.html', {
'mapitem_type': mapitem_type
})
return render(request, 'editor/mapitem_delete.html', {
'name': mapitem.name,
'mapitem_type': mapitem_type,
'path': request.path
})
form = mapitemtype.EditorForm(instance=mapitem, data=request.POST, request=request)
form = model.EditorForm(instance=obj, data=request.POST, request=request)
if form.is_valid():
# Update/create mapitem
mapitem = form.save(commit=False)
# Update/create objects
obj = form.save(commit=False)
if form.titles is not None:
mapitem.titles = {}
obj.titles = {}
for language, title in form.titles.items():
if title:
mapitem.titles[language] = title
obj.titles[language] = title
if not settings.DIRECT_EDITING:
# todo: suggest changes
raise NotImplementedError
mapitem.save()
obj.save()
form.save_m2m()
return render(request, 'editor/mapitem_success.html', {
'mapitem_type': mapitem_type
})
return render(request, 'editor/redirect.html', ctx)
else:
form = mapitemtype.EditorForm(instance=mapitem, request=request)
form = model.EditorForm(instance=obj, request=request)
return render(request, 'editor/mapitem.html', {
ctx.update({
'form': form,
'mapitem_type': mapitem_type,
'title': mapitemtype._meta.verbose_name,
'has_geometry': hasattr(mapitemtype, 'geometry'),
'name': orig_name,
'geomtype': getattr(mapitemtype, 'geomtype', None),
'path': request.path,
'new': new
})
return render(request, 'editor/edit.html', ctx)