aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluxagraf <sng@luxagraf.net>2018-12-06 06:57:52 -0600
committerluxagraf <sng@luxagraf.net>2018-12-06 06:57:52 -0600
commitd45fa99aa9d587b5674484f68955b43f39e8f6fd (patch)
tree29b2b5c14de7a26cc9cfe88ad6e89fec0fbe1cae
parent45245bc0a9b659ff547ec20eb70af3def4ee7c6f (diff)
redid tags to use through model, cleaned up note and notebook detail
views
-rw-r--r--README.md18
-rw-r--r--apps/notes/forms.py2
-rw-r--r--apps/notes/models.py29
-rw-r--r--apps/notes/serializers.py34
-rw-r--r--apps/notes/tests/test_models.py23
-rw-r--r--apps/notes/tests/test_views.py48
-rw-r--r--apps/notes/urls.py23
-rw-r--r--apps/notes/views.py40
-rw-r--r--design/templates/notes/notebook_create.html20
-rw-r--r--design/templates/notes/notebook_detail.html64
-rw-r--r--design/templates/notes/notes_create.html21
-rw-r--r--design/templates/notes/notes_detail.html76
-rw-r--r--design/templates/notes/notes_list.html19
13 files changed, 251 insertions, 166 deletions
diff --git a/README.md b/README.md
index c87cb3b..3602b22 100644
--- a/README.md
+++ b/README.md
@@ -41,3 +41,21 @@ Create, edit and view notes
## Art credits
<div>Icons made by <a href="https://www.freepik.com/" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
+
+## Features
+
+### Capture
+
+### Editing
+
+### Organizing
+
+### Surfacing
+
+### Outlining
+
+### Archiving
+
+### Versioning
+
+### Collaborating
diff --git a/apps/notes/forms.py b/apps/notes/forms.py
index c1df176..5ef9f84 100644
--- a/apps/notes/forms.py
+++ b/apps/notes/forms.py
@@ -20,7 +20,7 @@ class NoteForm(forms.ModelForm):
class NotebookForm(NoteForm):
class Meta:
model = Notebook
- fields = ['name']
+ fields = ['name', 'color_rgb']
labels = {
"name": _("Notebook Name"),
}
diff --git a/apps/notes/models.py b/apps/notes/models.py
index c0b23ce..95c1c96 100644
--- a/apps/notes/models.py
+++ b/apps/notes/models.py
@@ -12,18 +12,36 @@ from django.conf import settings
from utils.util import unique_slug_generator
+from django.utils.translation import ugettext_lazy as _
+
+from taggit.managers import TaggableManager
+from taggit.models import TagBase, GenericTaggedItemBase
+
+
+class LuxTag(TagBase):
+ color_rgb = models.CharField(max_length=20, null=True, blank=True)
+
+ class Meta:
+ verbose_name = _("Tag")
+ verbose_name_plural = _("Tags")
+
+
+class TaggedNotes(GenericTaggedItemBase):
+ tag = models.ForeignKey(LuxTag, related_name="%(app_label)s_%(class)s_items", on_delete=models.CASCADE)
+
class Notebook(models.Model):
+ """ Notebook model for Notes """
unique_id = models.UUIDField(default=uuid.uuid4, editable=False)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=250)
- url = models.CharField(max_length=250, null=True, blank=True)
+ color_rgb = models.CharField(max_length=20, null=True, blank=True)
slug = models.SlugField(blank=True)
date_created = models.DateTimeField(blank=True, auto_now_add=True, editable=False)
date_updated = models.DateTimeField(blank=True, auto_now=True, editable=False)
class Meta:
- unique_together = ("owner", "slug")
+ unique_together = ("owner", "name")
def __str__(self):
return self.name
@@ -35,7 +53,7 @@ class Notebook(models.Model):
@cached_property
def get_absolute_url(self):
- return reverse("notes:notebook-detail", kwargs={"user": self.owner.username, "slug": self.slug})
+ return reverse("notebooks:detail", kwargs={"slug": self.slug})
class Note(models.Model):
@@ -50,18 +68,19 @@ class Note(models.Model):
url = models.CharField(max_length=250, null=True, blank=True)
slug = models.SlugField(blank=True)
notebook = models.ForeignKey(Notebook, null=True, blank=True, on_delete=models.SET_NULL)
- tags = TaggableManager(blank=True, help_text='Tags')
+ tags = TaggableManager(through=TaggedNotes, blank=True, help_text='Tags')
is_public = models.BooleanField(default=False)
class Meta:
unique_together = ("owner", "slug")
+ ordering = ("-date_created", "-date_updated")
def __str__(self):
return self.title
@cached_property
def get_absolute_url(self):
- return reverse("notes:note-detail", kwargs={"user": self.owner.username, "slug": self.slug})
+ return reverse("notes:detail", kwargs={"slug": self.slug, 'pk': self.pk})
def save(self, **kwargs):
if not self.title:
diff --git a/apps/notes/serializers.py b/apps/notes/serializers.py
index daef52e..f811edd 100644
--- a/apps/notes/serializers.py
+++ b/apps/notes/serializers.py
@@ -1,11 +1,29 @@
from rest_framework import serializers
from taggit_serializer.serializers import TagListSerializerField, TaggitSerializer
-from .models import Note, Notebook
+from .models import Note, Notebook, LuxTag
+
+import six
+
+
+class NewTagListSerializerField(TagListSerializerField):
+ def to_internal_value(self, value):
+ if isinstance(value, six.string_types):
+ value = [v.strip() for v in value.split(',')]
+
+ if not isinstance(value, list):
+ self.fail('not_a_list', input_type=type(value).__name__)
+
+ for s in value:
+ if not isinstance(s, six.string_types):
+ self.fail('not_a_str')
+
+ self.child.run_validation(s)
+ return value
class NoteSerializer(TaggitSerializer, serializers.ModelSerializer):
- tags = TagListSerializerField()
+ tags = NewTagListSerializerField(required=False)
class Meta:
model = Note
@@ -14,7 +32,17 @@ class NoteSerializer(TaggitSerializer, serializers.ModelSerializer):
class NotebookSerializer(serializers.HyperlinkedModelSerializer):
json_absolute_url = serializers.URLField(source='get_absolute_url', read_only=True)
+ owner = serializers.HiddenField(
+ default=serializers.CurrentUserDefault()
+ )
class Meta:
model = Notebook
- fields = ('name', 'json_absolute_url')
+ fields = ('name', 'color_rgb', 'json_absolute_url', 'owner')
+
+
+class NoteTagSerializer(serializers.HyperlinkedModelSerializer):
+
+ class Meta:
+ model = LuxTag
+ fields = ('name', 'color_hex')
diff --git a/apps/notes/tests/test_models.py b/apps/notes/tests/test_models.py
index cf21aca..05f2618 100644
--- a/apps/notes/tests/test_models.py
+++ b/apps/notes/tests/test_models.py
@@ -1,16 +1,26 @@
from django.test import TestCase
+from django.urls import reverse
+from django.contrib import auth
from mixer.backend.django import mixer
-from notes.models import Note, Notebook
-from accounts.models import User
+from notes.models import Note, Notebook
+
+User = auth.get_user_model()
class NotebookModelTest(TestCase):
+ def setUp(self):
+ self.user = mixer.blend(User, username='tpynchon')
+ self.notebook = Notebook(owner=self.user, name="San Miguel Notes")
+ self.notebook.save()
def test_string_representation(self):
- user = mixer.blend(User, username='tpynchon')
- notebook = Notebook(owner=user, name="San Miguel Notes")
- self.assertEqual(str(notebook), "San Miguel Notes")
+ """Notebook title should be the name of the object"""
+ self.assertEqual(str(self.notebook), "San Miguel Notes")
+
+ def test_get_absolute_url(self):
+ """Absolute URL should return /nb/slug """
+ self.assertEqual(str(self.notebook.get_absolute_url), reverse("notebooks:detail", kwargs={'slug': self.notebook.slug}))
class NoteModelTest(TestCase):
@@ -41,4 +51,5 @@ class NoteModelTest(TestCase):
self.assertEqual(str(self.note_no_title), str(self.note_no_title.body_text)[:50])
def test_get_absolute_url(self):
- self.assertEqual(str(self.note.get_absolute_url), "/notes/%s/%s" % (self.note.owner.username, self.note.slug))
+ """Absolute URL should return /n/slug/pk """
+ self.assertEqual(str(self.note.get_absolute_url), "/n/%s/%s" % (self.note.slug, self.note.pk))
diff --git a/apps/notes/tests/test_views.py b/apps/notes/tests/test_views.py
index 4f9a4ce..be48226 100644
--- a/apps/notes/tests/test_views.py
+++ b/apps/notes/tests/test_views.py
@@ -1,6 +1,6 @@
import json
from django.test import Client
-from django.test import RequestFactory, TestCase
+from django.test import RequestFactory, TestCase, TransactionTestCase
from django.urls import reverse
from django.template.defaultfilters import slugify
@@ -14,6 +14,37 @@ from notes.models import Note
from notes.views import NoteListView, NoteViewSet
+class NoteCreateViewTests(TransactionTestCase):
+ """
+ Because I need pks to get URL of object I need
+ a clean database so I know the one and only object
+ has a pk of 1. There's probably a better way to do
+ this though.
+ Especially because this is a private API and subject
+ to change/deletion:
+ https://docs.djangoproject.com/en/2.1/topics/testing/advanced/#django.test.TransactionTestCase.reset_sequences
+ """
+ reset_sequences = True
+
+ def setUp(self):
+ self.client = Client()
+ self.user = User.objects.create(username='testuser', password='password')
+
+ def test_note_create_view(self):
+ data = {
+ 'pk': 2,
+ 'title': "test note post",
+ 'body_text': "the body of the note",
+ 'url': "https://luxagraf.net/",
+ 'tags': [],
+ }
+ self.client.force_login(self.user)
+ url = reverse("notes:create")
+ response = self.client.post(url, data)
+ self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, '/n/%s/%s' % (slugify(data['title']), Note.objects.count()))
+
+
class NotesViewsTest(TestCase):
def setUp(self):
# Every test needs access to the request factory.
@@ -35,25 +66,12 @@ class NotesViewsTest(TestCase):
self.note.save()
def test_list_view(self):
- request = self.factory.get('/notes/')
+ request = self.factory.get('/n/')
request.user = self.user
response = NoteListView.as_view()(request)
self.assertEqual(response.status_code, 200)
# bad_user
- def test_note_create_view(self):
- data = {
- 'title': "test note post",
- 'body_text': "the body of the note",
- 'url': "https://luxagraf.net/",
- 'tags': [],
- }
- self.client.force_login(self.user)
- url = reverse("notes:note-create")
- response = self.client.post(url, data)
- self.assertEqual(response.status_code, 302)
- self.assertRedirects(response, '/notes/%s/%s' % (self.user.username, slugify(data['title'])))
-
def test_api_list(self):
# Make an authenticated request to the view...
request = self.factory.get('/api/notes/')
diff --git a/apps/notes/urls.py b/apps/notes/urls.py
deleted file mode 100644
index a79c7cd..0000000
--- a/apps/notes/urls.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from django.urls import path
-
-from .views import (
- NoteDetailView,
- NoteCreateView,
- NoteListView,
- NoteListRedirectView,
- NotebookListView,
- NotebookDetailView,
- NoteTagView,
-)
-
-app_name = "notes"
-
-urlpatterns = [
- path(r'create/', NoteCreateView.as_view(), name='note-create',),
- path(r'<str:user>/tagged/<slug>', NoteTagView.as_view(), name='note-tag',),
- path(r'<str:user>/notebooks/<slug>', NotebookDetailView.as_view(), name='notebook-detail',),
- path(r'<str:user>/notebooks/', NotebookListView.as_view(), name='notebook-list',),
- path(r'<str:user>/<slug>', NoteDetailView.as_view(), name='note-detail',),
- path(r'<str:user>/', NoteListView.as_view(), name='note-list',),
- path(r'', NoteListRedirectView.as_view(), name='note-redirect',),
-]
diff --git a/apps/notes/views.py b/apps/notes/views.py
index d885ad9..5d55720 100644
--- a/apps/notes/views.py
+++ b/apps/notes/views.py
@@ -11,8 +11,8 @@ from rest_framework.response import Response
from rest_framework.decorators import list_route
from rest_framework import permissions
-from .serializers import NoteSerializer, NotebookSerializer
-from .models import Note, Notebook
+from .serializers import NoteSerializer, NotebookSerializer, NoteTagSerializer
+from .models import Note, Notebook, LuxTag
from .forms import NoteForm, NotebookForm
@@ -43,7 +43,7 @@ class NoteListView(LoggedInViewWithUser, ListView):
class NoteTagView(LoggedInViewWithUser, ListView):
model = Note
template_name = 'notes/notes_list.html'
-
+
def get_queryset(self):
'''
This can generate a crazy amount of joins if there's a lot of tags
@@ -69,12 +69,6 @@ class NoteTagView(LoggedInViewWithUser, ListView):
return context
-class NoteListRedirectView(RedirectView, LoggedInViewWithUser):
-
- def get_redirect_url(self, *args, **kwargs):
- return reverse_lazy("notes:note-list", kwargs={"user": self.request.user.username})
-
-
class NoteDetailView(UpdateView, LoggedInViewWithUser):
model = Note
form_class = NoteForm
@@ -101,7 +95,12 @@ class NoteCreateView(CreateView, LoggedInViewWithUser):
return super(NoteCreateView, self).form_valid(form)
def get_success_url(self):
- return reverse_lazy('notes:note-detail', kwargs={'user': self.request.user.username, 'slug': self.object.slug})
+ return reverse_lazy('notes:detail', kwargs={'slug': self.object.slug, 'pk': self.object.pk})
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related()
+ return context
class NotebookListView(CreateView, LoggedInViewWithUser):
@@ -124,11 +123,14 @@ class NotebookDetailView(DetailView, LoggedInViewWithUser):
model = Notebook
def get_object(self):
- return get_object_or_404(self.get_queryset().select_related(), owner=self.request.user, slug=self.kwargs["slug"])
+ notebook = get_object_or_404(self.get_queryset().select_related(), owner=self.request.user, slug=self.kwargs["slug"])
+ self.form = NotebookForm(instance=notebook)
+ return notebook
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related()
+ context['form'] = self.form
return context
@@ -153,7 +155,7 @@ class NoteViewSet(viewsets.ModelViewSet):
return Note.objects.filter(owner=self.request.user).order_by('-date_created')
def perform_create(self, serializer):
- serializer.save(owner=self.request.user)
+ serializer.save(owner=self.request.user, tags__owner=self.request.user)
def get_object(self):
obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])
@@ -178,3 +180,17 @@ class NotebookViewSet(viewsets.ModelViewSet):
def get_menu_data(self, serializer):
return Notebook.objects.filter(owner=self.request.user).order_by('-name')[:1]
+
+
+class TagViewSet(viewsets.ModelViewSet):
+ """
+ API endpoint that allows notes to be viewed or edited.
+ """
+ serializer_class = NoteTagSerializer
+ permission_classes = (permissions.IsAuthenticated,)
+
+ def get_queryset(self):
+ return LuxTag.objects.filter(owner=self.request.user)
+
+ def perform_create(self, serializer):
+ serializer.save(owner=self.request.user)
diff --git a/design/templates/notes/notebook_create.html b/design/templates/notes/notebook_create.html
index 8ffc94a..1386946 100644
--- a/design/templates/notes/notebook_create.html
+++ b/design/templates/notes/notebook_create.html
@@ -2,6 +2,7 @@
{% block extrastyles %}
<link rel="stylesheet" href="/media/quill.snow.css" />
+<script async src="/media/js/vanilla-picker.min.js"></script>
{% endblock %}
{% block content %}
<main>
@@ -10,34 +11,23 @@
{% csrf_token %}
{{ form.non_field_errors }}
{% for field in form %}
-<fieldset class="{% if field.errors %}error {%endif%}{% if field.name == 'body_qjson' or field.name == 'body_html' %}hide {%endif%}" id="fs-{{field.name}}" >
+<fieldset class="{% if field.errors %}error {%endif%}{% if field.name == 'color_hex' %}hide {%endif%}" id="fs-{{field.name}}" >
{{field.label_tag}}
{{field}}
{% if field.errors %}{{field.errors}}{% endif %}
</fieldset>
{% endfor %}
+<p id="color-picker"><a href="#">Pick color</a></p>
<p><input class="btn btn-inline" value="create" type="submit" /></p>
</form>
<ul>{% for object in notebook_list %}
<li>
- <a href="{% url 'notes:notebook-detail' user.username object.slug %}"><i class="icon-notebook"> </i>{{object.name}}</a>
+ <a href="{% url 'notebooks:detail' object.slug %}"><i class="icon-notebook"> </i>{{object.name}}</a>
</li>
{%endfor%}</ul>
</article>
<aside class="note-list-container">
- <div class="svg-wrapper"><svg class="svg-icon-arrow">
- <svg viewBox="0 0 16 13" id="shape-double-arrow" width="100%" height="100%"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square"><g id="Showing-post-info" transform="translate(-297.000000, -105.000000)" stroke="currentColor"><g transform="translate(305.000000, 111.500000) scale(-1, 1) rotate(-180.000000) translate(-305.000000, -111.500000) translate(297.000000, 105.000000)"><path d="M2.20710678,6.5 L6.85355339,1.85355339 L7.20710678,1.5 L6.5,0.792893219 L6.14644661,1.14644661 L1.14644661,6.14644661 L1.05805826,6.23483496 L0.792893219,6.5 L1.14644661,6.85355339 L6.14644661,11.8535534 L6.5,12.2071068 L7.20710678,11.5 L6.85355339,11.1464466 L2.20710678,6.5 Z" id="Combined-Shape"></path><path d="M10.2071068,6.5 L14.8535534,1.85355339 L15.2071068,1.5 L14.5,0.792893219 L14.1464466,1.14644661 L9.14644661,6.14644661 L9.05805826,6.23483496 L8.79289322,6.5 L9.14644661,6.85355339 L14.1464466,11.8535534 L14.5,12.2071068 L15.2071068,11.5 L14.8535534,11.1464466 L10.2071068,6.5 Z" id="Combined-Shape"></path></g></g></g></svg>
- </svg></div>
- <div class="">
- <ul class="list-note-preview">{% for obj in notes_list %}
- <li>
- <a href="{% url 'notes:note-detail' user.username obj.slug %}">
- <h4>{{obj.title}}</h4>
- <div class="note-preview">{{obj.body_text|truncatewords:12}}</div>
- </a>
- </li>
- {% endfor %}</ul>
- </div>
+ {% include "notes/partials/note_sidebar.html" with note_list=note_list %}
</aside>
<div class="balance-container">
</div>
diff --git a/design/templates/notes/notebook_detail.html b/design/templates/notes/notebook_detail.html
index 36873e1..a0b06a3 100644
--- a/design/templates/notes/notebook_detail.html
+++ b/design/templates/notes/notebook_detail.html
@@ -1,49 +1,59 @@
{% extends 'base.html' %}
+{% block extrastyles %}
+<script async src="/media/js/vanilla-picker.min.js"></script>
+{% endblock %}
+
{% block content %}
<main>
- <article class="note-container">
- {%comment%}
- <form id="new-note-form" action="{% url 'notebook-api-list' %}" method="post">
+ <article class="note-container single-col">
+ <div class="flex-wrapper">
+ <form id="nb-edit-form" action="{% url 'notebook-api-detail' object.pk %}" method="PATCH">{% csrf_token %}
+ {{ form.non_field_errors }}
+
+ <div class="flex-wrapper flex-inner">
+ {% for field in form %}{% if field.name == 'color_rgb' %}
+ <fieldset class="color-picker-fieldset" id="color-picker" {% if form.instance.color_rgb %}style="background-color: {{form.instance.color_rgb}}; border: none;"{%endif%}>
+ <input type="text" name="color_rgb" value="{{form.instance.color_rgb}}" maxlength="20" id="id_color_rgb">
+ {% if field.errors %}{{field.errors}}{% endif %}
+ </fieldset>{% else %}
+ <fieldset class="hide">
+ {{field.label_tag}}
+ {{field}}
+ {% if field.errors %}{{field.errors}}{% endif %}
+ </fieldset>{% endif %}
+ {% endfor %}
+ <h1 class="notebook-title" id="nb-title">{{object.name}}</h1>
+ </div>
+ <input id="btn-js-hide" type="submit" class="btn sm" value="Save" >
+ </form>
+ <div class="edit-btn-wrapper"><a class="hide btn btn-hollow" id="edit-toggle-btn">Edit</a></div>
+ </div>
+
+ <form id="new-note-form" action="{% url 'notebook-api-list' %}" method="post" class="hide">
<label>Create a new notebook</label>
{% csrf_token %}
{{ form.non_field_errors }}
{% for field in form %}
- <fieldset class="{% if field.errors %}error {%endif%}{% if field.name == 'body_qjson' or field.name == 'body_html' %}hide {%endif%}" id="fs-{{field.name}}" >
+ <fieldset class="" id="fs-{{field.name}}" >
{{field.label_tag}}
{{field}}
{% if field.errors %}{{field.errors}}{% endif %}
</fieldset>
{% endfor %}
- <p><input class="btn btn-inline" value="create" type="submit" /></p>
+ <p><input id="btn-js-hide" class="btn btn-inline" value="create" type="submit" /></p>
</form>
- {%endcomment%}
-{{object}}
- <ul class="list-note-preview">{% for obj in object.note_set.all %}
- <li>
- <a href="{% url 'notes:note-detail' user.username obj.slug %}">
- <h4>{{obj.title}}</h4>
- <div class="note-preview">{{obj.body_text|truncatewords:36}}</div>
- </a>
- </li>
+ <ul class="list-note-preview">{% for object in object.note_set.all %}
+ {% include "notes/partials/note_list.html" with object=object hidecolor=True hidenotebook=True %}
{% endfor %}</ul>
</article>
<aside class="note-list-container">
- <div class="svg-wrapper"><svg class="svg-icon-arrow">
- <svg viewBox="0 0 16 13" id="shape-double-arrow" width="100%" height="100%"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square"><g id="Showing-post-info" transform="translate(-297.000000, -105.000000)" stroke="currentColor"><g transform="translate(305.000000, 111.500000) scale(-1, 1) rotate(-180.000000) translate(-305.000000, -111.500000) translate(297.000000, 105.000000)"><path d="M2.20710678,6.5 L6.85355339,1.85355339 L7.20710678,1.5 L6.5,0.792893219 L6.14644661,1.14644661 L1.14644661,6.14644661 L1.05805826,6.23483496 L0.792893219,6.5 L1.14644661,6.85355339 L6.14644661,11.8535534 L6.5,12.2071068 L7.20710678,11.5 L6.85355339,11.1464466 L2.20710678,6.5 Z" id="Combined-Shape"></path><path d="M10.2071068,6.5 L14.8535534,1.85355339 L15.2071068,1.5 L14.5,0.792893219 L14.1464466,1.14644661 L9.14644661,6.14644661 L9.05805826,6.23483496 L8.79289322,6.5 L9.14644661,6.85355339 L14.1464466,11.8535534 L14.5,12.2071068 L15.2071068,11.5 L14.8535534,11.1464466 L10.2071068,6.5 Z" id="Combined-Shape"></path></g></g></g></svg>
- </svg></div>
- <div class="">
- <ul class="list-note-preview">{% for obj in notes_list %}
- <li>
- <a href="{% url 'notes:note-detail' user.username obj.slug %}">
- <h4>{{obj.title}}</h4>
- <div class="note-preview">{{obj.body_text|truncatewords:12}}</div>
- </a>
- </li>
- {% endfor %}</ul>
- </div>
+ {% include "notes/partials/note_sidebar.html" with note_list=note_list %}
</aside>
<div class="balance-container">
</div>
</main>
{% endblock %}
+{% block jsdomready %}
+window.url = "{% url 'notebook-api-detail' object.pk %}";
+{%endblock%}
diff --git a/design/templates/notes/notes_create.html b/design/templates/notes/notes_create.html
index 9bbdb26..9ca4111 100644
--- a/design/templates/notes/notes_create.html
+++ b/design/templates/notes/notes_create.html
@@ -5,8 +5,9 @@
{% endblock %}
{% block content %}
<main>
+ <article class="note-container">
<h1>Create a new note</h1>
- <form id="new-note-form" action="{% url 'notes:note-create' %}" method="post">
+ <form id="new-note-form" action="{% url 'notes:create' %}" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
{% for field in form %}
@@ -23,6 +24,24 @@
{% endfor %}
<p><input class="btn btn-inline" value="submit" type="submit" /></p>
</form>
+</article>
+ <aside class="note-list-container">
+ <div class="svg-wrapper"><svg class="svg-icon-arrow">
+ <svg viewBox="0 0 16 13" id="shape-double-arrow" width="100%" height="100%"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square"><g id="Showing-post-info" transform="translate(-297.000000, -105.000000)" stroke="currentColor"><g transform="translate(305.000000, 111.500000) scale(-1, 1) rotate(-180.000000) translate(-305.000000, -111.500000) translate(297.000000, 105.000000)"><path d="M2.20710678,6.5 L6.85355339,1.85355339 L7.20710678,1.5 L6.5,0.792893219 L6.14644661,1.14644661 L1.14644661,6.14644661 L1.05805826,6.23483496 L0.792893219,6.5 L1.14644661,6.85355339 L6.14644661,11.8535534 L6.5,12.2071068 L7.20710678,11.5 L6.85355339,11.1464466 L2.20710678,6.5 Z" id="Combined-Shape"></path><path d="M10.2071068,6.5 L14.8535534,1.85355339 L15.2071068,1.5 L14.5,0.792893219 L14.1464466,1.14644661 L9.14644661,6.14644661 L9.05805826,6.23483496 L8.79289322,6.5 L9.14644661,6.85355339 L14.1464466,11.8535534 L14.5,12.2071068 L15.2071068,11.5 L14.8535534,11.1464466 L10.2071068,6.5 Z" id="Combined-Shape"></path></g></g></g></svg>
+ </svg></div>
+ <div class="">
+ <ul class="list-note-preview">{% for obj in notes_list %}
+ <li>
+ <a href="{% url 'notes:detail' user.username obj.slug %}">
+ <h4>{{obj.title}}</h4>
+ <div class="note-preview">{{obj.body_text|truncatewords:12}}</div>
+ </a>
+ </li>
+ {% endfor %}</ul>
+ </div>
+ </aside>
+ <div class="balance-container">
+ </div>
</main>
{% endblock %}
diff --git a/design/templates/notes/notes_detail.html b/design/templates/notes/notes_detail.html
index 95583bd..b2ddbc3 100644
--- a/design/templates/notes/notes_detail.html
+++ b/design/templates/notes/notes_detail.html
@@ -2,26 +2,38 @@
{% block extrastyles %}
<link rel="stylesheet" href="/media/quill.snow.css" />
{% endblock %}
-{% block breadcrumbs %}
-<li><a href="{%url 'notes:note-list' user.username %}">Notes</a></li>
-{% endblock %}
-
{% block content %}
<main>
<article class="note-container">
+ <form action="" method="post" id="note-edit-form">{% csrf_token %}
<header class="note-header">
<div class="note-header-left">
- <span class="label">tags:</span>
- <ul>{% for tag in object.tags.all %}
- <li>
- <a href="{% url 'notes:note-tag' user.username tag.slug %}">{{tag}}</a>
- </li>
- {%endfor%}</ul>
- <div class="notebook">
- <span class="label">notebook:</span>
- <a href="">{{object.notebook.name}}</a>
- </div>
+
+ <div class="flex-wrapper">
+ <div class="notebook">
+ <a id="n-link" href="{% url 'notebooks:detail' object.slug %}"><span id="n-box" class="color-box" style="background-color: {{object.notebook.color_rgb}}"></span><span id="n-name">{{object.notebook}}</span></a>
+ <div id="notebook-edit" class="hide">
+ <span class="error">{{ form.notebook.errors }}</span>
+ {{form.notebook}}
+ </div>
+ </div>
+ <div class="tags">
+ <span class="label">tags:</span>
+ <div id="t-display" class="">{% for tag in object.tags.all %}
+ <a class="t-link" href="{% url 'notes:tags' tag.slug %}">
+ <span class="tag-wrapper" data-bg-color="#{{tag.color_color_rgb}};" >{{tag}}</span>
+ </a>{%endfor%}
+ </div>
+ <div id="tags-edit" class="hide">
+ <span class="error">{{ form.notebook.errors }}</span>
+ {{form.tags}}
+ </div>
+ </div>
+ </div>
+
</div>
+ <div class="hide">{{form.body_text}}</div>
+ <fieldset class="hide">{{form.title}}</fieldset>
<div class="note-header-right">
<h2 class="note-time">{{object.date_created|date:"M d, Y"}}</h2>
{% if object.url %}<h3 class="note-url"><a class="btn btn-small btn-subtle" href="{{object.url}}">Source</a><a class="btn btn-small btn-subtle right-padding-0 left-margin-2" href="object.cache">Archive</a></h3>{% endif %}
@@ -30,10 +42,6 @@
<div class="edit-btn-wrapper"><button class="hide btn btn-hollow" id="edit-toggle-btn">Edit</button></div>
<h1 id="note-title" class="note-title">{{object.title}}</h1>
<div id="q-container" class="inactive"><div id="note-body">{% if object.body_html %}{{object.body_html|safe}}{%else%}{{object.body_text}}{%endif%}</div></div>
- <form action="" method="post" id="note-edit-form">{% csrf_token %}
- {% for field in form %}{% if field.name in "title body_text" %}
- <div class="hide">{{field}}</div>
- {% endif%}{% endfor %}
<input id="btn-js-hide" type="submit" class="btn sm" value="Save" >
</form>
</article>
@@ -44,7 +52,7 @@
<div class="">
<ul class="list-note-preview">{% for obj in notes_list %}
<li>
- <a href="{% url 'notes:note-detail' user.username obj.slug %}">
+ <a href="{% url 'notes:detail' obj.slug obj.pk %}">
<h4>{{obj.title}}</h4>
<div class="note-preview">{{obj.body_text|truncatewords:12}}</div>
</a>
@@ -71,34 +79,6 @@ document.addEventListener('readystatechange', event => {
});
</script>
{% endblock %}
- <script>
{% block jsdomready %}
- var btn = document.getElementById("edit-toggle-btn"),
- qcontainer = document.getElementById('q-container'),
- title = document.getElementById('note-title'),
- form = document.getElementById('note-edit-form'),
- note_html = document.createElement('textarea'),
- note_qjson = document.createElement('textarea');
-
- window.editing = false;
- window.quillchange = false;
-
- hljs.initHighlightingOnLoad();
- btn.classList.remove('hide');
- note_html.setAttribute('name', 'body_html');
- note_html.setAttribute('class', 'hide');
- note_html.setAttribute('id', 'id_body_html');
- note_qjson.setAttribute('name', 'body_qjson');
- note_qjson.setAttribute('id', 'id_body_qjson');
- note_qjson.setAttribute('class', 'hide');
- form.appendChild(note_html);
- form.appendChild(note_qjson);
- document.getElementById("btn-js-hide").classList.add("hide");
- btn.addEventListener('click', function(){edit_note(this, title, qcontainer, window.quill, "{% url 'notes-api-detail' object.pk %}" )}, false)
+window.url = "{% url 'notes-api-detail' object.pk %}";
{%endblock%}
- </script>
-
-'indent
-'align
-'direction
-'code-block
diff --git a/design/templates/notes/notes_list.html b/design/templates/notes/notes_list.html
index b1c1700..393cf89 100644
--- a/design/templates/notes/notes_list.html
+++ b/design/templates/notes/notes_list.html
@@ -4,16 +4,11 @@
<main>
<article class="note-container">
<h1>Notes {% if tags|length == 1%} tagged {% for tag in tags%}{{tag}}{%endfor%}{%endif%}</h1>
- <div>Tagged with: {% for tag in tags%}<a href="{{tag|slugify}}">{{tag}}</a>{%endfor%}</div>
- <ul class="list-note-preview">{% for obj in object_list %}
- <li>
- <a href="{% url 'notes:note-detail' user.username obj.slug %}">
- <h4>{{obj.title}}</h4>
- <div class="note-preview">{{obj.body_text|truncatewords:36}}</div>
- </a>
- </li>
+ {% if tags|length >= 1%}<div>Tagged with: {% for tag in tags%}<a href="{{tag|slugify}}">{{tag}}</a>{%endfor%}</div>{%endif%}
+ <ul class="list-note-preview">{% for object in object_list %}
+ {% include "notes/partials/note_list.html" with object=object %}
{% endfor %}</ul>
- </article>
+ </article>{% if tags|length >= 1%}
<aside class="note-list-container">
<div class="svg-wrapper"><svg class="svg-icon-arrow">
<svg viewBox="0 0 16 13" id="shape-double-arrow" width="100%" height="100%"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square"><g id="Showing-post-info" transform="translate(-297.000000, -105.000000)" stroke="currentColor"><g transform="translate(305.000000, 111.500000) scale(-1, 1) rotate(-180.000000) translate(-305.000000, -111.500000) translate(297.000000, 105.000000)"><path d="M2.20710678,6.5 L6.85355339,1.85355339 L7.20710678,1.5 L6.5,0.792893219 L6.14644661,1.14644661 L1.14644661,6.14644661 L1.05805826,6.23483496 L0.792893219,6.5 L1.14644661,6.85355339 L6.14644661,11.8535534 L6.5,12.2071068 L7.20710678,11.5 L6.85355339,11.1464466 L2.20710678,6.5 Z" id="Combined-Shape"></path><path d="M10.2071068,6.5 L14.8535534,1.85355339 L15.2071068,1.5 L14.5,0.792893219 L14.1464466,1.14644661 L9.14644661,6.14644661 L9.05805826,6.23483496 L8.79289322,6.5 L9.14644661,6.85355339 L14.1464466,11.8535534 L14.5,12.2071068 L15.2071068,11.5 L14.8535534,11.1464466 L10.2071068,6.5 Z" id="Combined-Shape"></path></g></g></g></svg>
@@ -21,7 +16,7 @@
<div class="">
<ul class="list-note-preview">{% for obj in notes_list %}
<li>
- <a href="{% url 'notes:note-detail' user.username obj.slug %}">
+ <a href="{% url 'notes:detail' obj.slug obj.pk %}">
<h4>{{obj.title}}</h4>
<div class="note-preview">{{obj.body_text|truncatewords:12}}</div>
</a>
@@ -29,6 +24,10 @@
{% endfor %}</ul>
</div>
</aside>
+ {%else%}
+ <div class="balance-container-left">
+ </div>
+ {%endif%}
<div class="balance-container">
</div>
</main>