# HG changeset patch # User bsw # Date 1612219434 -3600 # Node ID 2f9e1e882de68ae85a14a4f667485719090292c1 # Parent 9e26d81775a1bef1b9a98d6c414b0d59b928f8f2 Add/remove interest via fetch diff -r 9e26d81775a1 -r 2f9e1e882de6 app/main/_layout/default.html --- a/app/main/_layout/default.html Mon Feb 01 21:57:34 2021 +0100 +++ b/app/main/_layout/default.html Mon Feb 01 23:43:54 2021 +0100 @@ -13,7 +13,7 @@ - + diff -r 9e26d81775a1 -r 2f9e1e882de6 app/main/delegation/_info.lua --- a/app/main/delegation/_info.lua Mon Feb 01 21:57:34 2021 +0100 +++ b/app/main/delegation/_info.lua Mon Feb 01 23:43:54 2021 +0100 @@ -185,8 +185,13 @@ } elseif not issue.half_frozen and not info.own_participation then ui.link{ - attr = { class = "float-right mdl-button mdl-js-button mdl-button--icon mdl-button--accent" }, - module = "interest", action = "update", params = { issue_id = issue.id }, + attr = { + class = "float-right mdl-button mdl-js-button mdl-button--icon mdl-button--accent", + }, + form_attr = { + onsubmit = "toggleInterest(" .. issue.id .. ", 'issue_" .. issue.id .. "_interest_icon'); return false;" + }, + module = "interest", action = "update", params = { issue_id = issue.id, interested = true }, routing = { default = { mode = "redirect", module = "index", view = "index", params = { unit = redirect_unit, area = redirect_area @@ -194,13 +199,18 @@ anchor = "issue_" .. issue.id } }, content = function() - ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "star_outline" } + ui.tag{ tag = "i", attr = { id = "issue_" .. issue.id .. "_interest_icon", class = "material-icons" }, content = "star_outline" } end } elseif not issue.half_frozen and info.own_participation then ui.link{ - attr = { class = "float-right mdl-button mdl-js-button mdl-button--icon mdl-button--accent" }, - module = "interest", action = "update", params = { issue_id = issue.id, delete = true }, + attr = { + class = "float-right mdl-button mdl-js-button mdl-button--icon mdl-button--accent" + }, + form_attr = { + onsubmit = "toggleInterest(" .. issue.id .. ", 'issue_" .. issue.id .. "_interest_icon'); return false;" + }, + module = "interest", action = "update", params = { issue_id = issue.id, interested = false }, routing = { default = { mode = "redirect", module = "index", view = "index", params = { unit = redirect_unit, area = redirect_area @@ -208,7 +218,7 @@ anchor = "issue_" .. issue.id } }, content = function() - ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "star" } + ui.tag{ tag = "i", attr = { id = "issue_" .. issue.id .. "_interest_icon", class = "material-icons" }, content = "star" } end } if not issue.closed and info.own_participation and info.weight and info.weight > 1 then diff -r 9e26d81775a1 -r 2f9e1e882de6 app/main/interest/_action/update.lua --- a/app/main/interest/_action/update.lua Mon Feb 01 21:57:34 2021 +0100 +++ b/app/main/interest/_action/update.lua Mon Feb 01 23:43:54 2021 +0100 @@ -1,41 +1,5 @@ -local issue_id = assert(param.get("issue_id", atom.integer), "no issue id given") - -local interest = Interest:by_pk(issue_id, app.session.member.id) - -local issue = Issue:new_selector():add_where{ "id = ?", issue_id }:for_share():single_object_mode():exec() - -if not app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then - return execute.view { module = "index", view = "403" } -end +local issue_id = param.get("issue_id", atom.integer) +local interested = param.get("interested", atom.boolean) -if issue.closed then - slot.put_into("error", _"This issue is already closed.") - return false -elseif issue.fully_frozen then - slot.put_into("error", _"Voting for this issue has already begun.") - return false -elseif - (issue.half_frozen and issue.phase_finished) or - (not issue.accepted and issue.phase_finished) -then - slot.put_into("error", _"Current phase is already closed.") - return false -end +return Interest:update(issue_id, app.session.member, interested) -if param.get("delete", atom.boolean) then - if interest then - interest:destroy() --- slot.put_into("notice", _"Interest removed") - else --- slot.put_into("notice", _"Interest already removed") - end - return -end - -if not interest then - interest = Interest:new() - interest.issue_id = issue_id - interest.member_id = app.session.member_id - interest:save() --- slot.put_into("notice", _"Interest updated") -end diff -r 9e26d81775a1 -r 2f9e1e882de6 app/main/interest/_action/xhr_update.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/interest/_action/xhr_update.lua Mon Feb 01 23:43:54 2021 +0100 @@ -0,0 +1,9 @@ +local issue_id = param.get("issue_id", atom.integer) +local interested = param.get("interested", atom.boolean) + +slot.set_layout() + +if not Interest:update(issue_id, app.session.member, interested) then + request.set_status("500 Internal Server Error") +end + diff -r 9e26d81775a1 -r 2f9e1e882de6 app/main/issue/_sidebar.lua --- a/app/main/issue/_sidebar.lua Mon Feb 01 21:57:34 2021 +0100 +++ b/app/main/issue/_sidebar.lua Mon Feb 01 23:43:54 2021 +0100 @@ -86,7 +86,7 @@ ui.link { attr = { class = "mdl-button mdl-js-button" }, module = "interest", action = "update", - params = { issue_id = issue.id, delete = true }, + params = { issue_id = issue.id, interested = false }, routing = { default = { mode = "redirect", module = initiative and "initiative" or "issue", view = "show", id = initiative and initiative.id or issue.id } }, @@ -96,7 +96,7 @@ ui.link { attr = { class = "mdl-button mdl-js-button" }, module = "interest", action = "update", - params = { issue_id = issue.id }, + params = { issue_id = issue.id, interested = true }, routing = { default = { mode = "redirect", module = initiative and "initiative" or "issue", view = "show", id = initiative and initiative.id or issue.id } }, diff -r 9e26d81775a1 -r 2f9e1e882de6 app/main/issue/_sidebar_whatcanido.lua --- a/app/main/issue/_sidebar_whatcanido.lua Mon Feb 01 21:57:34 2021 +0100 +++ b/app/main/issue/_sidebar_whatcanido.lua Mon Feb 01 23:43:54 2021 +0100 @@ -278,7 +278,7 @@ routing = { default = { mode = "redirect", module = view_module, view = "show", id = view_id } }, - params = { issue_id = issue.id, delete = true }, + params = { issue_id = issue.id, interested = false }, text = _"remove my interest" } end } @@ -291,7 +291,7 @@ ui.tag { tag = "li", content = function () ui.link { module = "interest", action = "update", - params = { issue_id = issue.id }, + params = { issue_id = issue.id, interested = true }, routing = { default = { mode = "redirect", module = view_module, view = "show", id = view_id } }, diff -r 9e26d81775a1 -r 2f9e1e882de6 model/interest.lua --- a/model/interest.lua Mon Feb 01 21:57:34 2021 +0100 +++ b/model/interest.lua Mon Feb 01 23:43:54 2021 +0100 @@ -22,4 +22,45 @@ :add_where{ "issue_id = ? AND member_id = ?", issue_id, member_id } :optional_object_mode() :exec() -end \ No newline at end of file +end + +function Interest:update(issue_id, member, interested) + local interest = Interest:by_pk(issue_id, member.id) + + local issue = Issue:new_selector():add_where{ "id = ?", issue_id }:for_share():single_object_mode():exec() + + if not member:has_voting_right_for_unit_id(issue.area.unit_id) then + return execute.view { module = "index", view = "403" } + end + + if issue.closed then + slot.put_into("error", _"This issue is already closed.") + return false + elseif issue.fully_frozen then + slot.put_into("error", _"Voting for this issue has already begun.") + return false + elseif + (issue.half_frozen and issue.phase_finished) or + (not issue.accepted and issue.phase_finished) + then + slot.put_into("error", _"Current phase is already closed.") + return false + end + + if interested == false then + if interest then + interest:destroy() + end + return true + end + + if not interest then + interest = Interest:new() + interest.issue_id = issue_id + interest.member_id = app.session.member_id + interest:save() + end + + return true + +end diff -r 9e26d81775a1 -r 2f9e1e882de6 static/js/xhr.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/static/js/xhr.js Mon Feb 01 23:43:54 2021 +0100 @@ -0,0 +1,21 @@ +function toggleInterest(issue_id, iconElId) { + var iconEl = document.getElementById(iconElId); + var interested = iconEl.innerHTML == "star_outline"; + + var data = new FormData(); + data.append("issue_id", issue_id); + data.append("interested", interested); + + fetch("/lf/interest/xhr_update", { + method : "POST", + body: data + }).then( + response => { + if (response.status == 200) { + iconEl.innerHTML = interested ? "star" : "star_outline"; + } + } + ); + +} +