add sorting topics view
This commit is contained in:
parent
800cd6a1bf
commit
12269dd9b3
35
apps/mod.lua
35
apps/mod.lua
@ -1,23 +1,46 @@
|
||||
local app = require("lapis").Application()
|
||||
|
||||
local db = require("lapis.db")
|
||||
|
||||
local util = require("util")
|
||||
|
||||
local models = require("models")
|
||||
local Users = models.Users
|
||||
|
||||
app:get("user_list", "/list", function(self)
|
||||
-- everything here requires a logged in moderator
|
||||
app:before_filter(function(self)
|
||||
self.me = util.get_logged_in_user(self)
|
||||
if not self.me then
|
||||
return {redirect_to = self:url_for("all_topics")}
|
||||
self:write{redirect_to = self:url_for("all_topics")}
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if not self.me:is_mod() then
|
||||
return {redirect_to = self:url_for("all_topics")}
|
||||
self:write{redirect_to = self:url_for("all_topics")}
|
||||
return
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
app:get("user_list", "/list", function(self)
|
||||
self.users = Users:select("")
|
||||
|
||||
|
||||
return {render = "mod.user-list"}
|
||||
end)
|
||||
|
||||
app:get("sort_topics", "/sort-topics", function(self)
|
||||
self.topics = db.query("SELECT * FROM topics ORDER BY sort_order ASC")
|
||||
self.page_title = "sorting topics"
|
||||
return {render = "mod.sort-topics"}
|
||||
end)
|
||||
|
||||
app:post("sort_topics", "/sort-topics", function(self)
|
||||
local updates = self.params
|
||||
db.query("BEGIN")
|
||||
for topic_id, new_order in pairs(updates) do
|
||||
db.update("topics", {sort_order = new_order}, {id = topic_id})
|
||||
end
|
||||
db.query("COMMIT")
|
||||
return {redirect_to = self:url_for("sort_topics")}
|
||||
end)
|
||||
|
||||
return app
|
||||
|
@ -364,3 +364,16 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
||||
grid-area: topic-locked-container;
|
||||
border: 2px outset rgb(217.26, 220.38, 213.42);
|
||||
}
|
||||
|
||||
.draggable-topic {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
background-color: #c1ceb1;
|
||||
padding: 20px;
|
||||
margin: 12px 0;
|
||||
border-top: 6px outset rgb(217.26, 220.38, 213.42);
|
||||
border-bottom: 6px outset rgb(135.1928346457, 145.0974015748, 123.0025984252);
|
||||
}
|
||||
.draggable-topic.dragged {
|
||||
background-color: rgb(177, 206, 204.5);
|
||||
}
|
||||
|
45
js/sort-topics.js
Normal file
45
js/sort-topics.js
Normal file
@ -0,0 +1,45 @@
|
||||
// https://codepen.io/crouchingtigerhiddenadam/pen/qKXgap
|
||||
let selected = null;
|
||||
let container = document.getElementById("topics-container")
|
||||
|
||||
function isBefore(el1, el2) {
|
||||
let cur
|
||||
if (el2.parentNode === el1.parentNode) {
|
||||
for (cur = el1.previousSibling; cur; cur = cur.previousSibling) {
|
||||
if (cur === el2) return true
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function dragOver(e) {
|
||||
let target = e.target.closest(".draggable-topic")
|
||||
|
||||
if (!target || target === selected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBefore(selected, target)) {
|
||||
container.insertBefore(selected, target)
|
||||
} else {
|
||||
container.insertBefore(selected, target.nextSibling)
|
||||
}
|
||||
}
|
||||
|
||||
function dragEnd() {
|
||||
if (!selected) return;
|
||||
|
||||
selected.classList.remove("dragged")
|
||||
selected = null;
|
||||
for (let i = 0; i < container.childElementCount - 1; i++) {
|
||||
let input = container.children[i].querySelector(".topic-input");
|
||||
input.value = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
function dragStart(e) {
|
||||
e.dataTransfer.effectAllowed = 'move'
|
||||
e.dataTransfer.setData('text/plain', null)
|
||||
selected = e.target
|
||||
selected.classList.add("dragged")
|
||||
}
|
@ -366,3 +366,18 @@ input[type="text"], input[type="password"], textarea, select {
|
||||
grid-area: topic-locked-container;
|
||||
border: 2px outset $light;
|
||||
}
|
||||
|
||||
|
||||
.draggable-topic {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
background-color: $accent_color;
|
||||
padding: 20px;
|
||||
margin: 12px 0;
|
||||
border-top: 6px outset $light;
|
||||
border-bottom: 6px outset $dark2;
|
||||
|
||||
&.dragged {
|
||||
background-color: $button_color;
|
||||
}
|
||||
}
|
||||
|
19
views/mod/sort-topics.etlua
Normal file
19
views/mod/sort-topics.etlua
Normal file
@ -0,0 +1,19 @@
|
||||
<div class="darkbg settings-container">
|
||||
<% if infobox then %>
|
||||
<% render("views.common.infobox", infobox) %>
|
||||
<% end %>
|
||||
<h1>Change topics order</h1>
|
||||
<p>Drag topic titles to reoder them. Press submit when done. The topics will appear to users in the order set here.</p>
|
||||
<form method="post" id=topics-container>
|
||||
<% for _, topic in ipairs(topics) do %>
|
||||
<div draggable="true" class="draggable-topic" ondragover="dragOver(event)" ondragstart="dragStart(event)" ondragend="dragEnd()">
|
||||
<div class="thread-title"><%= topic.name %></div>
|
||||
<div><%= topic.description %></div>
|
||||
<input type="hidden" name="<%= topic.id %>" value="<%= topic.sort_order %>" class="topic-input">
|
||||
</div>
|
||||
<% end %>
|
||||
<input type=submit value="Save order">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/sort-topics.js"></script>
|
@ -2,6 +2,7 @@
|
||||
<h1 class="thread-title">All topics</h1>
|
||||
<% if me:is_mod() then %>
|
||||
<a class="linkbutton" href="<%= url_for("topic_create") %>">Create new topic</a>
|
||||
<a class="linkbutton" href="<%= url_for("sort_topics") %>">Sort topics</a>
|
||||
<% end %>
|
||||
</nav>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user