Design pending blogs in organizations (#123)

This commit is contained in:
Phuoc Anh Kha Le 2024-07-23 01:24:43 -05:00 committed by GitHub
parent 66f6212947
commit 44554d7de6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 423 additions and 306 deletions

View file

@ -208,13 +208,8 @@ class PostView(TitleMixin, CommentedDetailView, PageVoteDetailView, BookMarkDeta
orgs = list(self.object.organizations.all())
if self.request.profile:
if self.request.profile.id in self.object.get_authors():
for org in orgs:
if org.is_member(self.request.profile):
context["editable_orgs"].append(org)
else:
for org in orgs:
if org.is_admin(self.request.profile):
if self.request.profile.can_edit_organization(org):
context["editable_orgs"].append(org)
return context

View file

@ -1118,7 +1118,7 @@ class EditOrganizationBlog(
LoginRequiredMixin,
TitleMixin,
OrganizationHomeView,
MemberOrganizationMixin,
AdminOrganizationMixin,
UpdateView,
):
template_name = "organization/blog/edit.html"
@ -1134,19 +1134,20 @@ class EditOrganizationBlog(
self.blog_id = kwargs["blog_pk"]
self.blog = BlogPost.objects.get(id=self.blog_id)
if self.organization not in self.blog.organizations.all():
raise Exception("This blog does not belong to this organization")
if (
self.request.profile.id not in self.blog.get_authors()
and not self.can_edit_organization(self.organization)
):
raise Exception("Not allowed to edit this blog")
except:
raise Exception(_("This blog does not belong to this organization"))
if not self.request.profile.can_edit_organization(self.organization):
raise Exception(_("Not allowed to edit this blog"))
except Exception as e:
return generic_message(
request,
_("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):
self.blog_id = kwargs["blog_pk"]
BlogPost.objects.get(pk=self.blog_id).delete()
@ -1164,6 +1165,22 @@ class EditOrganizationBlog(
if request.POST["action"] == "Delete":
self.create_notification("Delete blog")
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(
"organization_pending_blogs",
args=(self.organization_id, self.organization.slug),
@ -1185,9 +1202,8 @@ class EditOrganizationBlog(
args=[self.organization.id, self.organization.slug, self.blog_id],
)
html = f'<a href="{link}">{blog.title} - {self.organization.name}</a>'
post_authors = blog.authors.all()
posible_users = self.organization.admins.all() | post_authors
make_notification(posible_users, action, html, self.request.profile)
to_users = (self.organization.admins.all() | blog.get_authors()).distinct()
make_notification(to_users, action, html, self.request.profile)
def form_valid(self, form):
with revisions.create_revision():
@ -1224,3 +1240,8 @@ class PendingBlogs(
def get_title(self):
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

View file

@ -24,9 +24,6 @@ msgstr "Giới thiệu"
msgid "Status"
msgstr "Máy chấm"
msgid "Courses"
msgstr "Khóa học"
msgid "Suggestions"
msgstr "Đề xuất ý tưởng"
@ -42,9 +39,6 @@ msgstr "Đăng ký tên"
msgid "Report"
msgstr "Báo cáo tiêu cực"
msgid "Bug Report"
msgstr "Báo cáo lỗi"
msgid "2sat"
msgstr ""
@ -600,6 +594,12 @@ msgstr ""
msgid "z-function"
msgstr ""
#~ msgid "Courses"
#~ msgstr "Khóa học"
#~ msgid "Bug Report"
#~ msgstr "Báo cáo lỗi"
#~ msgid "Insert Image"
#~ msgstr "Chèn hình ảnh"

View file

@ -795,6 +795,14 @@ noscript #noscript {
background-color: royalblue !important;
}
.background-green {
background-color: #28a745 !important;
}
.background-red {
background-color: #dc3545 !important;
}
.background-footer {
color: #808080;
}

View file

@ -1769,6 +1769,12 @@ noscript #noscript {
.background-royalblue {
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 {
color: rgb(152, 143, 129);
}
@ -3828,15 +3834,6 @@ svg line.messageLine1 {
div.mermaid .actor {
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 {
background-color: white !important;
padding-top: 1rem;
@ -3844,6 +3841,3 @@ mitid-authenticators-code-app > .code-app-container {
iframe#unpaywall[src$="unpaywall.html"] {
color-scheme: light !important;
}
.oui-icon {
font-family: 'Oui Icons' !important;
}

View 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>

View file

@ -1,28 +1,71 @@
{% extends "organization/home-base.html" %}
{% block middle_content %}
<table class="table">
<thead>
<tr>
<th>
{{_('Blog')}}
</th>
<th>
{{_('Author')}}
</th>
<th>
{{_('Post time')}}
</th>
</tr>
</thead>
<tbody>
{% for blog in blogs %}
<tr>
<td><a href="{{url('edit_organization_blog', organization.id, organization.slug, blog.id)}}">{{blog.title}}</a></td>
<td>{{link_users(blog.authors.all())}}</td>
<td>{{- blog.publish_on|date(_("N j, Y, g:i a")) -}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% block org_js %}
{% include "organization/blog/pending-js.html" %}
{% endblock %}
{% block middle_content %}
{% for post in blogs %}
<section class="{% if post.sticky %}sticky {% endif %} blog-box" id="post-{{post.id}}">
{% if post.is_organization_private and show_organization_private_icon %}
<div style="margin-bottom: 1em; display: flex;">
{% for org in post.organizations.all() %}
{% include "organization/tag.html" %}
{% endfor %}
</div>
{% endif %}
<div style="margin-bottom: 0.5em">
<span class="post-content-header time">
{% with authors=post.get_authors() %}
{%- if authors -%}
<span class="user-img" style="width: 1.5em; height: 1.5em">
<img src="{{gravatar(authors[0])}}" loading="lazy">
</span>
<span class="post-authors">{{ link_users(authors) }}</span>
{%- endif -%}
{% endwith %}
&#8226;
{{ relative_time(post.publish_on) }}
{%- if post.sticky %} &#8226;
<i title="Sticky" class="fa fa-star fa-fw"></i>{% endif -%}
</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 %}