2023-08-13 11:50:21 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
manage project members
diff --git a/data.lua b/data.lua index d919615..18a0ea5 100644 --- a/data.lua +++ b/data.lua @@ -188,6 +188,29 @@ function Model:get_user_projects(user_id) ]], user_id) end +function Model:get_members(proj_id) + return self.db:execute([[ + SELECT nick, name FROM User JOIN Membership ON User.id = Membership.user_id + WHERE Membership.proj_id = ? ORDER BY nick; + ]], proj_id) +end + +function Model:add_member(proj_id, nick) + local user = self:get_user(nick) + if user == nil then return false end + local query = "INSERT INTO Membership(proj_id, user_id) VALUES (?, ?);" + self.db:execute(query, proj_id, user.id) + return true +end + +function Model:remove_member(proj_id, nick) + local user = self:get_user(nick) + if user == nil then return false end + local query = "DELETE FROM Membership WHERE proj_id = ? AND user_id = ?;" + self.db:execute(query, proj_id, user.id) + return true +end + function Model:update_project(old_name, new_name, desc, goal, color, priority) local query = [[ UPDATE Project SET name = ?, desc = ?, goal = ?, color = ?, priority = ? diff --git a/skopos.lua b/skopos.lua index 8ed88bc..07e029a 100644 --- a/skopos.lua +++ b/skopos.lua @@ -288,6 +288,40 @@ function App:routes() end return "/p", 303 end}, + -- members + {"GET", "/p/([-_%w]+)/m", + function (req, name) + local user = self:get_user(req) + if user == nil then return "/login?after="..req.path, 303 end + local proj = self.model:get_user_project(user.id, name) + if proj == nil then return "not found", 404 end + local members = self.model:get_members(proj.id) + local env = {title=self.title, user=user, proj=proj, members=members} + return lud.template.render_file("view/members.html", env) + end}, + {"POST", "/p/([-_%w]+)/m/add", + function (req, name) + local user = self:get_user(req) + if user == nil then return "/login?after="..req.path, 303 end + local proj = self.model:get_user_project(user.id, name) + if proj == nil then return "not found", 404 end + local nick = req.form.username + if self.model:add_member(proj.id, nick) then + self:log(LOG_INFO, "user "..user.nick.." added "..nick.." to "..name) + end + return "/p/"..name.."/m", 303 + end}, + {"POST", "/p/([-_%w]+)/m/([-_%w]+)/rem", + function (req, name, nick) + local user = self:get_user(req) + if user == nil then return "/login?after="..req.path, 303 end + local proj = self.model:get_user_project(user.id, name) + if proj == nil then return "not found", 404 end + if self.model:remove_member(proj.id, nick) then + self:log(LOG_INFO, "user "..user.nick.." removed "..nick.." from "..name) + end + return "/p/"..name.."/m", 303 + end}, -- tickets {"GET", "/p/([-_%w]+)/t/new", function (req, name) diff --git a/view/members.html b/view/members.html new file mode 100644 index 0000000..5c4cb55 --- /dev/null +++ b/view/members.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>{{$title}} - members</title> + <style> + .centered { text-align: center; } + % include view/menu.css + % include view/table.css + </style> +</head> +<body> + % include view/menu.html + <h1 class="centered">{{$proj.name}} - members</h1> + <table class="center"> + <tr> + <th>nick</th> + <th>name</th> + <th>remove</th> + </tr> + % for member in $members do + <tr> + <td><a href="/u/{{$member.nick}}">{{$member.nick}}</a></td> + <td>{{$member.name}}</td> + <td> + <form action="/p/{{$proj.name}}/m/{{$member.nick}}/rem" method="post"> + <button type="submit">remove</button> + </form> + </td> + </tr> + % end + </table> + <br> + <form class="centered" action="/p/{{$proj.name}}/m/add" method="post"> + <input type="text" name="username" placeholder="Username" required pattern="[-_A-Za-z0-9]+"> + <input type="submit" value="add"></li> + </form> +</body> +</html> diff --git a/view/menu.html b/view/menu.html index 7027ca6..69a185e 100644 --- a/view/menu.html +++ b/view/menu.html @@ -4,6 +4,7 @@ <a href="/p">projects</a> % if $proj ~= nil then <a href="/p/{{$proj.name}}">{{$proj.name}}</a> + <a href="/p/{{$proj.name}}/m">members</a> <a href="/p/{{$proj.name}}/a">archive</a> % if $tick ~= nil then <a href="/p/{{$proj.name}}/t/{{$tick.code}}/c/new">new comment</a>