editor: restoring editing functionality (for sections for now)
This commit is contained in:
parent
cb761d08f3
commit
a16696a941
13 changed files with 84 additions and 207 deletions
|
@ -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():
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
{% load static %}
|
||||
<span data-redirect="{% url 'editor.mapitems.level' mapitem_type=mapitem_type level='LEVEL' %}"></span>
|
|
@ -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>« 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>« 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 %}
|
|
@ -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>
|
|
@ -1 +1 @@
|
|||
<span data-redirect="{{ target }}"></span>
|
||||
<span data-redirect="{% if target %}{{ target }}{% elif back_url %}{{ back_url }}{% endif %}"></span>
|
||||
|
|
|
@ -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' %}">« {% trans 'Back to overview' %}</a>
|
||||
|
|
|
@ -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'}),
|
||||
]
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue