# HG changeset patch # User bsw # Date 1366476034 -7200 # Node ID 81bde33c22568f715045a2bda9a88bdd1256dfa5 # Parent 0d75cd1cdcd5d6c25ed9bd6ff050e9a2627dbd9e Added support for regular delegation check, fixed css for pagination diff -r 0d75cd1cdcd5 -r 81bde33c2256 app/main/_filter/21_auth.lua --- a/app/main/_filter/21_auth.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/app/main/_filter/21_auth.lua Sat Apr 20 18:40:34 2013 +0200 @@ -89,6 +89,19 @@ trace.debug("Member locked.") request.redirect{ module = 'index', view = 'login' } else + if config.check_delegations_interval_hard and app.session.member_id and app.session.needs_delegation_check + and not (module == "admin" or (module == "index" and ( + view == "check_delegations" + or action == "check_delegations" + or action == "logout" + or view == "about" + or view == "usage_terms" + or action == "set_lang") + )) + and not (module == "member_image" and view == "show") then + request.redirect{ module = 'index', view = 'check_delegations' } + return + end if auth_needed then trace.debug("Authentication accepted.") else diff -r 0d75cd1cdcd5 -r 81bde33c2256 app/main/_filter_view/30_navigation.lua --- a/app/main/_filter_view/30_navigation.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/app/main/_filter_view/30_navigation.lua Sat Apr 20 18:40:34 2013 +0200 @@ -10,7 +10,7 @@ view = 'index' } - if app.session:has_access("anonymous") then + if app.session:has_access("anonymous") and not (app.session.needs_delegation_check) then ui.link{ content = _"Search", diff -r 0d75cd1cdcd5 -r 81bde33c2256 app/main/index/_action/check_delegations.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/index/_action/check_delegations.lua Sat Apr 20 18:40:34 2013 +0200 @@ -0,0 +1,38 @@ +local delegations = Delegation:delegations_to_check_for_member_id(app.session.member_id, true) + + +-- check if for any unit/area delegation an option is choosen +for i, delegation in ipairs(delegations) do + + local option = param.get("delegation_" .. delegation.id) + + if option == "confirm" then + elseif option == "revoke" then + else + slot.put_into("error", _"Please decide for each delegation to confirm or to revoke it!") + return false + end + +end + +-- revoke delegations +for i, delegation in ipairs(delegations) do + + local option = param.get("delegation_" .. delegation.id) + + if option == "revoke" then + local d = Delegation:by_id(delegation.id) + if d.truster_id == app.session.member_id then + d:destroy() + end + end +end + +-- set delegation check as done +app.session.member.last_delegation_check = "now" +app.session.member.last_activity = "now" +app.session.member.active = true +app.session.member:save() + +app.session.needs_delegation_check = false +app.session:save() diff -r 0d75cd1cdcd5 -r 81bde33c2256 app/main/index/_action/login.lua --- a/app/main/index/_action/login.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/app/main/index/_action/login.lua Sat Apr 20 18:40:34 2013 +0200 @@ -55,8 +55,12 @@ if member then member.last_login = "now" - member.last_activity = "now" - member.active = true + if config.check_delegations_interval_hard and member.needs_delegation_check_hard then + app.session.needs_delegation_check = true + else + member.last_activity = "now" + member.active = true + end if member.lang == nil then member.lang = app.session.lang else diff -r 0d75cd1cdcd5 -r 81bde33c2256 app/main/index/_menu.lua --- a/app/main/index/_menu.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/app/main/index/_menu.lua Sat Apr 20 18:40:34 2013 +0200 @@ -1,6 +1,6 @@ ui.tag{ tag = "ul", content = function() - if app.session.member_id then + if app.session.member_id and not app.session.needs_delegation_check then ui.tag{ tag = "li", content = function() ui.link{ @@ -55,7 +55,9 @@ } end } - + end + + if app.session.member_id then ui.tag{ tag = "li", content = function() ui.link{ diff -r 0d75cd1cdcd5 -r 81bde33c2256 app/main/index/_notifications.lua --- a/app/main/index/_notifications.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/app/main/index/_notifications.lua Sat Apr 20 18:40:34 2013 +0200 @@ -14,6 +14,21 @@ } end +if config.check_delegations_interval_soft then + local member = Member:new_selector() + :add_where({ "id = ?", app.session.member_id }) + :add_field({ "now() > COALESCE(last_delegation_check, activated) + ?::interval", config.check_delegations_interval_soft }, "needs_delegation_check_soft") + :single_object_mode() + :exec() + + if member.needs_delegation_check_soft then + notification_links[#notification_links+1] = { + module = "index", view = "check_delegations", + text = _"Check your delegations!" + } + end +end + local broken_delegations_count = Delegation:selector_for_broken(app.session.member_id):count() if broken_delegations_count > 0 then diff -r 0d75cd1cdcd5 -r 81bde33c2256 app/main/index/check_delegations.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/index/check_delegations.lua Sat Apr 20 18:40:34 2013 +0200 @@ -0,0 +1,110 @@ +local delegations = Delegation:delegations_to_check_for_member_id(app.session.member_id) + +ui.title(_"Current unit and area delegations need confirmation") + +ui.actions(function() + if not app.session.needs_delegation_check then + ui.link{ module = "index", view = "index", text = _"Cancel" } + end +end) + +util.help("index.check_delegations", _"Check delegations") + +ui.form{ + module = "index", action = "check_delegations", + routing = { + default = { mode = "redirect", module = "index", view = "index" }, + error = { mode = "redirect", module = "index", view = "check_delegations" } + }, + content = function() + + ui.tag{ tag = "table", attr = { class = "striped" }, content = function() + + ui.tag{ tag = "tr", content = function() + + ui.tag{ tag = "th", content = _"unit / area" } + ui.tag{ tag = "th", content = _"delegated to" } + ui.tag{ tag = "th", content = _"action" } + + end } + + for i, delegation in ipairs(delegations) do + + local unit = Unit:by_id(delegation.unit_id) + local area = Area:by_id(delegation.area_id) + local member = Member:by_id(delegation.trustee_id) + local info + if area then + area:load_delegation_info_once_for_member_id(app.session.member_id) + info = area.delegation_info + else + unit:load_delegation_info_once_for_member_id(app.session.member_id) + info = unit.delegation_info + end + + ui.tag{ tag = "tr", content = function () + + ui.tag { tag = "td", content = function() + ui.tag{ tag = "span", attr = { class = "unit_link" }, content = delegation.unit_name } + ui.tag{ tag = "span", attr = { class = "area_link" }, content = delegation.area_name } + end } + + ui.tag { tag = "td", content = function() + if (member) then + local text = _"delegates to" + ui.image{ + attr = { class = "delegation_arrow", alt = text, title = text }, + static = "delegation_arrow_24_horizontal.png" + } + execute.view{ module = "member_image", view = "_show", params = { + member = member, class = "micro_avatar", popup_text = member.name, + image_type = "avatar", show_dummy = true, + } } + slot.put(" ") + ui.tag { tag = "span", content = delegation.member_name } + else + ui.tag{ tag = "span", content = _"Abandon unit delegation" } + end + end } + + ui.tag { tag = "td", content = function() + local checked = config.check_delegations_default + ui.tag{ tag = "input", attr = { + type = "radio", + id = "delegation_" .. delegation.id .. "_confirm", + name = "delegation_" .. delegation.id, + value = "confirm", + checked = checked == "confirm" and "checked" or nil + } } + ui.tag{ + tag = "label", + attr = { ["for"] = "delegation_" .. delegation.id .. "_confirm" }, + content = _"confirm" + } + ui.tag{ tag = "input", attr = { + type = "radio", + id = "delegation_" .. delegation.id .. "_revoke", + name = "delegation_" .. delegation.id, + value = "revoke", + checked = checked == "revoke" and "checked" or nil + } } + ui.tag{ + tag = "label", + attr = { ["for"] = "delegation_" .. delegation.id .. "_revoke" }, + content = _"revoke" + } + end} + + end } + + end + + end} + + + slot.put("
") + + ui.submit{ text = "Finish delegation check" } + + end +} diff -r 0d75cd1cdcd5 -r 81bde33c2256 config/example.lua --- a/config/example.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/config/example.lua Sat Apr 20 18:40:34 2013 +0200 @@ -89,6 +89,17 @@ -- ------------------------------------------------------------------------ -- config.delegation_warning_time = '6 months' +-- after which time a user is advised (_soft) or forced (_hard) to check +-- unit and area delegations. default: no check at all +-- ------------------------------------------------------------------------ +-- config.check_delegations_interval_hard = "6 months" +-- config.check_delegations_interval_soft = "3 months" + +-- default option when checking delegations +-- available options: "confirm", "revoke" and "none", default: "confirm" +-- ------------------------------------------------------------------------ +-- config.check_delegations_default = "confirm" + -- Prefix of all automatic mails, defaults to "[Liquid Feedback] " -- ------------------------------------------------------------------------ -- config.mail_subject_prefix = "[LiquidFeedback] " diff -r 0d75cd1cdcd5 -r 81bde33c2256 config/init.lua --- a/config/init.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/config/init.lua Sat Apr 20 18:40:34 2013 +0200 @@ -44,6 +44,10 @@ config.locked_profile_fields = {} end +if config.check_delegations_default == nil then + config.check_delegations_default = "confirm" +end + if not config.database then config.database = { engine='postgresql', dbname='liquid_feedback' } end diff -r 0d75cd1cdcd5 -r 81bde33c2256 model/delegation.lua --- a/model/delegation.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/model/delegation.lua Sat Apr 20 18:40:34 2013 +0200 @@ -70,4 +70,25 @@ :add_where{"delegation.truster_id = ?", member_id} :add_where{"member.active = 'f' OR (member.last_activity IS NULL OR age(member.last_activity) > ?::interval)", config.delegation_warning_time } end - \ No newline at end of file + +function Delegation:delegations_to_check_for_member_id(member_id, for_update) + + Member:new_selector():add_where({ "id = ?", member_id }):for_update():exec() + + local selector = Delegation:new_selector() + :add_field("member.name", "member_name") + :add_field("unit.name", "unit_name") + :add_field("area.name", "area_name") + :left_join("area", nil, "area.active AND area.id = delegation.area_id") + :join("unit", nil, "unit.active AND (unit.id = delegation.unit_id OR unit.id = area.unit_id)") + :left_join("member", nil, "member.id = delegation.trustee_id") + :add_where({ "delegation.truster_id = ?", member_id }) + :add_order_by("unit.name, area.name NULLS FIRST") + + if for_update then + selector:for_update_of("delegation") + end + + return selector:exec() + +end \ No newline at end of file diff -r 0d75cd1cdcd5 -r 81bde33c2256 model/member.lua --- a/model/member.lua Wed Mar 20 09:26:11 2013 +0100 +++ b/model/member.lua Sat Apr 20 18:40:34 2013 +0200 @@ -373,6 +373,7 @@ function Member:by_login_and_password(login, password) local selector = self:new_selector() + selector:add_field({ "now() > COALESCE(last_delegation_check, activated) + ?::interval", config.check_delegations_interval_hard }, "needs_delegation_check_hard") selector:add_where{'"login" = ?', login } selector:add_where('NOT "locked"') selector:optional_object_mode() diff -r 0d75cd1cdcd5 -r 81bde33c2256 static/style.css --- a/static/style.css Wed Mar 20 09:26:11 2013 +0100 +++ b/static/style.css Sat Apr 20 18:40:34 2013 +0200 @@ -64,6 +64,16 @@ margin: 0; } +table.striped tr:nth-child(even) td { + background-color: #ddd; +} +table.striped td, table.striped label { + vertical-align: middle; +} +table.striped label { + vertical-align: top; +} + .page, .topbar_content { max-width: 1130px; @@ -125,6 +135,10 @@ display: inline; } +input[type=submit] { + border-radius: 4px; +} + /************************************************************************* * Notices, warnings and errors */ @@ -483,6 +497,11 @@ margin-right: 8px; } +table .unit_link, +table .area_link { + margin-top: 1px; +} + .unit_link { background-color: #44a; color: #fff; @@ -660,8 +679,15 @@ .ui_paginate_select a { padding: 0.5em; border-radius: 4px; + line-height: 250%; + background: #eee; } +.ui_paginate_select a.active { + background: #444; +} + + /************************************************************************* * ui.bargraph */