mirror of
git://git.yoctoproject.org/layerindex-web.git
synced 2025-07-19 12:49:01 +02:00
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:
parent
e6d7b215a6
commit
26ab9dbb28
1
TODO
1
TODO
|
@ -14,7 +14,6 @@ TODO:
|
||||||
* Captcha
|
* Captcha
|
||||||
|
|
||||||
Later:
|
Later:
|
||||||
* Allow adding/editing notes
|
|
||||||
* Usage links in list page?
|
* Usage links in list page?
|
||||||
* Avoid page content changing size depending on whether scrollbar is there or not?
|
* Avoid page content changing size depending on whether scrollbar is there or not?
|
||||||
* Style/extend about page?
|
* Style/extend about page?
|
||||||
|
|
34
layerindex/deleteconfirm.html
Normal file
34
layerindex/deleteconfirm.html
Normal 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 "{{ object }}"?</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 %}
|
|
@ -33,6 +33,9 @@
|
||||||
<span class="pull-right">
|
<span class="pull-right">
|
||||||
{% if perms.layeritem.publish_layer or useredit %}
|
{% if perms.layeritem.publish_layer or useredit %}
|
||||||
<a href="{% url edit_layer layeritem.name %}" class="btn">Edit layer</a>
|
<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 %}
|
{% endif %}
|
||||||
{% if layeritem.status = "N" and perms.layeritem.publish_layer %}
|
{% if layeritem.status = "N" and perms.layeritem.publish_layer %}
|
||||||
<a href="{% url publish layeritem.name %}" class="btn btn-primary">Publish layer</a>
|
<a href="{% url publish layeritem.name %}" class="btn btn-primary">Publish layer</a>
|
||||||
|
@ -48,7 +51,13 @@
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
{% for note in layeritem.layernote_set.all %}
|
{% for note in layeritem.layernote_set.all %}
|
||||||
<div class="alert">
|
<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>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
42
layerindex/editlayernote.html
Normal file
42
layerindex/editlayernote.html
Normal 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. "This layer is obsolete, use layer xyz instead".</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 %}
|
|
@ -4,7 +4,7 @@
|
||||||
#
|
#
|
||||||
# Licensed under the MIT license, see COPYING.MIT for details
|
# 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 import forms
|
||||||
from django.core.validators import URLValidator, RegexValidator, email_re
|
from django.core.validators import URLValidator, RegexValidator, email_re
|
||||||
from django.forms.models import inlineformset_factory
|
from django.forms.models import inlineformset_factory
|
||||||
|
@ -110,3 +110,13 @@ class SubmitLayerForm(forms.ModelForm):
|
||||||
val = URLValidator(verify_exists=False)
|
val = URLValidator(verify_exists=False)
|
||||||
val(url)
|
val(url)
|
||||||
return 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
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
class LayerItem(models.Model):
|
class LayerItem(models.Model):
|
||||||
|
@ -88,6 +89,9 @@ class LayerItem(models.Model):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('layer_item', args=(self.name,));
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
from django.conf.urls.defaults import *
|
from django.conf.urls.defaults import *
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import DetailView, ListView
|
||||||
from layerindex.models import LayerItem, Recipe
|
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('',
|
urlpatterns = patterns('',
|
||||||
url(r'^$',
|
url(r'^$',
|
||||||
|
@ -35,6 +35,12 @@ urlpatterns = patterns('',
|
||||||
LayerDetailView.as_view(
|
LayerDetailView.as_view(
|
||||||
template_name='layerindex/detail.html'),
|
template_name='layerindex/detail.html'),
|
||||||
name='layer_item'),
|
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]+)/$',
|
url(r'^recipe/(?P<pk>[-\w]+)/$',
|
||||||
DetailView.as_view(
|
DetailView.as_view(
|
||||||
model=Recipe,
|
model=Recipe,
|
||||||
|
|
|
@ -9,10 +9,10 @@ from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidde
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.template import RequestContext
|
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 datetime import datetime
|
||||||
from django.views.generic import DetailView, ListView
|
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.db import transaction
|
||||||
from django.contrib.auth.models import User, Permission
|
from django.contrib.auth.models import User, Permission
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
@ -23,6 +23,46 @@ import simplesearch
|
||||||
import settings
|
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):
|
def edit_layer_view(request, template_name, slug=None):
|
||||||
useredit = False
|
useredit = False
|
||||||
if slug:
|
if slug:
|
||||||
|
@ -68,7 +108,7 @@ def edit_layer_view(request, template_name, slug=None):
|
||||||
d = Context({
|
d = Context({
|
||||||
'user_name': user.get_full_name(),
|
'user_name': user.get_full_name(),
|
||||||
'layer_name': layeritem.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)
|
subject = '%s - %s' % (settings.SUBMIT_EMAIL_SUBJECT, layeritem.name)
|
||||||
from_email = settings.SUBMIT_EMAIL_FROM
|
from_email = settings.SUBMIT_EMAIL_FROM
|
||||||
|
@ -105,7 +145,7 @@ def _statuschange(request, name, newstatus):
|
||||||
if w.status != newstatus:
|
if w.status != newstatus:
|
||||||
w.change_status(newstatus, request.user.username)
|
w.change_status(newstatus, request.user.username)
|
||||||
w.save()
|
w.save()
|
||||||
return HttpResponseRedirect(reverse('layer_item', args=(name,)))
|
return HttpResponseRedirect(w.get_absolute_url())
|
||||||
|
|
||||||
class LayerListView(ListView):
|
class LayerListView(ListView):
|
||||||
context_object_name = 'layer_list'
|
context_object_name = 'layer_list'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user