Add ability to add, edit and delete layer notes

This allows adding an important notice to a layer e.g. "this layer is
deprecated, please use layer xyz instead". Only one layer note can be
added through the interface although the data structures allow multiple,
so notes may be added programmatically without disturbing user-added
ones.

With this change we also add a get_absolute_url() function to the
LayerItem model and change the calls to reverse() for layers to use it.

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2013-02-27 19:11:58 +00:00
parent e6d7b215a6
commit 26ab9dbb28
8 changed files with 152 additions and 8 deletions

1
TODO
View File

@ -14,7 +14,6 @@ TODO:
* Captcha
Later:
* Allow adding/editing notes
* Usage links in list page?
* Avoid page content changing size depending on whether scrollbar is there or not?
* Style/extend about page?

View File

@ -0,0 +1,34 @@
{% extends "base.html" %}
{% load i18n %}
{% comment %}
layerindex-web - delete confirmation template
Copyright (C) 2013 Intel Corporation
Licensed under the MIT license, see COPYING.MIT for details
{% endcomment %}
<!--
{% autoescape on %}
{% block title %}OpenEmbedded metadata index - delete {{ object_type }}{% endblock %}
{% endautoescape %}
-->
{% block content %}
{% autoescape on %}
<h2>Delete {{ object_type }}</h2>
<p>Are you sure you want to delete &quot;{{ object }}&quot;?</p>
<form action="" method="post">
{% csrf_token %}
<input type="submit" value="Delete" class='btn btn-warning' />
<a href="{{ return_url }}" class='btn'>Cancel</a>
</form>
{% endautoescape %}
{% endblock %}

View File

@ -33,6 +33,9 @@
<span class="pull-right">
{% if perms.layeritem.publish_layer or useredit %}
<a href="{% url edit_layer layeritem.name %}" class="btn">Edit layer</a>
{% if layeritem.layernote_set.count = 0 %}
<a href="{% url add_layernote layeritem.name %}" class="btn">Add note</a>
{% endif %}
{% endif %}
{% if layeritem.status = "N" and perms.layeritem.publish_layer %}
<a href="{% url publish layeritem.name %}" class="btn btn-primary">Publish layer</a>
@ -48,7 +51,13 @@
<div class="row-fluid">
{% for note in layeritem.layernote_set.all %}
<div class="alert">
{{ note.text }}
<p>{{ note.text }}</p>
{% if perms.layeritem.publish_layer or useredit %}
<p>
<a href="{% url edit_layernote layeritem.name note.pk %}" class="btn">Edit note</a>
<a href="{% url delete_layernote layeritem.name note.pk %}" class='btn'>Delete note</a>
</p>
{% endif %}
</div>
{% endfor %}
</div>

View File

@ -0,0 +1,42 @@
{% extends "base.html" %}
{% load i18n %}
{% comment %}
layerindex-web - add/edit layer note form page template
Copyright (C) 2013 Intel Corporation
Licensed under the MIT license, see COPYING.MIT for details
{% endcomment %}
<!--
{% block title %}OpenEmbedded metadata index - {% if form.instance.pk %}add layer note{% else %}edit layer note{% endif %}{% endblock %}
-->
{% block content %}
{% autoescape on %}
<h2>Add layer note to {{ form.instance.layer.name }}</h2>
<p>This note will appear at the very top of the layer detail page. This would typically be used for important notices, e.g. &quot;This layer is obsolete, use layer xyz instead&quot;.</p>
<form id="edit_layernote_form" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" class='btn' />
<a href="{% url layer_item form.instance.layer.name %}" class='btn'>Cancel</a>
</form>
{% endautoescape %}
{% endblock %}
{% block scripts %}
<script>
$(document).ready(function() {
$("#edit_layernote_form input:text, #edit_layernote_form textarea").first().focus();
});
</script>
{% endblock %}

View File

@ -4,7 +4,7 @@
#
# Licensed under the MIT license, see COPYING.MIT for details
from layerindex.models import LayerItem, LayerMaintainer
from layerindex.models import LayerItem, LayerMaintainer, LayerNote
from django import forms
from django.core.validators import URLValidator, RegexValidator, email_re
from django.forms.models import inlineformset_factory
@ -110,3 +110,13 @@ class SubmitLayerForm(forms.ModelForm):
val = URLValidator(verify_exists=False)
val(url)
return url
class EditNoteForm(forms.ModelForm):
class Meta:
model = LayerNote
fields = ('text',)
def clean_text(self):
text = self.cleaned_data['text'].strip()
return text

View File

@ -7,6 +7,7 @@
from django.db import models
from datetime import datetime
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
import os.path
class LayerItem(models.Model):
@ -88,6 +89,9 @@ class LayerItem(models.Model):
return True
return False
def get_absolute_url(self):
return reverse('layer_item', args=(self.name,));
def __unicode__(self):
return self.name

View File

@ -7,7 +7,7 @@
from django.conf.urls.defaults import *
from django.views.generic import DetailView, ListView
from layerindex.models import LayerItem, Recipe
from layerindex.views import LayerListView, RecipeSearchView, MachineSearchView, PlainTextListView, LayerDetailView, edit_layer_view
from layerindex.views import LayerListView, RecipeSearchView, MachineSearchView, PlainTextListView, LayerDetailView, edit_layer_view, edit_layernote_view, delete_layernote_view
urlpatterns = patterns('',
url(r'^$',
@ -35,6 +35,12 @@ urlpatterns = patterns('',
LayerDetailView.as_view(
template_name='layerindex/detail.html'),
name='layer_item'),
url(r'^layer/(?P<slug>[-\w]+)/addnote/$',
edit_layernote_view, {'template_name': 'layerindex/editlayernote.html'}, name="add_layernote"),
url(r'^layer/(?P<slug>[-\w]+)/editnote/(?P<pk>[-\w]+)/$',
edit_layernote_view, {'template_name': 'layerindex/editlayernote.html'}, name="edit_layernote"),
url(r'^layer/(?P<slug>[-\w]+)/deletenote/(?P<pk>[-\w]+)/$',
delete_layernote_view, {'template_name': 'layerindex/deleteconfirm.html'}, name="delete_layernote"),
url(r'^recipe/(?P<pk>[-\w]+)/$',
DetailView.as_view(
model=Recipe,

View File

@ -9,10 +9,10 @@ from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidde
from django.core.urlresolvers import reverse
from django.core.exceptions import PermissionDenied
from django.template import RequestContext
from layerindex.models import LayerItem, LayerMaintainer, LayerDependency, Recipe, Machine
from layerindex.models import LayerItem, LayerMaintainer, LayerDependency, LayerNote, Recipe, Machine
from datetime import datetime
from django.views.generic import DetailView, ListView
from layerindex.forms import SubmitLayerForm, LayerMaintainerFormSet
from layerindex.forms import SubmitLayerForm, LayerMaintainerFormSet, EditNoteForm
from django.db import transaction
from django.contrib.auth.models import User, Permission
from django.db.models import Q
@ -23,6 +23,46 @@ import simplesearch
import settings
def edit_layernote_view(request, template_name, slug, pk=None):
layeritem = get_object_or_404(LayerItem, name=slug)
if not (request.user.is_authenticated() and (request.user.has_perm('layerindex.publish_layer') or layeritem.user_can_edit(request.user))):
raise PermissionDenied
if pk:
# Edit mode
layernote = get_object_or_404(LayerNote, pk=pk)
else:
# Add mode
layernote = LayerNote()
layernote.layer = layeritem
if request.method == 'POST':
form = EditNoteForm(request.POST, instance=layernote)
if form.is_valid():
form.save()
return HttpResponseRedirect(layeritem.get_absolute_url())
else:
form = EditNoteForm(instance=layernote)
return render(request, template_name, {
'form': form,
})
def delete_layernote_view(request, template_name, slug, pk):
layeritem = get_object_or_404(LayerItem, name=slug)
if not (request.user.is_authenticated() and (request.user.has_perm('layerindex.publish_layer') or layeritem.user_can_edit(request.user))):
raise PermissionDenied
layernote = get_object_or_404(LayerNote, pk=pk)
if request.method == 'POST':
layernote.delete()
return HttpResponseRedirect(layeritem.get_absolute_url())
else:
return render(request, template_name, {
'object': layernote,
'object_type': layernote._meta.verbose_name,
'return_url': layeritem.get_absolute_url()
})
def edit_layer_view(request, template_name, slug=None):
useredit = False
if slug:
@ -68,7 +108,7 @@ def edit_layer_view(request, template_name, slug=None):
d = Context({
'user_name': user.get_full_name(),
'layer_name': layeritem.name,
'layer_url': request.build_absolute_uri(reverse('layer_item', args=(layeritem.name,))),
'layer_url': request.build_absolute_uri(layeritem.get_absolute_url()),
})
subject = '%s - %s' % (settings.SUBMIT_EMAIL_SUBJECT, layeritem.name)
from_email = settings.SUBMIT_EMAIL_FROM
@ -105,7 +145,7 @@ def _statuschange(request, name, newstatus):
if w.status != newstatus:
w.change_status(newstatus, request.user.username)
w.save()
return HttpResponseRedirect(reverse('layer_item', args=(name,)))
return HttpResponseRedirect(w.get_absolute_url())
class LayerListView(ListView):
context_object_name = 'layer_list'