0.2.3 #99

Merged
sonny merged 112 commits from development into master 2020-05-23 16:58:42 +02:00
80 changed files with 525 additions and 775 deletions
Showing only changes of commit a4b5373ed2 - Show all commits

View file

@ -0,0 +1,17 @@
{% extends "components/form/form.html" %}
{% load i18n %}
{% block actions %}
<section class="section form__section--last">
<fieldset class="fieldset form__fieldset">
{% include "components/form/cancel-button.html" %}
{% include "components/form/confirm-button.html" %}
</fieldset>
<fieldset class="fieldset form__fieldset">
<a class="link" href="{% url 'accounts:password-reset' %}">
<small class="small">{% trans "I forgot my password" %}</small>
</a>
</fieldset>
</section>
{% endblock actions %}

View file

@ -0,0 +1,18 @@
{% extends "components/form/form.html" %}
{% load i18n %}
{% block actions %}
<section class="section form__section--last">
<fieldset class="fieldset form__fieldset">
{% include "components/form/cancel-button.html" %}
</fieldset>
<fieldset class="fieldset form__fieldset">
<a class="link button button--primary" href="{% url 'accounts:password-change' %}">
{% trans "Change password" %}
</a>
{% include "components/form/confirm-button.html" %}
</fieldset>
</section>
{% endblock actions %}

View file

@ -1,24 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main id="login--page" class="main">
<form class="form login-form" method="POST" action="{% url 'accounts:login' %}">
{% csrf_token %}
<div class="form__header">
<h1 class="form__title">Login</h1>
</div>
<fieldset class="login-form__fieldset">
{{ form }}
</fieldset>
<fieldset class="login-form__fieldset">
<button class="button button--confirm" type="submit">Login</button>
<a class="link" href="{% url 'accounts:password-reset' %}">
<small class="small">I forgot my password</small>
</a>
</fieldset>
</form>
</main>
{% endblock %}

View file

@ -1,22 +0,0 @@
{% extends "base.html" %}
{% load static i18n %}
{% block content %}
<main class="main">
<form class="form password-change-form" method="post">
{% csrf_token %}
<div class="form__header">
<h1 class="h1 form__title">{% trans "Password change" %}</h1>
</div>
<fieldset class="fieldset password-change-form__fieldset">
{{ form }}
</fieldset>
<fieldset class="fieldset password-reset-form__fieldset">
<a class="button button--cancel" href="{% url 'accounts:settings' %}">Cancel</a>
<button class="button button--confirm" type="submit">Change</button>
</fieldset>
</form>
</main>
{% endblock %}

View file

@ -1,42 +0,0 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<main id="settings--page" class="main">
<form class="form settings-form" method="post">
{% csrf_token %}
<div class="form__header">
<h1 class="h1 form__title">{% trans "User settings" %}</h1>
</div>
{{ form.non_field_errors }}
<section class="section form__section settings-form__section">
<fieldset class="form__fieldset settings-form__fieldset">
<label class="label settings-form__label" for="first_name">{% trans "First name" %}</label>
{{ form.first_name.errors }}
{{ form.first_name }}
</fieldset>
<fieldset class="form__fieldset settings-form__fieldset">
<label class="label settings-form__label" for="last_name">{% trans "Last name" %}</label>
{{ form.last_name.errors }}
{{ form.last_name }}
</fieldset>
</section>
<section class="section form__section settings-form__section">
<fieldset class="form__fieldset settings-form__fieldset">
<a class="link button button--cancel" href="{% url 'index' %}">Cancel</a>
<span class="span">
<a class="link button button--primary" href="{% url 'accounts:password-change' %}">
{% trans "Change password" %}
</a>
<button class="button button--confirm">Save</button>
</span>
</fieldset>
</section>
</form>
</main>
{% endblock %}

View file

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block content %}
<main id="login--page" class="main">
{% include "accounts/components/login-form.html" with form=form title="Login" confirm_text="Login" %}
</main>
{% endblock %}

View file

@ -0,0 +1,8 @@
{% extends "base.html" %}
{% block content %}
<main id="password-change--page" class="main">
{% url 'accounts:settings' as cancel_url %}
{% include "components/form/form.html" with form=form title="Change password" confirm_text="Change password" cancel_url=cancel_url %}
</main>
{% endblock %}

View file

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block content %}
<main id="settings--page" class="main">
{% include "accounts/components/settings-form.html" with form=form title="User profile" confirm_text="Save" %}
</main>
{% endblock %}

View file

@ -11,7 +11,7 @@ from newsreader.accounts.models import User
class LoginView(django_views.LoginView):
template_name = "accounts/login.html"
template_name = "accounts/views/login.html"
success_url = reverse_lazy("index")
@ -74,32 +74,32 @@ class ActivationResendView(registration_views.ResendActivationView):
# prompts for a new password
# PasswordResetCompleteView shows a success message for the above
class PasswordResetView(django_views.PasswordResetView):
template_name = "password-reset/password_reset_form.html"
subject_template_name = "password-reset/password_reset_subject.txt"
email_template_name = "password-reset/password_reset_email.html"
template_name = "password-reset/password-reset.html"
subject_template_name = "password-reset/password-reset-subject.txt"
email_template_name = "password-reset/password-reset-email.html"
success_url = reverse_lazy("accounts:password-reset-done")
class PasswordResetDoneView(django_views.PasswordResetDoneView):
template_name = "password-reset/password_reset_done.html"
template_name = "password-reset/password-reset-done.html"
class PasswordResetConfirmView(django_views.PasswordResetConfirmView):
template_name = "password-reset/password_reset_confirm.html"
template_name = "password-reset/password-reset-confirm.html"
success_url = reverse_lazy("accounts:password-reset-complete")
class PasswordResetCompleteView(django_views.PasswordResetCompleteView):
template_name = "password-reset/password_reset_complete.html"
template_name = "password-reset/password-reset-complete.html"
class PasswordChangeView(django_views.PasswordChangeView):
template_name = "accounts/password_change.html"
template_name = "accounts/views/password-change.html"
success_url = reverse_lazy("accounts:settings")
class SettingsView(ModelFormMixin, FormView):
template_name = "accounts/settings.html"
template_name = "accounts/views/settings.html"
success_url = reverse_lazy("accounts:settings")
form_class = UserSettingsForm
model = User

View file

@ -172,6 +172,8 @@ AUTH_PASSWORD_VALIDATORS = [
# Authentication user model
AUTH_USER_MODEL = "accounts.User"
LOGIN_REDIRECT_URL = "/"
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = "en-us"

View file

@ -1,4 +1,5 @@
from django import forms
from django.utils.translation import gettext_lazy as _
import pytz
@ -11,6 +12,7 @@ class CollectionRuleForm(forms.ModelForm):
timezone = forms.ChoiceField(
widget=forms.Select(attrs={"size": len(pytz.all_timezones)}),
choices=((timezone, timezone) for timezone in pytz.all_timezones),
help_text=_("The timezone which the feed uses"),
)
def __init__(self, *args, **kwargs):

View file

@ -1,37 +0,0 @@
{% extends "base.html" %}
{% load static i18n %}
{% block content %}
<main id="import--page" class="main">
<form class="form import-form" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="form__header">
<h1 class="h1 form__title">{% trans "Import an OPML file" %}</h1>
</div>
<section class="section form__section import-form__section">
<fieldset class="form__fieldset import-form__fieldset">
<label class="label import-form__label" for="name">
{% trans "File" %}
</label>
{{ form.file.errors }}
{{ form.file }}
</fieldset>
<fieldset class="form__fieldset import-form__fieldset">
<label class="label import-form__label" for="name">
{% trans "Skip existing" %}
</label>
{{ form.skip_existing }}
</fieldset>
<fieldset class="form__fieldset import-form__fieldset">
<a class="link button button--cancel" href="{% url 'news:collection:rules' %}">Cancel</a>
<button class="button button--confirm">Import</button>
</fieldset>
</section>
</form>
</main>
{% endblock %}

View file

@ -1,9 +0,0 @@
{% extends "collection/rule.html" %}
{% block form-header %}
<h1 class="h1 form__title">Create a rule</h1>
{% endblock %}
{% block confirm-button %}
<button class="button button--confirm">Create rule</button>
{% endblock %}

View file

@ -1,9 +0,0 @@
{% extends "collection/rule.html" %}
{% block form-header %}
<h1 class="h1 form__title">Update rule</h1>
{% endblock %}
{% block confirm-button %}
<button class="button button--confirm">Save rule</button>
{% endblock %}

View file

@ -1,55 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main id="rule--page" class="main">
<form class="form rule-form" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="form__header">
{% block form-header %}{% endblock %}
</div>
<section class="section form__section rule-form__section">
<fieldset class="form__fieldset rule-form__fieldset">
<label class="label" for="name">Name</label>
{{ form.name.errors }}
{{ form.name }}
</fieldset>
<fieldset class="form__fieldset rule-form__fieldset">
<label class="label" for="name">Category</label>
{{ form.category.errors }}
{{ form.category }}
</fieldset>
<fieldset class="form__fieldset rule-form__fieldset">
<label class="label" for="name">Feed url</label>
{{ form.url.errors }}
{{ form.url }}
</fieldset>
<fieldset class="form__fieldset rule-form__fieldset">
<label class="label" for="name">Favicon url</label>
{{ form.favicon.errors }}
{{ form.favicon }}
</fieldset>
<fieldset class="form__fieldset rule-form__fieldset">
<label class="label" for="name">Timezone</label>
<small class="small helptext">The timezone which the feed uses</small>
{{ form.timezone.errors }}
{{ form.timezone }}
</fieldset>
</section>
<section class="section form__section rule-form__section">
<fieldset class="form__fieldset rule-form__fieldset">
<a class="link button button--cancel" href="{% url 'news:collection:rules' %}">Cancel</a>
{% block confirm-button %}{% endblock %}
</fieldset>
</section>
</form>
</main>
{% endblock %}

View file

@ -1,69 +0,0 @@
{% extends "base.html" %}
{% load i18n static %}
{% block content %}
<main id="rules--page" class="main">
<form class="form rules-form">
{% csrf_token %}
<div class="form__actions">
<input type="submit" class="button button--primary" formaction="{% url "news:collection:rules-enable" %}" formmethod="post" value="{% trans "Enable" %}" />
<input type="submit" class="button button--primary" formaction="{% url "news:collection:rules-disable" %}" formmethod="post" value="{% trans "Disable" %}" />
<input type="submit" class="button button--error" formaction="{% url "news:collection:rules-delete" %}" formmethod="post" value="{% trans "Delete" %}"/>
</div>
<table class="table rules-table">
<thead class="table__header rules-table__header">
<tr class="table__row rules-table__row">
<th class="table__heading rules-table__heading--select">
<input type="checkbox" id="select-all" data-input="rules" />
</th>
<th class="table__heading rules-table__heading--name">{% trans "Name" %}</th>
<th class="table__heading rules-table__heading--category">{% trans "Category" %}</th>
<th class="table__heading rules-table__heading--url">{% trans "URL" %}</th>
<th class="table__heading rules-table__heading--succeeded">{% trans "Successfuly ran" %}</th>
<th class="table__heading rules-table__heading--enabled">{% trans "Enabled" %}</th>
<th class="table__heading rules-table__heading--link"></th>
</tr>
</thead>
<tbody class="table__body">
{% for rule in rules %}
<tr class="table__row rules-table__row">
<td class="table__item rules-table__item"><input name="rules" type="checkbox" value="{{ rule.pk }}" /></td>
<td class="table__item rules-table__item" title="{{ rule.name }}">{{ rule.name }}</td>
<td class="table__item rules-table__item" title="{{ rule.category.name }}">{{ rule.category.name }}</td>
<td class="table__item rules-table__item" title="{{ rule.url }}">{{ rule.url }}</td>
<td class="table__item rules-table__item" title="{{ rule.succeeded }}">{{ rule.succeeded }}</td>
<td class="table__item rules-table__item" title="{{ rule.enabled }}">{{ rule.enabled }}</td>
<td class="table__item rules-table__item">
<a class="link" href="{% url "news:collection:rule-update" rule.pk %}"><i class="gg-pen"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
<div class="table__footer">
<div class="pagination">
<span class="pagination__previous">
{% if page_obj.has_previous %}
<a class="link button" href="?page=1">{% trans "first" %}</a>
<a class="link button" href="?page={{ page_obj.previous_page_number }}">{% trans "previous" %}</a>
{% endif %}
</span>
<span class="pagination__current">
{% blocktrans with current_number=page_obj.number total_count=page_obj.paginator.num_pages %}
Page {{ current_number }} of {{ total_count }}
{% endblocktrans %}
</span>
<span class="pagination__next">
{% if page_obj.has_next %}
<a class="link button" href="?page={{ page_obj.next_page_number }}">{% trans "next" %}</a>
<a class="link button" href="?page={{ page_obj.paginator.num_pages }}">{% trans "last" %}</a>
{% endif %}
</span>
</div>
</div>
</main>
{% endblock %}

View file

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main id="import--page" class="main">
{% url "news:collection:rules" as cancel_url %}
{% include "components/form/form.html" with form=form title="Import an OPML file" cancel_url=cancel_url confirm_text="Import rules" %}
</main>
{% endblock %}

View file

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main id="rule--page" class="main">
{% url "news:collection:rules" as cancel_url %}
{% include "components/form/form.html" with form=form title="Create rule" cancel_url=cancel_url confirm_text="Create rule" %}
</main>
{% endblock %}

View file

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main id="rule--page" class="main">
{% url "news:collection:rules" as cancel_url %}
{% include "components/form/form.html" with form=form title="Update rule" cancel_url=cancel_url confirm_text="Save rule" %}
</main>
{% endblock %}

View file

@ -0,0 +1,79 @@
{% extends "base.html" %}
{% load i18n static %}
{% block content %}
<main id="rules--page" class="main">
<form class="form rules-form">
{% csrf_token %}
<section class="section form__section form__section--actions">
<fieldset class="fieldset form__fieldset">
<input type="submit" class="button button--primary" formaction="{% url "news:collection:rules-enable" %}" formmethod="post" value="{% trans "Enable" %}" />
<input type="submit" class="button button--primary" formaction="{% url "news:collection:rules-disable" %}" formmethod="post" value="{% trans "Disable" %}" />
<input type="submit" class="button button--error" formaction="{% url "news:collection:rules-delete" %}" formmethod="post" value="{% trans "Delete" %}"/>
</fieldset>
<div class="form__actions">
<a class="link button button--confirm" href="{% url "news:collection:rule-create" %}">{% trans "Add a rule" %}</a>
</div>
</section>
<section class="section form__section">
<table class="table rules-table">
<thead class="table__header rules-table__header">
<tr class="table__row rules-table__row">
<th class="table__heading rules-table__heading--select">
<input type="checkbox" id="select-all" data-input="rules" />
</th>
<th class="table__heading rules-table__heading--name">{% trans "Name" %}</th>
<th class="table__heading rules-table__heading--category">{% trans "Category" %}</th>
<th class="table__heading rules-table__heading--url">{% trans "URL" %}</th>
<th class="table__heading rules-table__heading--succeeded">{% trans "Successfuly ran" %}</th>
<th class="table__heading rules-table__heading--enabled">{% trans "Enabled" %}</th>
<th class="table__heading rules-table__heading--link"></th>
</tr>
</thead>
<tbody class="table__body">
{% for rule in rules %}
<tr class="table__row rules-table__row">
<td class="table__item rules-table__item"><input name="rules" type="checkbox" value="{{ rule.pk }}" /></td>
<td class="table__item rules-table__item" title="{{ rule.name }}">{{ rule.name }}</td>
<td class="table__item rules-table__item" title="{{ rule.category.name }}">{{ rule.category.name }}</td>
<td class="table__item rules-table__item" title="{{ rule.url }}">{{ rule.url }}</td>
<td class="table__item rules-table__item" title="{{ rule.succeeded }}">{{ rule.succeeded }}</td>
<td class="table__item rules-table__item" title="{{ rule.enabled }}">{{ rule.enabled }}</td>
<td class="table__item rules-table__item">
<a class="link" href="{% url "news:collection:rule-update" rule.pk %}"><i class="gg-pen"></i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</section>
</form>
<div class="table__footer">
<div class="pagination">
<span class="pagination__previous">
{% if page_obj.has_previous %}
<a class="link button" href="?page=1">{% trans "first" %}</a>
<a class="link button" href="?page={{ page_obj.previous_page_number }}">{% trans "previous" %}</a>
{% endif %}
</span>
<span class="pagination__current">
{% blocktrans with current_number=page_obj.number total_count=page_obj.paginator.num_pages %}
Page {{ current_number }} of {{ total_count }}
{% endblocktrans %}
</span>
<span class="pagination__next">
{% if page_obj.has_next %}
<a class="link button" href="?page={{ page_obj.next_page_number }}">{% trans "next" %}</a>
<a class="link button" href="?page={{ page_obj.paginator.num_pages }}">{% trans "last" %}</a>
{% endif %}
</span>
</div>
</div>
</main>
{% endblock %}

View file

@ -48,21 +48,21 @@ class CollectionRuleDetailMixin:
class CollectionRuleListView(CollectionRuleViewMixin, ListView):
paginate_by = 50
template_name = "collection/rules.html"
template_name = "news/collection/views/rules.html"
context_object_name = "rules"
class CollectionRuleUpdateView(
CollectionRuleViewMixin, CollectionRuleDetailMixin, UpdateView
):
template_name = "collection/rule-update.html"
template_name = "news/collection/views/rule-update.html"
context_object_name = "rule"
class CollectionRuleCreateView(
CollectionRuleViewMixin, CollectionRuleDetailMixin, CreateView
):
template_name = "collection/rule-create.html"
template_name = "news/collection/views/rule-create.html"
class CollectionRuleBulkView(FormView):
@ -122,7 +122,7 @@ class CollectionRuleBulkDeleteView(CollectionRuleBulkView):
class OPMLImportView(FormView):
form_class = OPMLImportForm
success_url = reverse_lazy("news:collection:rules")
template_name = "collection/import.html"
template_name = "news/collection/views/import.html"
def form_valid(self, form):
user = self.request.user

View file

@ -1,15 +1,27 @@
from django import forms
from django.forms.widgets import CheckboxSelectMultiple
from newsreader.accounts.models import User
from newsreader.news.collection.models import CollectionRule
from newsreader.news.core.models import Category
class RulesWidget(CheckboxSelectMultiple):
template_name = "news/core/widgets/rules.html"
option_template_name = "news/core/widgets/rule.html"
def create_option(self, *args, **kwargs):
option = super().create_option(*args, **kwargs)
instance = self.choices.queryset.get(pk=option["value"])
if self.category and instance.category:
option["selected"] = self.category.pk == instance.category.pk
return {**option, "instance": instance}
class CategoryForm(forms.ModelForm):
rules = forms.ModelMultipleChoiceField(
required=False,
queryset=CollectionRule.objects.all(),
widget=forms.widgets.CheckboxSelectMultiple,
required=False, queryset=CollectionRule.objects.none(), widget=RulesWidget
)
user = forms.ModelChoiceField(
@ -23,6 +35,8 @@ class CategoryForm(forms.ModelForm):
super().__init__(*args, **kwargs)
self.fields["rules"].queryset = CollectionRule.objects.filter(user=self.user)
self.fields["rules"].widget.category = self.instance
self.fields["user"].queryset = User.objects.filter(pk=self.user.pk)
self.initial["user"] = self.user

View file

@ -1,9 +0,0 @@
{% extends "core/category.html" %}
{% block form-header %}
<h1 class="h1 form__title">Create a category</h1>
{% endblock %}
{% block confirm-button %}
<button class="button button--confirm">Create category</button>
{% endblock %}

View file

@ -1,9 +0,0 @@
{% extends "core/category.html" %}
{% block form-header %}
<h1 class="h1 form__title">Update category</h1>
{% endblock %}
{% block confirm-button %}
<button class="button button--confirm">Save category</button>
{% endblock %}

View file

@ -1,62 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main id="category--page" class="main">
<form class="form category-form" method="post">
{% csrf_token %}
<div class="form__header">
{% block form-header %}{% endblock %}
</div>
{{ form.non_field_errors }}
{{ form.user.errors }}
{{ form.user }}
<section class="section form__section category-form__section">
<fieldset class="form__fieldset category-form__fieldset">
<label class="label category-form__label" for="name">Name</label>
{{ form.name.errors }}
{{ form.name }}
</fieldset>
</section>
<section class="section form__section category-form__section">
<fieldset class="form__fieldset category-form__fieldset">
<label class="label category-form__label" for="rules">Collection rules</label>
<small class="small help-text">
Note that existing assigned rules will be reassigned to this category
</small>
{{ form.rules.errors }}
<ul class="list checkbox-list">
{% for rule in rules %}
<li class="list__item checkbox-list__item">
<input class="input category-form__input" type="checkbox" name="rules"
{% if category and rule.pk in category.rule_ids %}checked{% endif %}
value="{{ rule.pk }}" />
{% if rule.favicon %}
<img class="favicon" src="{{ rule.favicon }}" />
{% else %}
<i class="gg-image"></i>
{% endif %}
<span>{{ rule.name }}</span>
</li>
{% endfor %}
</ul>
</fieldset>
</section>
<section class="section form__section category-form__section">
<fieldset class="form__fieldset category-form__fieldset">
<a class="link button button--cancel" href="{% url 'news:core:categories' %}">Cancel</a>
{% block confirm-button %}{% endblock %}
</fieldset>
</section>
</form>
</main>
{% endblock %}

View file

@ -1,5 +1,4 @@
{% extends "base.html" %}
{% load static %}
{% block content %}

View file

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main id="category--page" class="main">
{% url "news:core:categories" as cancel_url %}
{% include "components/form/form.html" with form=form title="Create category" cancel_url=cancel_url confirm_text="Create category" %}
</main>
{% endblock %}

View file

@ -0,0 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main id="category--page" class="main">
{% url "news:core:categories" as cancel_url %}
{% include "components/form/form.html" with form=form title="Update category" cancel_url=cancel_url confirm_text="Save category" %}
</main>
{% endblock %}

View file

@ -1,5 +1,4 @@
{% extends "base.html" %}
{% load static %}
{% block content %}

View file

@ -0,0 +1,10 @@
<input class="input category-form__input" type="{{ option.type }}"
name="{{ option.name }}" value="{{ option.value|stringformat:'s' }}"{% if option.selected %} checked{% endif %} />
{% if option.instance.favicon %}
<img class="favicon" src="{{ option.instance.favicon }}" />
{% else %}
<i class="gg-image"></i>
{% endif %}
<span>{{ option.label }}</span>

View file

@ -0,0 +1,9 @@
<ul class="list checkbox-list">
{% for group, options, index in widget.optgroups %}
{% for option in options %}
<li class="list__item checkbox-list__item">
{% include "news/core/widgets/rule.html" with option=option only %}
</li>
{% endfor %}
{% endfor %}
</ul>

View file

@ -9,7 +9,7 @@ from newsreader.news.core.models import Category
class NewsView(TemplateView):
template_name = "core/homepage.html"
template_name = "news/core/views/homepage.html"
# TODO serialize objects to show filled main page
def get_context_data(self, **kwargs):
@ -55,14 +55,14 @@ class CategoryDetailMixin:
class CategoryListView(CategoryViewMixin, ListView):
template_name = "core/categories.html"
template_name = "news/core/views/categories.html"
context_object_name = "categories"
class CategoryUpdateView(CategoryViewMixin, CategoryDetailMixin, UpdateView):
template_name = "core/category-update.html"
template_name = "news/core/views/category-update.html"
context_object_name = "category"
class CategoryCreateView(CategoryViewMixin, CategoryDetailMixin, CreateView):
template_name = "core/category-create.html"
template_name = "news/core/views/category-create.html"

View file

@ -1,11 +0,0 @@
.activation-form {
margin: 10px 0;
& h4 {
padding: 20px 24px 5px 24px;
}
&__fieldset:last-child {
flex-direction: row;
justify-content: space-between;
}
}

View file

@ -1,13 +0,0 @@
.category-form {
@extend .form;
margin: 20px 0;
&__section:last-child {
& .category-form__fieldset {
display: flex;
flex-direction: row;
justify-content: space-between;
}
}
}

View file

@ -1,3 +1,5 @@
@import "mixin.scss";
.form {
display: flex;
flex-direction: column;
@ -8,6 +10,29 @@
font-family: $form-font;
background-color: $white;
&__section {
&--last {
& .form__fieldset {
display: flex;
flex-direction: row;
justify-content: space-between;
}
}
&--actions {
display: flex;
flex-direction: row !important;
& .form__fieldset {
flex-direction: row;
& > * {
margin: 0 0 0 5px;
}
}
}
}
&__fieldset {
@extend .fieldset;
}
@ -16,21 +41,24 @@
display: flex;
flex-direction: row;
padding: 15px;
@include form-padding;
}
&__actions {
display: flex;
justify-content: space-between;
flex-direction: row;
width: 50%;
padding: 15px;
@include form-padding;
}
&__title {
font-size: 18px;
}
&__intro {
@include form-padding;
}
& .favicon {
height: 20px;
}

View file

@ -1,17 +0,0 @@
.import-form {
margin: 20px 0;
&__fieldset:last-child {
display: flex;
flex-direction: row;
justify-content: space-between;
}
& input[type=file] {
width: 50%;
}
& input[type=checkbox] {
margin: 0 auto 0 10px;
}
}

View file

@ -1,33 +0,0 @@
.login-form {
@extend .form;
width: 100%;
h4 {
margin: 0;
padding: 20px 24px 5px 24px;
}
&__fieldset {
@extend .form__fieldset;
& label {
@extend .label;
}
& input {
@extend .input;
}
}
&__fieldset:last-child {
flex-direction: row-reverse;
justify-content: space-between;
}
&__fieldset:last-child {
.button {
padding: 10px 50px;
}
}
}

View file

@ -0,0 +1,3 @@
@mixin form-padding {
padding: 15px;
}

View file

@ -1,3 +0,0 @@
.password-reset-confirm-form {
margin: 20px 0;
}

View file

@ -1,18 +0,0 @@
.password-reset-form {
margin: 20px 0;
&__fieldset:last-child {
display: flex;
flex-direction: row;
justify-content: space-between;
}
& .form__header {
display: flex;
flex-direction: column;
}
& .form__title {
margin: 0 0 5px 0;
}
}

View file

@ -1,11 +0,0 @@
.register-form {
margin: 10px 0;
& h4 {
padding: 20px 24px 5px 24px;
}
&__fieldset:last-child {
flex-direction: row;
justify-content: space-between;
}
}

View file

@ -1,25 +0,0 @@
.rule-form {
margin: 20px 0;
&__section:last-child {
& .rule-form__fieldset {
display: flex;
flex-direction: row;
justify-content: space-between;
}
}
#id_category {
width: 50%;
padding: 0 10px;
}
#id_timezone {
max-height: 200px;
width: 50%;
margin: 0 15px;
padding: 0 10px;
}
}

View file

@ -1,9 +0,0 @@
.settings-form {
&__section:last-child {
& .settings-form__fieldset {
display: flex;
flex-direction: row;
justify-content: space-between;
}
}
}

View file

@ -1,15 +1,3 @@
@import "form";
@import "category-form";
@import "rule-form";
@import "rules-form";
@import "import-form";
@import "login-form";
@import "activation-form";
@import "register-form";
@import "password-reset-form";
@import "password-reset-confirm-form";
@import "settings-form";

View file

@ -1,10 +1,11 @@
@import "badge/index";
@import "button/index";
@import "help-text/index";
@import "input/index";
@import "label/index";
@import "link/index";
@import "h1/index";
@import "h2/index";
@import "h3/index";
@import "small/index";
@import "input/index";
@import "label/index";
@import "help-text/index";
@import "badge/index";
@import "select/index";

View file

@ -8,6 +8,15 @@
&:focus {
border: 1px $focus-blue solid;
}
&[type="file"] {
width: 40%;
}
&[type="checkbox"] {
align-self: flex-start;
margin: 0 0 0 10px;
}
}
input {

View file

@ -0,0 +1,13 @@
.select {
max-height: 200px;
&:not([size]){
width: 40%;
}
padding: 0 15px;
}
select {
@extend .select;
}

View file

@ -0,0 +1 @@
@import "select";

View file

@ -3,4 +3,29 @@
width: 50%;
border-radius: 4px;
& .form {
@extend .form;
width: 100%;
h4 {
margin: 0;
padding: 20px 24px 5px 24px;
}
&__section {
&--last {
flex-direction: row-reverse;
justify-content: space-between;
}
}
&__fieldset {
@extend .form__fieldset;
&--last {
}
}
}
}

View file

@ -0,0 +1,13 @@
<div class="card">
{% if header_text %}
{% include "components/card/header.html" %}
{% endif %}
{% if content %}
{% include "components/card/content.html" %}
{% endif %}
{% if footer_text %}
{% include "components/card/footer.html" %}
{% endif %}
</div>

View file

@ -0,0 +1,3 @@
<div class="card__content">
<p>{{ content }}</p>
</div>

View file

@ -0,0 +1,3 @@
<div class="card__footer">
<p>{{ footer_text }}</p>
</div>

View file

@ -0,0 +1,3 @@
<div class="card__header">
<h1>{{ header_text }}</h1>
</div>

View file

@ -0,0 +1,5 @@
{% load i18n %}
{% if cancel_url %}
<a class="link button button--cancel" href="{{ cancel_url }}">{% trans "Cancel" %}</a>
{% endif %}

View file

@ -0,0 +1,9 @@
{% load i18n %}
<button class="button button--confirm">
{% if confirm_text %}
{{ confirm_text }}
{% else %}
{% trans "Save" %}
{% endif %}
</button>

View file

@ -0,0 +1,3 @@
<section class="section form__section form__section--errors">
{{ errors }}
</section>

View file

@ -0,0 +1,43 @@
{% load i18n %}
<form class="form{% if classes %} {{ classes }}{% endif %}" method="{{ method|default:"post" }}" enctype="multipart/form-data">
{% csrf_token %}
{% if title %}
{% include "components/form/title.html" with title=title only %}
{% endif %}
{% block intro %}
{% endblock intro %}
{% if form.non_field_errors %}
{% include "components/form/errors.html" with errors=form.non_field_errors only %}
{% endif %}
{% block fields %}
<section class="section form__section">
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
{% for field in form.visible_fields %}
<fieldset class="fieldset form__fieldset">
{% include "components/form/label.html" %}
{{ field.errors }}
{{ field }}
{% include "components/form/help-text.html" %}
</fieldset>
{% endfor %}
</section>
{% endblock fields %}
{% block actions %}
<section class="section form__section--last">
<fieldset class="fieldset form__fieldset">
{% include "components/form/cancel-button.html" %}
{% include "components/form/confirm-button.html" %}
</fieldset>
</section>
{% endblock actions %}
</form>

View file

@ -0,0 +1 @@
<small class="small helptext">{{ field.help_text }}</small>

View file

@ -0,0 +1,3 @@
<label class="label form__label" for="{{ field.name }}">
{{ field.label }}
</label>

View file

@ -0,0 +1,3 @@
<section class="section form__header">
<h1 class="h1 form__title">{{ title }}</h1>
</section>

View file

@ -0,0 +1,13 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<main class="main">
{% trans "Password reset complete" as header_text %}
{% blocktrans asvar content %}
You may now <a href="{{ login_url }}">log in</a>
{% endblocktrans %}
{% include "components/card/card.html" with header_text=header_text content=content %}
</main>
{% endblock %}

View file

@ -0,0 +1,30 @@
{% extends "base.html" %}
{% load i18n %}
{% block meta %}
<!-- NOTE(joshblum): This prevents leaking the password reset token via the
Referer header to any 3rd party apps on the page. -->
<meta name="referrer" content="origin">
{% endblock %}
{% block content %}
<main class="main">
{% if validlink %}
{% url 'accounts:login' as cancel_url %}
{% trans "Enter your new password below to reset your password:" as title %}
{% trans "Change password" as confirm_text %}
{% include "components/form/form.html" with form=form title=title confirm_text=confirm_text cancel_url=cancel_url %}
{% else %}
{% trans "Password reset unsuccessful" as header_text %}
{% url 'accounts:password-reset' as reset_url %}
{% blocktrans asvar content %}
Password reset unsuccessful. Please
<a class="link" href="{{ reset_url }}">try again.</a>
{% endblocktrans %}
{% include "components/card/card.html" with header_text=header_text content=content %}
{% endif %}
</main>
{% endblock %}
{# This is used by django.contrib.auth #}

View file

@ -0,0 +1,16 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Password reset" %}{% endblock %}
{% block content %}
<main class="main">
{% trans "Password reset" as header_text %}
{% blocktrans asvar content %}
We have sent you an email with a link to reset your password. Please check
your email and click the link to continue.
{% endblocktrans %}
{% include "components/card/card.html" with header_text=header_text content=content %}
</main>
{% endblock %}

View file

@ -0,0 +1,11 @@
{% extends "components/form/form.html" %}
{% load i18n %}
{% block intro %}
<p class="form__intro">
{% blocktrans %}
Forgot your password? Enter your email in the form below and we'll send you
instructions for creating a new one.
{% endblocktrans %}
</p>
{% endblock intro %}

View file

@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block content %}
<main class="main">
{% include "password-reset/password-reset-form.html" with form=form title="Reset password" confirm_text="Reset password" %}
</main>
{% endblock %}

View file

@ -1,23 +0,0 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Password reset complete" %}{% endblock %}
{% block content %}
<main class="main">
<div class="card">
<div class="card__header">
<h1>{% trans "Password reset complete" %}</h1>
</div>
<div class="card__content">
<p>
{% trans "Your password has been reset!" %}
{% blocktrans %}
You may now <a href="{{ login_url }}">log in</a>
{% endblocktrans %}.
</p>
</div>
<div class="card__footer" />
</div>
</main>
{% endblock %}

View file

@ -1,55 +0,0 @@
{% extends "base.html" %}
{% load static i18n %}
{% block meta %}
<!-- NOTE(joshblum): This prevents leaking the password reset token via the
Referer header to any 3rd party apps on the page. -->
<meta name="referrer" content="origin">
{% endblock %}
{% block title %}{% trans "Confirm password reset" %}{% endblock %}
{% block content %}
<main class="main">
{% if validlink %}
<form class="form password-reset-confirm-form" method="POST">
{% csrf_token %}
<div class="form__header">
<h1 class="form__title">
{% trans "Enter your new password below to reset your password:" %}
</h1>
</div>
<fieldset class="fieldset password-reset-form__fieldset">
{{ form }}
</fieldset>
<fieldset class="fieldset password-reset-form__fieldset">
<a class="button button--cancel" href="{% url 'accounts:login' %}">Cancel</a>
<button class="button button--confirm" type="submit">Change password</button>
</fieldset>
</form>
{% else %}
<div class="card">
<div class="card__header">
<h1>{% trans "Password reset unsuccessful" %}</h1>
</div>
<div class="card__content">
<p>
{% url 'accounts:password-reset' as reset_url %}
{% blocktrans %}
Password reset unsuccessful. Please
<a class="link" href="{{ reset_url }}">try again.</a>
{% endblocktrans %}
</p>
</div>
<div class="card__footer" />
</div>
{% endif %}
</main>
{% endblock %}
{# This is used by django.contrib.auth #}

View file

@ -1,23 +0,0 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Password reset" %}{% endblock %}
{% block content %}
<main class="main">
<div class="card">
<div class="card__header">
<h1>{% trans "Password reset" %}</h1>
</div>
<div class="card__content">
<p>
{% blocktrans %}
We have sent you an email with a link to reset your password. Please check
your email and click the link to continue.
{% endblocktrans %}
</p>
</div>
<div class="card__footer" />
</div>
</main>
{% endblock %}

View file

@ -1,30 +0,0 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Reset password" %}{% endblock %}
{% block content %}
<main class="main">
<form class="form password-reset-form" method="POST">
{% csrf_token %}
<div class="form__header">
<h1 class="form__title">{% trans "Reset password" %}</h1>
<p>
{% blocktrans %}
Forgot your password? Enter your email in the form below and we'll send you
instructions for creating a new one.
{% endblocktrans %}
</p>
</div>
<fieldset class="fieldset password-reset-form__fieldset">
{{ form }}
</fieldset>
<fieldset class="fieldset password-reset-form__fieldset">
<a class="button button--cancel" href="{% url 'accounts:login' %}">Cancel</a>
<button class="button button--confirm" type="submit">Send reset mail</button>
</fieldset>
</form>
</main>
{% endblock %}

View file

@ -1,7 +1,5 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Account Activated" %}{% endblock %}
{% load i18n %}
{% comment %}
**registration/activation_complete.html**
@ -13,19 +11,14 @@ account is now active.
{% block content %}
<main class="main">
<div class="card">
<div class="card__header">
<h1>{% trans "Account activated" %}</h1>
</div>
<div class="card__content">
<p>
{% trans "Your account is now activated." %}
{% if not user.is_authenticated %}
{% trans "You can log in." %}
{% endif %}
</p>
</div>
<div class="card__footer" />
</div>
{% trans "Account activated" as header_text %}
{% if user.is_authenticated %}
{% trans "Your account is activated. You can now log in." as content %}
{% else %}
{% trans "Your account is activated." as content %}
{% endif %}
{% include "components/card/card.html" with header_text=header_text content=content %}
</main>
{% endblock %}

View file

@ -68,5 +68,5 @@ following context:
``HttpRequest`` instance for better flexibility.
For example it can be used to compute absolute register URL:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
{{ request.scheme }}://{{ request.get_host }}{% url 'accounts:activate' activation_key %}
{% endcomment %}

View file

@ -48,5 +48,5 @@ following context:
``HttpRequest`` instance for better flexibility.
For example it can be used to compute absolute register URL:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
{{ request.scheme }}://{{ request.get_host }}{% url 'accounts:activate' activation_key %}
{% endcomment %}

View file

@ -1,7 +1,5 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Activation Failure" %}{% endblock %}
{% load i18n %}
{% comment %}
**registration/activate.html**
@ -14,14 +12,8 @@ Used if account activation fails. With the default setup, has the following cont
{% block content %}
<main class="main">
<div class="card">
<div class="card__header">
<h1>{% trans "Activation Failure" %}</h1>
</div>
<div class="card__content">
<p>{% trans "Account activation failed." %}</p>
</div>
<div class="card__footer" />
</div>
{% trans "Activation Failure" as header_text %}
{% trans "Account activation failed." as content %}
{% include "components/card/card.html" with header_text=header_text content=content %}
</main>
{% endblock %}

View file

@ -14,18 +14,10 @@ the following context:
{% block content %}
<main class="main">
<div class="card">
<div class="card__header">
<h1>{% trans "Account activation resent" %}</h1>
</div>
<div class="card__content">
<p>
{% blocktrans %}
We have sent an email to {{ email }} with further instructions.
{% endblocktrans %}
</p>
</div>
<div class="card__footer" />
</div>
{% trans "Account activation resent" as header_text %}
{% blocktrans asvar content %}
We have sent an email to {{ email }} with further instructions.
{% endblocktrans %}
{% include "components/card/card.html" with header_text=header_text content=content %}
</main>
{% endblock %}

View file

@ -1,35 +1,9 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Resend Activation Email" %}{% endblock %}
{% comment %}
**registration/resend_activation_form.html**
Used to show the form users will fill out to resend the activation email. By
default, has the following context:
``form``
The registration form. This will be an instance of some subclass
of ``django.forms.Form``; consult `Django's forms documentation
<http://docs.djangoproject.com/en/dev/topics/forms/>`_ for
information on how to display this in a template.
{% endcomment %}
{% load static %}
{% block content %}
<main class="main">
<form class="form activation-form" method="POST">
{% csrf_token %}
<div class="form__header">
<h1 class="form__title">Resend activation code</h1>
</div>
<fieldset class="fieldset activation-form__fieldset">
{{ form }}
</fieldset>
<fieldset class="fieldset activation-form__fieldset">
<a class="button button--cancel" href="{% url 'accounts:login' %}">Cancel</a>
<button class="button button--confirm" type="submit">Resend code</button>
</fieldset>
</form>
{% url "accounts:login" as cancel_url %}
{% include "components/form/form.html" with form=form title="Resend activation code" cancel_url=cancel_url confirm_text="Resend code" %}
</main>
{% endblock %}

View file

@ -1,20 +1,10 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Registration is closed" %}{% endblock %}
{% block content %}
<main class="main">
<div class="card">
<div class="card__header">
<h1>{% trans "Registration is closed" %}</h1>
</div>
<div class="card__content">
<p>
{% trans "Sorry, but registration is closed at this moment. Come back later." %}
</p>
</div>
<div class="card__footer" />
</div>
{% trans "Registration is closed" as header_text %}
{% trans "Sorry, but registration is closed at this moment. Come back later." as content %}
{% include "components/card/card.html" with header_text=header_text content=content %}
</main>
{% endblock %}

View file

@ -1,7 +1,5 @@
{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Activation email sent" %}{% endblock %}
{% load i18n %}
{% comment %}
**registration/registration_complete.html**
@ -14,16 +12,8 @@ been sent.
{% block content %}
<main class="main">
<div class="card">
<div class="card__header">
<h1>{% trans "Activation email sent" %}</h1>
</div>
<div class="card__content">
<p>
{% trans "Please check your email to complete the registration process." %}
</p>
</div>
<div class="card__footer" />
</div>
{% trans "Activation email sent" as header_text %}
{% trans "Please check your email to complete the registration process." as content %}
{% include "components/card/card.html" with header_text=header_text content=content %}
</main>
{% endblock %}

View file

@ -1,22 +1,9 @@
{% extends "base.html" %}
{% load static %}
{% block content %}
<main class="main">
<form class="form register-form" method="POST">
{% csrf_token %}
<div class="form__header">
<h1 class="form__title">Register</h1>
</div>
<fieldset class="fieldset register-form__fieldset">
{{ form }}
</fieldset>
<fieldset class="fieldset register-form__fieldset">
<a class="button button--cancel" href="{% url 'accounts:login' %}">Cancel</a>
<button class="button button--confirm" type="submit">Register</button>
</fieldset>
</form>
{% url "accounts:login" as cancel_url %}
{% include "components/form/form.html" with form=form title="Register" cancel_url=cancel_url confirm_text="Register" %}
</main>
{% endblock %}