Design pending blogs in organizations (#123)
This commit is contained in:
parent
66f6212947
commit
44554d7de6
8 changed files with 423 additions and 306 deletions
|
@ -208,14 +208,9 @@ class PostView(TitleMixin, CommentedDetailView, PageVoteDetailView, BookMarkDeta
|
||||||
orgs = list(self.object.organizations.all())
|
orgs = list(self.object.organizations.all())
|
||||||
|
|
||||||
if self.request.profile:
|
if self.request.profile:
|
||||||
if self.request.profile.id in self.object.get_authors():
|
for org in orgs:
|
||||||
for org in orgs:
|
if self.request.profile.can_edit_organization(org):
|
||||||
if org.is_member(self.request.profile):
|
context["editable_orgs"].append(org)
|
||||||
context["editable_orgs"].append(org)
|
|
||||||
else:
|
|
||||||
for org in orgs:
|
|
||||||
if org.is_admin(self.request.profile):
|
|
||||||
context["editable_orgs"].append(org)
|
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
|
@ -1118,7 +1118,7 @@ class EditOrganizationBlog(
|
||||||
LoginRequiredMixin,
|
LoginRequiredMixin,
|
||||||
TitleMixin,
|
TitleMixin,
|
||||||
OrganizationHomeView,
|
OrganizationHomeView,
|
||||||
MemberOrganizationMixin,
|
AdminOrganizationMixin,
|
||||||
UpdateView,
|
UpdateView,
|
||||||
):
|
):
|
||||||
template_name = "organization/blog/edit.html"
|
template_name = "organization/blog/edit.html"
|
||||||
|
@ -1134,19 +1134,20 @@ class EditOrganizationBlog(
|
||||||
self.blog_id = kwargs["blog_pk"]
|
self.blog_id = kwargs["blog_pk"]
|
||||||
self.blog = BlogPost.objects.get(id=self.blog_id)
|
self.blog = BlogPost.objects.get(id=self.blog_id)
|
||||||
if self.organization not in self.blog.organizations.all():
|
if self.organization not in self.blog.organizations.all():
|
||||||
raise Exception("This blog does not belong to this organization")
|
raise Exception(_("This blog does not belong to this organization"))
|
||||||
if (
|
if not self.request.profile.can_edit_organization(self.organization):
|
||||||
self.request.profile.id not in self.blog.get_authors()
|
raise Exception(_("Not allowed to edit this blog"))
|
||||||
and not self.can_edit_organization(self.organization)
|
except Exception as e:
|
||||||
):
|
|
||||||
raise Exception("Not allowed to edit this blog")
|
|
||||||
except:
|
|
||||||
return generic_message(
|
return generic_message(
|
||||||
request,
|
request,
|
||||||
_("Permission denied"),
|
_("Permission denied"),
|
||||||
_("Not allowed to edit this blog"),
|
e,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def publish_blog(self, request, *args, **kwargs):
|
||||||
|
self.blog_id = kwargs["blog_pk"]
|
||||||
|
BlogPost.objects.filter(pk=self.blog_id).update(visible=True)
|
||||||
|
|
||||||
def delete_blog(self, request, *args, **kwargs):
|
def delete_blog(self, request, *args, **kwargs):
|
||||||
self.blog_id = kwargs["blog_pk"]
|
self.blog_id = kwargs["blog_pk"]
|
||||||
BlogPost.objects.get(pk=self.blog_id).delete()
|
BlogPost.objects.get(pk=self.blog_id).delete()
|
||||||
|
@ -1164,6 +1165,22 @@ class EditOrganizationBlog(
|
||||||
if request.POST["action"] == "Delete":
|
if request.POST["action"] == "Delete":
|
||||||
self.create_notification("Delete blog")
|
self.create_notification("Delete blog")
|
||||||
self.delete_blog(request, *args, **kwargs)
|
self.delete_blog(request, *args, **kwargs)
|
||||||
|
cur_url = reverse(
|
||||||
|
"organization_home",
|
||||||
|
args=(self.organization_id, self.organization.slug),
|
||||||
|
)
|
||||||
|
return HttpResponseRedirect(cur_url)
|
||||||
|
elif request.POST["action"] == "Reject":
|
||||||
|
self.create_notification("Reject blog")
|
||||||
|
self.delete_blog(request, *args, **kwargs)
|
||||||
|
cur_url = reverse(
|
||||||
|
"organization_pending_blogs",
|
||||||
|
args=(self.organization_id, self.organization.slug),
|
||||||
|
)
|
||||||
|
return HttpResponseRedirect(cur_url)
|
||||||
|
elif request.POST["action"] == "Approve":
|
||||||
|
self.create_notification("Approve blog")
|
||||||
|
self.publish_blog(request, *args, **kwargs)
|
||||||
cur_url = reverse(
|
cur_url = reverse(
|
||||||
"organization_pending_blogs",
|
"organization_pending_blogs",
|
||||||
args=(self.organization_id, self.organization.slug),
|
args=(self.organization_id, self.organization.slug),
|
||||||
|
@ -1185,9 +1202,8 @@ class EditOrganizationBlog(
|
||||||
args=[self.organization.id, self.organization.slug, self.blog_id],
|
args=[self.organization.id, self.organization.slug, self.blog_id],
|
||||||
)
|
)
|
||||||
html = f'<a href="{link}">{blog.title} - {self.organization.name}</a>'
|
html = f'<a href="{link}">{blog.title} - {self.organization.name}</a>'
|
||||||
post_authors = blog.authors.all()
|
to_users = (self.organization.admins.all() | blog.get_authors()).distinct()
|
||||||
posible_users = self.organization.admins.all() | post_authors
|
make_notification(to_users, action, html, self.request.profile)
|
||||||
make_notification(posible_users, action, html, self.request.profile)
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
with revisions.create_revision():
|
with revisions.create_revision():
|
||||||
|
@ -1224,3 +1240,8 @@ class PendingBlogs(
|
||||||
|
|
||||||
def get_title(self):
|
def get_title(self):
|
||||||
return _("Pending blogs in %s") % self.organization.name
|
return _("Pending blogs in %s") % self.organization.name
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["org"] = self.organization
|
||||||
|
return context
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,9 +24,6 @@ msgstr "Giới thiệu"
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Máy chấm"
|
msgstr "Máy chấm"
|
||||||
|
|
||||||
msgid "Courses"
|
|
||||||
msgstr "Khóa học"
|
|
||||||
|
|
||||||
msgid "Suggestions"
|
msgid "Suggestions"
|
||||||
msgstr "Đề xuất ý tưởng"
|
msgstr "Đề xuất ý tưởng"
|
||||||
|
|
||||||
|
@ -42,9 +39,6 @@ msgstr "Đăng ký tên"
|
||||||
msgid "Report"
|
msgid "Report"
|
||||||
msgstr "Báo cáo tiêu cực"
|
msgstr "Báo cáo tiêu cực"
|
||||||
|
|
||||||
msgid "Bug Report"
|
|
||||||
msgstr "Báo cáo lỗi"
|
|
||||||
|
|
||||||
msgid "2sat"
|
msgid "2sat"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -600,6 +594,12 @@ msgstr ""
|
||||||
msgid "z-function"
|
msgid "z-function"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "Courses"
|
||||||
|
#~ msgstr "Khóa học"
|
||||||
|
|
||||||
|
#~ msgid "Bug Report"
|
||||||
|
#~ msgstr "Báo cáo lỗi"
|
||||||
|
|
||||||
#~ msgid "Insert Image"
|
#~ msgid "Insert Image"
|
||||||
#~ msgstr "Chèn hình ảnh"
|
#~ msgstr "Chèn hình ảnh"
|
||||||
|
|
||||||
|
|
|
@ -795,6 +795,14 @@ noscript #noscript {
|
||||||
background-color: royalblue !important;
|
background-color: royalblue !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.background-green {
|
||||||
|
background-color: #28a745 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-red {
|
||||||
|
background-color: #dc3545 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.background-footer {
|
.background-footer {
|
||||||
color: #808080;
|
color: #808080;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1769,6 +1769,12 @@ noscript #noscript {
|
||||||
.background-royalblue {
|
.background-royalblue {
|
||||||
background-color: rgb(25, 58, 158) !important;
|
background-color: rgb(25, 58, 158) !important;
|
||||||
}
|
}
|
||||||
|
.background-green {
|
||||||
|
background-color: rgb(32, 134, 55) !important;
|
||||||
|
}
|
||||||
|
.background-red {
|
||||||
|
background-color: rgb(165, 29, 42) !important;
|
||||||
|
}
|
||||||
.background-footer {
|
.background-footer {
|
||||||
color: rgb(152, 143, 129);
|
color: rgb(152, 143, 129);
|
||||||
}
|
}
|
||||||
|
@ -3828,15 +3834,6 @@ svg line.messageLine1 {
|
||||||
div.mermaid .actor {
|
div.mermaid .actor {
|
||||||
fill: var(--darkreader-neutral-background) !important;
|
fill: var(--darkreader-neutral-background) !important;
|
||||||
}
|
}
|
||||||
.google-material-icons {
|
|
||||||
font-family: 'Google Material Icons' !important;
|
|
||||||
}
|
|
||||||
.google-symbols {
|
|
||||||
font-family: 'Google Symbols Subset', 'Google Symbols' !important;
|
|
||||||
}
|
|
||||||
.material-icons-extended {
|
|
||||||
font-family: 'Material Icons Extended' !important;
|
|
||||||
}
|
|
||||||
mitid-authenticators-code-app > .code-app-container {
|
mitid-authenticators-code-app > .code-app-container {
|
||||||
background-color: white !important;
|
background-color: white !important;
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
|
@ -3844,6 +3841,3 @@ mitid-authenticators-code-app > .code-app-container {
|
||||||
iframe#unpaywall[src$="unpaywall.html"] {
|
iframe#unpaywall[src$="unpaywall.html"] {
|
||||||
color-scheme: light !important;
|
color-scheme: light !important;
|
||||||
}
|
}
|
||||||
.oui-icon {
|
|
||||||
font-family: 'Oui Icons' !important;
|
|
||||||
}
|
|
||||||
|
|
48
templates/organization/blog/pending-js.html
Normal file
48
templates/organization/blog/pending-js.html
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
function ajax_post(url, data, on_success) {
|
||||||
|
return $.ajax({
|
||||||
|
url: url,
|
||||||
|
type: 'POST',
|
||||||
|
data: data,
|
||||||
|
success: function (data, textStatus, jqXHR) {
|
||||||
|
if (typeof on_success !== 'undefined')
|
||||||
|
on_success();
|
||||||
|
},
|
||||||
|
error: function (data, textStatus, jqXHR) {
|
||||||
|
alert('Action failed: ' + data.responseText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removePost(postId) {
|
||||||
|
$('#post-' + postId).slideUp('normal', function () {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.approvePost = function (url, postId, e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const csrfToken = '{{ csrf_token }}';
|
||||||
|
ajax_post(url, {
|
||||||
|
id: postId,
|
||||||
|
action: 'Approve',
|
||||||
|
csrfmiddlewaretoken: csrfToken
|
||||||
|
}, function () {
|
||||||
|
removePost(postId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.rejectPost = function (url, postId, e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const csrfToken = '{{ csrf_token }}';
|
||||||
|
ajax_post(url, {
|
||||||
|
id: postId,
|
||||||
|
action: 'Reject',
|
||||||
|
csrfmiddlewaretoken: csrfToken
|
||||||
|
}, function () {
|
||||||
|
removePost(postId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,28 +1,71 @@
|
||||||
{% extends "organization/home-base.html" %}
|
{% extends "organization/home-base.html" %}
|
||||||
|
|
||||||
|
{% block org_js %}
|
||||||
|
{% include "organization/blog/pending-js.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block middle_content %}
|
{% block middle_content %}
|
||||||
<table class="table">
|
{% for post in blogs %}
|
||||||
<thead>
|
<section class="{% if post.sticky %}sticky {% endif %} blog-box" id="post-{{post.id}}">
|
||||||
<tr>
|
{% if post.is_organization_private and show_organization_private_icon %}
|
||||||
<th>
|
<div style="margin-bottom: 1em; display: flex;">
|
||||||
{{_('Blog')}}
|
{% for org in post.organizations.all() %}
|
||||||
</th>
|
{% include "organization/tag.html" %}
|
||||||
<th>
|
{% endfor %}
|
||||||
{{_('Author')}}
|
</div>
|
||||||
</th>
|
{% endif %}
|
||||||
<th>
|
<div style="margin-bottom: 0.5em">
|
||||||
{{_('Post time')}}
|
<span class="post-content-header time">
|
||||||
</th>
|
{% with authors=post.get_authors() %}
|
||||||
</tr>
|
{%- if authors -%}
|
||||||
</thead>
|
<span class="user-img" style="width: 1.5em; height: 1.5em">
|
||||||
<tbody>
|
<img src="{{gravatar(authors[0])}}" loading="lazy">
|
||||||
{% for blog in blogs %}
|
</span>
|
||||||
<tr>
|
<span class="post-authors">{{ link_users(authors) }}</span>
|
||||||
<td><a href="{{url('edit_organization_blog', organization.id, organization.slug, blog.id)}}">{{blog.title}}</a></td>
|
{%- endif -%}
|
||||||
<td>{{link_users(blog.authors.all())}}</td>
|
{% endwith %}
|
||||||
<td>{{- blog.publish_on|date(_("N j, Y, g:i a")) -}}</td>
|
•
|
||||||
</tr>
|
{{ relative_time(post.publish_on) }}
|
||||||
{% endfor %}
|
{%- if post.sticky %} •
|
||||||
</tbody>
|
<i title="Sticky" class="fa fa-star fa-fw"></i>{% endif -%}
|
||||||
</table>
|
</span>
|
||||||
|
</div>
|
||||||
|
<h2 class="title">
|
||||||
|
<a href="{{ url('blog_post', post.id, post.slug) }}">{{ post.title }}</a>
|
||||||
|
</h2>
|
||||||
|
<div class="blog-description">
|
||||||
|
<div class="summary content-description">
|
||||||
|
{% cache 86400 'post_content' post.id %}
|
||||||
|
{{ post.content|markdown(lazy_load=True)|reference|str|safe }}
|
||||||
|
{% endcache %}
|
||||||
|
</div>
|
||||||
|
<div class="show-more"> {{_("...More")}} </div>
|
||||||
|
</div>
|
||||||
|
{% if request.profile.can_edit_organization(org) %}
|
||||||
|
<div class="actionbar-box">
|
||||||
|
<div class="actionbar {{'hide_texts_on_mobile' if hide_texts_on_mobile}}">
|
||||||
|
<span class="actionbar-block">
|
||||||
|
<a class="actionbar-button white background-green" href="#" onclick="javascript:approvePost('{{ url('edit_organization_blog', org.id , org.slug , post.id) }}', {{ post.id }}, event)">
|
||||||
|
<i class="fa fa-check" style="font-size: large;"></i>
|
||||||
|
<span class="actionbar-text">{{_("Approve")}}</span>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span class="actionbar-block">
|
||||||
|
<a class="actionbar-button black" href="{{ url('edit_organization_blog', org.id , org.slug , post.id) }}">
|
||||||
|
<i class="fa fa-edit" style="font-size: large;"></i>
|
||||||
|
<span class="actionbar-text">{{_("Edit")}}</span>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span class="actionbar-block">
|
||||||
|
<a class="actionbar-button white background-red" href="#" onclick="javascript:rejectPost('{{ url('edit_organization_blog', org.id , org.slug , post.id) }}', {{ post.id }}, event)">
|
||||||
|
<i class="fa fa-times" style="font-size: large;"></i>
|
||||||
|
<span class="actionbar-text">{{_("Reject")}}</span>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
|
{% endfor %}
|
||||||
|
{% include "feed/has_next.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
Loading…
Reference in a new issue