# HG changeset patch # User bsw # Date 1337360827 -7200 # Node ID 63d6549cc00b231a14a896766b5714c4583029b2 # Parent 9d463368e0d057b627c9f2c1223ed037aaa514cc Delegation chain preview improved, better visualisation of current context, code cleanup diff -r 9d463368e0d0 -r 63d6549cc00b app/main/_filter_view/30_navigation.lua --- a/app/main/_filter_view/30_navigation.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/_filter_view/30_navigation.lua Fri May 18 19:07:07 2012 +0200 @@ -3,35 +3,21 @@ slot.select('navigation', function() ui.link{ - attr = { class = "logolf" }, - content = _"Home", + content = function() + ui.tag{ attr = { class = "logolf" }, content = _"LiquidFeedback" } + slot.put(" · ") + ui.tag{ content = config.instance_name } + end, module = 'index', view = 'index' } - - if app.session.member_id then - ui.link{ - content = _"Units", - module = 'unit', - view = 'list' - } - ui.link{ - content = _"Members", - module = 'member', - view = 'list' - } - ui.link{ - content = _"Contacts", - module = 'contact', - view = 'list' - } - end + ui.link{ + content = _"Search", + module = 'index', + view = 'search' + } - ui.link{ - content = _"Search", - module = 'index', - view = 'search' - } + if config.public_access and app.session.member == nil then ui.link{ @@ -59,46 +45,36 @@ } else - ui.container{ attr = { class = "member_info" }, content = function() - ui.link{ - content = function() - execute.view{ - module = "member_image", - view = "_show", - params = { - member = app.session.member, - image_type = "avatar", - show_dummy = true, - class = "micro_avatar", - } - } - ui.tag{ content = app.session.member.name } - end, - module = "member", - view = "show", - id = app.session.member_id - } - - ui.link{ - text = _"Settings", - module = "member", - view = "settings" - } + ui.container{ attr = { class = "navigation_right" }, content = function() if app.session.member_id then - ui.link{ - -- image = { static = "icons/16/stop.png" }, - text = _"Logout", - module = 'index', - action = 'logout', - routing = { - default = { - mode = "redirect", - module = "index", - view = "index" + ui.container{ attr = { class = "member_menu" }, content = function() + ui.container{ attr = { class = "title" }, content = function() + ui.link{ + content = function() + execute.view{ + module = "member_image", + view = "_show", + params = { + member = app.session.member, + image_type = "avatar", + show_dummy = true, + class = "micro_avatar", + } + } + ui.tag{ content = app.session.member.name } + end, + module = "member", + view = "menu" } + end } + ui.container{ + attr = { id = "member_menu" }, + content = function() + execute.view{ module = "member", view = "_menu" } + end } - } + end } end end } diff -r 9d463368e0d0 -r 63d6549cc00b app/main/_layout/default.html --- a/app/main/_layout/default.html Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/_layout/default.html Fri May 18 19:07:07 2012 +0200 @@ -42,28 +42,28 @@ +
-
- -
-
- -
-
-
- -
- -
-
-
- -
diff -r 9d463368e0d0 -r 63d6549cc00b app/main/admin/unit_edit.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/admin/unit_edit.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,54 @@ +local id = param.get_id() + +local unit = Unit:by_id(id) + +if member then + slot.put_into("title", encode.html(_("Unit: '#{name}'", { name = unit.name }))) +else + slot.put_into("title", encode.html(_"Add new unit")) +end + +local units_selector = Unit:new_selector() + +if member then + units_selector + :left_join("privilege", nil, { "privilege.member_id = ? AND privilege.unit_id = unit.id", member.id }) + :add_field("privilege.voting_right", "voting_right") +end + +local units = units_selector:exec() + +ui.form{ + attr = { class = "vertical" }, + module = "admin", + action = "member_update", + id = member and member.id, + record = member, + readonly = not app.session.member.admin, + routing = { + default = { + mode = "redirect", + modules = "admin", + view = "member_list" + } + }, + content = function() + ui.field.text{ label = _"Identification", name = "identification" } + ui.field.text{ label = _"Notification email", name = "notify_email" } + ui.field.boolean{ label = _"Admin?", name = "admin" } + + slot.put("
") + + for i, unit in ipairs(units) do + ui.field.boolean{ + name = "unit_" .. unit.id, + label = unit.name, + value = unit.voting_right + } + end + slot.put("

") + + ui.field.boolean{ label = _"Send invite?", name = "invite_member" } + ui.submit{ text = _"Save" } + end +} diff -r 9d463368e0d0 -r 63d6549cc00b app/main/area/_head.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/area/_head.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,85 @@ +local area = param.get("area", "table") + +execute.view{ module = "unit", view = "_head", params = { unit = area.unit } } + +slot.select("head", function() + + ui.container{ attr = { class = "area_head" }, content = function() + + execute.view{ module = "delegation", view = "_info", params = { area = area } } + + ui.container{ attr = { class = "title" }, content = function() + -- area name + ui.link{ + module = "area", view = "show", id = area.id, + attr = { class = "area_name" }, content = area.name + } + end } + + ui.container{ attr = { class = "content" }, content = function() + + -- actions (members with appropriate voting right only) + if app.session.member_id then + + -- membership + local membership = Membership:by_pk(area.id, app.session.member.id) + + if membership then + + ui.tag{ content = _"You are member" } + + slot.put(" ") + + ui.tag{ content = function() + slot.put("(") + ui.link{ + text = _"Withdraw", + module = "membership", + action = "update", + params = { area_id = area.id, delete = true }, + routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } + } + slot.put(")") + end } + + slot.put(" · ") + + elseif app.session.member:has_voting_right_for_unit_id(area.unit_id) then + ui.link{ + text = _"Become a member", + module = "membership", + action = "update", + params = { area_id = area.id }, + routing = { + default = { + mode = "redirect", + module = "area", + view = "show", + id = area.id + } + } + } + + slot.put(" · ") + + end + + -- create new issue + if app.session.member:has_voting_right_for_unit_id(area.unit_id) then + ui.link{ + content = function() + slot.put(_"Create new issue") + end, + module = "initiative", + view = "new", + params = { area_id = area.id } + } + end + + end + + end } + + end } + +end) \ No newline at end of file diff -r 9d463368e0d0 -r 63d6549cc00b app/main/area/show.lua --- a/app/main/area/show.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/area/show.lua Fri May 18 19:07:07 2012 +0200 @@ -13,24 +13,7 @@ end -slot.select("title", function() - ui.link{ - content = area.name, - module = "area", view = "show", id = area.id - } - - if not config.single_unit_id then - slot.put(" · ") - ui.link{ - content = area.unit.name, - module = "unit", - view = "show", - id = area.unit_id - } - end - - -end) +execute.view{ module = "area", view = "_head", params = { area = area } } ui.container{ attr = { class = "vertical"}, @@ -40,35 +23,7 @@ } -if app.session.member_id then - execute.view{ - module = "membership", - view = "_show_box", - params = { area = area } - } - execute.view{ - module = "delegation", - view = "_show_box", - params = { area_id = area.id } - } - - if app.session.member:has_voting_right_for_unit_id(area.unit_id) then - slot.select("actions", function() - ui.link{ - content = function() - ui.image{ static = "icons/16/folder_add.png" } - slot.put(_"Create new issue") - end, - module = "initiative", - view = "new", - params = { area_id = area.id } - } - end) - end - - -end if app.session.member then execute.view{ diff -r 9d463368e0d0 -r 63d6549cc00b app/main/area/show_tab.lua --- a/app/main/area/show_tab.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/area/show_tab.lua Fri May 18 19:07:07 2012 +0200 @@ -50,7 +50,7 @@ tabs[#tabs+1] = { name = "members", - label = _"Members" .. " (" .. tostring(members_selector:count()) .. ")", + label = _"Participants" .. " (" .. tostring(members_selector:count()) .. ")", icon = { static = "icons/16/group.png" }, module = "member", view = "_list", diff -r 9d463368e0d0 -r 63d6549cc00b app/main/delegation/_info.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/delegation/_info.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,188 @@ +local unit = param.get("unit", "table") +local area = param.get("area", "table") +local issue = param.get("issue", "table") + +local unit_id = unit and unit.id or nil +local area_id = area and area.id or nil +local issue_id = issue and issue.id or nil + +local info +local delegation_text + +if unit then + unit:load_delegation_info_once_for_member_id(app.session.member_id) + info = unit.delegation_info + delegation_text = _"Delegate unit" +end + +if area then + area:load_delegation_info_once_for_member_id(app.session.member_id) + info = area.delegation_info + delegation_text = _"Delegate area" +end + +if issue then + issue:load_delegation_info_once_for_member_id(app.session.member_id) + info = issue.delegation_info + delegation_text = _"Delegate issue" +end + +ui.link{ + module = "delegation", view = "show", params = { + unit_id = unit_id, + area_id = area_id, + issue_id = issue_id + }, + attr = { class = "delegation_info" }, content = function() + + + local participant_occured = false + + if info.own_participation or info.first_trustee_id then + + local class = "micro_avatar" + if info.own_participation then + participant_occured = true + class = class .. " highlighted" + end + + execute.view{ module = "member_image", view = "_show", params = { + member = app.session.member, class = class, popup_text = app.session.member.name, + image_type = "avatar", show_dummy = true, + } } + + end + + if not info.first_trustee_id and (not issue or not issue.closed) then + slot.put(" ") + ui.tag{ attr = { class = "link" }, content = delegation_text } + end + + if not (issue and issue.state == "voting" and info.own_participation) then + + if info.first_trustee_id then + + local text = _"delegates to" + ui.image{ + attr = { class = "delegation_arrow", alt = text, title = text }, + static = "delegation_arrow_24_horizontal.png" + } + + local class = "micro_avatar" + if not participant_occured and info.first_trustee_participation then + participant_occured = true + class = class .. " highlighted" + end + + execute.view{ module = "member_image", view = "_show", params = { + member_id = info.first_trustee_id, class = class, popup_text = info.first_trustee_name, + image_type = "avatar", show_dummy = true, + } } + + end + + if info.first_trustee_ellipsis then + + local text = _"delegates to" + ui.image{ + attr = { class = "delegation_arrow", alt = text, title = text }, + static = "delegation_arrow_24_horizontal.png" + } + + slot.put("...") + + end + + if info.other_trustee_id then + + local text = _"delegates to" + ui.image{ + attr = { class = "delegation_arrow", alt = text, title = text }, + static = "delegation_arrow_24_horizontal.png" + } + + local class = "micro_avatar" + if not participant_occured and info.other_trustee_participation then + participant_occured = true + class = class .. " highlighted" + end + + execute.view{ module = "member_image", view = "_show", params = { + member_id = info.other_trustee_id, class = class, popup_text = info.other_trustee_name, + image_type = "avatar", show_dummy = true, + } } + + end + + if info.other_trustee_ellipsis then + + local text = _"delegates to" + ui.image{ + attr = { class = "delegation_arrow", alt = text, title = text }, + static = "delegation_arrow_24_horizontal.png" + } + + slot.put("...") + + end + + local trailing_ellipsis = info.other_trustee_ellipsis or + (info.first_trustee_ellipsis and not info.other_trustee_id) + + if info.delegation_loop == "own" 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 = app.session.member, class = "micro_avatar", popup_text = app.session.member.name, + image_type = "avatar", show_dummy = true, + } } + + elseif info.delegation_loop == "first" then + if info.first_trustee_ellipsis then + if not trailing_ellipsis then + + local text = _"delegates to" + ui.image{ + attr = { class = "delegation_arrow", alt = text, title = text }, + static = "delegation_arrow_24_horizontal.png" + } + + slot.put("...") + end + + else + + 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_id = info.first_trustee_id, class = "micro_avatar", popup_text = info.first_trustee_name, + image_type = "avatar", show_dummy = true, + } } + end + + + elseif info.delegation_loop and not trailing_ellipsis then + local text = _"delegates to" + ui.image{ + attr = { class = "delegation_arrow", alt = text, title = text }, + static = "delegation_arrow_24_horizontal.png" + } + + slot.put("...") + end + + end + + end + +} + diff -r 9d463368e0d0 -r 63d6549cc00b app/main/delegation/_show_box.lua --- a/app/main/delegation/_show_box.lua Tue Apr 17 00:07:04 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,275 +0,0 @@ -function change_delegation(scope, unit_id, area_id, issue, delegation, initiative_id) - local check_unit_id - if unit_id then - check_unit_id = unit_id - elseif area_id then - local area = Area:by_id(area_id) - check_unit_id = area.unit_id - else - local area = Area:by_id(issue.area_id) - check_unit_id = area.unit_id - end - - if not app.session.member:has_voting_right_for_unit_id(check_unit_id) then - return - end - - local image - local text - if scope == "unit" and delegation and delegation.unit_id then - image = { static = "icons/16/table_go.png" } - text = config.single_unit_id and _"Change global delegation" or _"Change unit delegation" - elseif scope == "unit" and not (delegation and delegation.unit_id) then - image = { static = "icons/16/table_go.png" } - text = config.single_unit_id and _"Set global delegation" or _"Set unit delegation" - elseif scope == "area" and delegation and delegation.area_id then - image = { static = "icons/16/table_go.png" } - text = _"Change area delegation" - elseif scope == "area" and not (delegation and delegation.area_id) then - image = { static = "icons/16/table_go.png" } - text = _"Set area delegation" - elseif scope == "issue" then - if delegation and delegation.issue_id then - image = { static = "icons/16/table_go.png" } - text = _"Change issue delegation" - elseif issue.state ~= "finished" and issue.state ~= "cancelled" then - image = { static = "icons/16/table_go.png" } - text = _"Set issue delegation" - end - end - ui.container{ - attr = { - class = "change_delegation", - }, - content = function() - ui.link{ - image = image, - text = text, - module = "delegation", - view = "new", - params = { - issue_id = issue and issue.id or nil, - initiative_id = initiative_id or nil, - area_id = area_id, - unit_id = unit_id - }, - } - if delegation then - ui.link{ - image = { static = "icons/16/delete.png" }, - text = _"Revoke", - module = "delegation", - action = "update", - params = { issue_id = delegation.issue_id, area_id = delegation.area_id, unit_id = delegation.unit_id, delete = true }, - routing = { - default = { - mode = "redirect", - module = request.get_module(), - view = request.get_view(), - id = param.get_id_cgi(), - params = param.get_all_cgi() - } - } - } - end - end - } -end - -local delegation -local unit_id -local area_id -local issue_id -local initiative_id - -local scope = "unit" - -unit_id = param.get("unit_id", atom.integer) - -local inline = param.get("inline", atom.boolean) - -if param.get("initiative_id", atom.integer) then - initiative_id = param.get("initiative_id", atom.integer) - issue_id = Initiative:by_id(initiative_id).issue_id - scope = "issue" -end - -if param.get("issue_id", atom.integer) then - issue_id = param.get("issue_id", atom.integer) - scope = "issue" -end - -if param.get("area_id", atom.integer) then - area_id = param.get("area_id", atom.integer) - scope = "area" -end - - - -local delegation -local issue - -if issue_id then - issue = Issue:by_id(issue_id) - delegation = Delegation:by_pk(app.session.member.id, nil, nil, issue_id) - if not delegation then - delegation = Delegation:by_pk(app.session.member.id, nil, issue.area_id) - end - if not delegation then - delegation = Delegation:by_pk(app.session.member.id, issue.area.unit_id) - end -elseif area_id then - delegation = Delegation:by_pk(app.session.member.id, nil, area_id) - if not delegation then - local area = Area:by_id(area_id) - delegation = Delegation:by_pk(app.session.member.id, area.unit_id) - end -end - -if not delegation then - delegation = Delegation:by_pk(app.session.member.id, unit_id) -end - -local slot_name = "actions" - -if inline then - slot_name = "default" -end - -slot.select(slot_name, function() - - if delegation then - ui.container{ - attr = { class = "delegation vote_info"}, - content = function() - ui.container{ - attr = { - title = _"Click for details", - class = "head head_active", - style = "cursor: pointer;", - onclick = "document.getElementById('delegation_content').style.display = 'block';" - }, - content = function() - if delegation.trustee_id then - ui.image{ - static = "icons/16/table_go.png" - } - local member = Member:new_selector() - :reset_fields() - :add_field("name", "delegation_name") - :add_where({ "id = ?", delegation.trustee_id }) - :single_object_mode() - :exec() - if delegation.issue_id then - slot.put( _("Issue delegated to '#{name}'", { name = member.delegation_name }) ) - elseif delegation.area_id then - slot.put( _("Area delegated to '#{name}'", { name = member.delegation_name }) ) - else - if config.single_unit_id then - slot.put( _("Global delegation set to '#{name}'", { name = member.delegation_name }) ) - else - slot.put( _("Unit delegated to '#{name}'", { name = member.delegation_name }) ) - end - end - - else - ui.image{ - static = "icons/16/table_go_crossed.png" - } - if delegation.issue_id then - slot.put(_"Delegation turned off for issue") - elseif delegation.area_id then - slot.put(_"Delegation turned off for area") - end - end - ui.image{ - static = "icons/16/dropdown.png" - } - end - } - ui.container{ - attr = { class = "content", id = "delegation_content" }, - content = function() - ui.container{ - attr = { - class = "close", - style = "cursor: pointer;", - onclick = "document.getElementById('delegation_content').style.display = 'none';" - }, - content = function() - ui.image{ static = "icons/16/cross.png" } - end - } - - local delegation_chain = Member:new_selector() - :add_field("delegation_chain.*") - :join("delegation_chain(" .. tostring(app.session.member.id) .. ", " .. tostring(unit_id or "NULL") .. ", " .. tostring(area_id or "NULL") .. ", " .. tostring(issue_id or "NULL") .. ")", "delegation_chain", "member.id = delegation_chain.member_id") - :add_order_by("index") - :exec() - - if not issue or (issue.state ~= "finished" and issue.state ~= "cancelled") then - change_delegation(scope, unit_id, area_id, issue, delegation, initiative_id) - slot.put("
") - end - - for i, record in ipairs(delegation_chain) do - local style - local overridden = (not issue or issue.state ~= 'voting') and record.overridden - if record.scope_in then - ui.container{ - attr = { class = "delegation_info" }, - content = function() - if not overridden then - ui.image{ - attr = { class = "delegation_arrow" }, - static = "delegation_arrow_24_vertical.png" - } - else - ui.image{ - attr = { class = "delegation_arrow delegation_arrow_overridden" }, - static = "delegation_arrow_24_vertical.png" - } - end - ui.container{ - attr = { class = "delegation_scope" .. (overridden and " delegation_scope_overridden" or "") }, - content = function() - if record.scope_in == "unit" then - slot.put(config.single_object_mode and _"Global delegation" or _"Unit delegation") - elseif record.scope_in == "area" then - slot.put(_"Area delegation") - elseif record.scope_in == "issue" then - slot.put(_"Issue delegation") - end - end - } - end - } - end - ui.container{ - attr = { class = overridden and "delegation_overridden" or "" }, - content = function() - execute.view{ - module = "member", - view = "_show_thumb", - params = { member = record } - } - end - } - if (not issue or issue.state ~= 'voting') and record.participation and not record.overridden then - ui.container{ - attr = { class = "delegation_participation" }, - content = function() - slot.put(_"This member is participating, the rest of delegation chain is suspended while discussing") - end - } - end - slot.put("
") - end - end - } - end - } - else - change_delegation(scope, unit_id, area_id, issue, nil, initiative_id) - end -end) diff -r 9d463368e0d0 -r 63d6549cc00b app/main/delegation/new.lua --- a/app/main/delegation/new.lua Tue Apr 17 00:07:04 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -local voting_right_unit_id - -local unit = Unit:by_id(param.get("unit_id", atom.integer)) -if unit then - voting_right_unit_id = unit.id - slot.put_into("title", encode.html(config.single_unit_id and _"Set global delegation" or _"Set unit delegation")) - util.help("delegation.new.unit") -end - -local area = Area:by_id(param.get("area_id", atom.integer)) -if area then - voting_right_unit_id = area.unit_id - slot.put_into("title", encode.html(_"Set delegation for Area '#{name}'":gsub("#{name}", area.name))) - util.help("delegation.new.area") -end - -local issue = Issue:by_id(param.get("issue_id", atom.integer)) -if issue then - voting_right_unit_id = issue.area.unit_id - slot.put_into("title", encode.html(_"Set delegation for Issue ##{number} in Area '#{area_name}'":gsub("#{number}", issue.id):gsub("#{area_name}", issue.area.name))) - util.help("delegation.new.issue") -end - -local initiative = Initiative:by_id(param.get("initiative_id", atom.integer)) - -slot.select("actions", function() - if issue then - ui.link{ - module = "issue", - view = "show", - id = issue.id, - content = function() - ui.image{ static = "icons/16/cancel.png" } - slot.put(_"Cancel") - end, - } - elseif area then - ui.link{ - module = "area", - view = "show", - id = area.id, - content = function() - ui.image{ static = "icons/16/cancel.png" } - slot.put(_"Cancel") - end, - } - else - ui.link{ - module = "index", - view = "index", - content = function() - ui.image{ static = "icons/16/cancel.png" } - slot.put(_"Cancel") - end, - } - end -end) - - -local contact_members = Member:build_selector{ - is_contact_of_member_id = app.session.member_id, - voting_right_for_unit_id = voting_right_unit_id, - order = "name" -}:exec() - -ui.form{ - attr = { class = "vertical" }, - module = "delegation", - action = "update", - params = { - unit_id = unit and unit.id or nil, - area_id = area and area.id or nil, - issue_id = issue and issue.id or nil, - }, - routing = { - default = { - mode = "redirect", - module = area and "area" or initiative and "initiative" or issue and "issue" or "unit", - view = "show", - id = area and area.id or initiative and initiative.id or issue and issue.id or unit.id - } - }, - content = function() - local records - - if issue then - local delegate_name = "" - local scope = "no delegation set" - local area_delegation = Delegation:by_pk(app.session.member_id, nil, issue.area_id) - if area_delegation then - delegate_name = area_delegation.trustee and area_delegation.trustee.name or _"abandoned" - scope = _"area" - else - local unit_delegation = Delegation:by_pk(app.session.member_id, issue.area.unit_id) - if unit_delegation then - delegate_name = unit_delegation.trustee.name - scope = config.single_unit_id and _"global" or _"unit" - end - end - local text_apply - local text_abandon - if config.single_unit_id then - text_apply = _("Apply global or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) - text_abandon = _"Abandon unit and area delegations for this issue" - else - text_apply = _("Apply unit or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) - text_abandon = _"Abandon unit and area delegations for this issue" - end - records = { - { id = -1, name = text_apply }, - { id = 0, name = text_abandon } - } - elseif area then - local delegate_name = "" - local scope = "no delegation set" - local unit_delegation = Delegation:by_pk(app.session.member_id, area.unit_id) - if unit_delegation then - delegate_name = unit_delegation.trustee.name - scope = config.single_unit_id and _"global" or _"unit" - end - local text_apply - local text_abandon - if config.single_unit_id then - text_apply = _("Apply global delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) - text_abandon = _"Abandon global delegation for this area" - else - text_apply = _("Apply unit delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) - text_abandon = _"Abandon unit delegation for this area" - end - records = { - { - id = -1, - name = text_apply - }, - { - id = 0, - name = text_abandon - } - } - - else - records = { - { - id = -1, - name = _"No delegation" - } - } - - end - -- add saved members - records[#records+1] = {id="_", name= "--- " .. _"Saved contacts" .. " ---"} - for i, record in ipairs(contact_members) do - records[#records+1] = record - end - -- add initiative authors - if initiative then - records[#records+1] = {id="_", name= "--- " .. _"Initiators" .. " ---"} - for i,record in ipairs(initiative.initiators) do - records[#records+1] = record.member - end - end - - disabled_records = {} - disabled_records["_"] = true - disabled_records[app.session.member_id] = true - - ui.field.select{ - label = _"Trustee", - name = "trustee_id", - foreign_records = records, - foreign_id = "id", - foreign_name = "name", - disabled_records = disabled_records - } - - ui.submit{ text = _"Save" } - end -} diff -r 9d463368e0d0 -r 63d6549cc00b app/main/delegation/show.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/delegation/show.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,314 @@ +local voting_right_unit_id + +local unit = Unit:by_id(param.get("unit_id", atom.integer)) +if unit then + voting_right_unit_id = unit.id + slot.put_into("title", encode.html(config.single_unit_id and _"Set global delegation" or _"Set unit delegation")) + util.help("delegation.new.unit") +end + +local area = Area:by_id(param.get("area_id", atom.integer)) +if area then + voting_right_unit_id = area.unit_id + slot.put_into("title", encode.html(_"Set delegation for Area '#{name}'":gsub("#{name}", area.name))) + util.help("delegation.new.area") +end + +local issue = Issue:by_id(param.get("issue_id", atom.integer)) +if issue then + voting_right_unit_id = issue.area.unit_id + slot.put_into("title", encode.html(_"Set delegation for Issue ##{number} in Area '#{area_name}'":gsub("#{number}", issue.id):gsub("#{area_name}", issue.area.name))) + util.help("delegation.new.issue") +end + +local initiative = Initiative:by_id(param.get("initiative_id", atom.integer)) + +slot.select("actions", function() + if issue then + ui.link{ + module = "issue", + view = "show", + id = issue.id, + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + } + elseif area then + ui.link{ + module = "area", + view = "show", + id = area.id, + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + } + else + ui.link{ + module = "index", + view = "index", + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + } + end +end) + + +local contact_members = Member:build_selector{ + is_contact_of_member_id = app.session.member_id, + voting_right_for_unit_id = voting_right_unit_id, + order = "name" +}:exec() + +ui.form{ + attr = { class = "vertical" }, + module = "delegation", + action = "update", + params = { + unit_id = unit and unit.id or nil, + area_id = area and area.id or nil, + issue_id = issue and issue.id or nil, + }, + routing = { + default = { + mode = "redirect", + module = area and "area" or initiative and "initiative" or issue and "issue" or "unit", + view = "show", + id = area and area.id or initiative and initiative.id or issue and issue.id or unit.id + } + }, + content = function() + local records + + if issue then + local delegate_name = "" + local scope = "no delegation set" + local area_delegation = Delegation:by_pk(app.session.member_id, nil, issue.area_id) + if area_delegation then + delegate_name = area_delegation.trustee and area_delegation.trustee.name or _"abandoned" + scope = _"area" + else + local unit_delegation = Delegation:by_pk(app.session.member_id, issue.area.unit_id) + if unit_delegation then + delegate_name = unit_delegation.trustee.name + scope = config.single_unit_id and _"global" or _"unit" + end + end + local text_apply + local text_abandon + if config.single_unit_id then + text_apply = _("Apply global or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) + text_abandon = _"Abandon unit and area delegations for this issue" + else + text_apply = _("Apply unit or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) + text_abandon = _"Abandon unit and area delegations for this issue" + end + records = { + { id = -1, name = text_apply }, + { id = 0, name = text_abandon } + } + elseif area then + local delegate_name = "" + local scope = "no delegation set" + local unit_delegation = Delegation:by_pk(app.session.member_id, area.unit_id) + if unit_delegation then + delegate_name = unit_delegation.trustee.name + scope = config.single_unit_id and _"global" or _"unit" + end + local text_apply + local text_abandon + if config.single_unit_id then + text_apply = _("Apply global delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) + text_abandon = _"Abandon global delegation for this area" + else + text_apply = _("Apply unit delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) + text_abandon = _"Abandon unit delegation for this area" + end + records = { + { + id = -1, + name = text_apply + }, + { + id = 0, + name = text_abandon + } + } + + else + records = { + { + id = -1, + name = _"No delegation" + } + } + + end + -- add saved members + records[#records+1] = {id="_", name= "--- " .. _"Saved contacts" .. " ---"} + for i, record in ipairs(contact_members) do + records[#records+1] = record + end + -- add initiative authors + if initiative then + records[#records+1] = {id="_", name= "--- " .. _"Initiators" .. " ---"} + for i,record in ipairs(initiative.initiators) do + records[#records+1] = record.member + end + end + + disabled_records = {} + disabled_records["_"] = true + disabled_records[app.session.member_id] = true + + ui.field.select{ + label = _"Trustee", + name = "trustee_id", + foreign_records = records, + foreign_id = "id", + foreign_name = "name", + disabled_records = disabled_records + } + + ui.submit{ text = _"Save" } + end +} + + + +-- ------------------------ + + + + +local delegation +local unit_id +local area_id +local issue_id +local initiative_id + +local scope = "unit" + +unit_id = param.get("unit_id", atom.integer) + +local inline = param.get("inline", atom.boolean) + +if param.get("initiative_id", atom.integer) then + initiative_id = param.get("initiative_id", atom.integer) + issue_id = Initiative:by_id(initiative_id).issue_id + scope = "issue" +end + +if param.get("issue_id", atom.integer) then + issue_id = param.get("issue_id", atom.integer) + scope = "issue" +end + +if param.get("area_id", atom.integer) then + area_id = param.get("area_id", atom.integer) + scope = "area" +end + + + +local delegation +local issue + +if issue_id then + issue = Issue:by_id(issue_id) + delegation = Delegation:by_pk(app.session.member.id, nil, nil, issue_id) + if not delegation then + delegation = Delegation:by_pk(app.session.member.id, nil, issue.area_id) + end + if not delegation then + delegation = Delegation:by_pk(app.session.member.id, issue.area.unit_id) + end +elseif area_id then + delegation = Delegation:by_pk(app.session.member.id, nil, area_id) + if not delegation then + local area = Area:by_id(area_id) + delegation = Delegation:by_pk(app.session.member.id, area.unit_id) + end +end + +if not delegation then + delegation = Delegation:by_pk(app.session.member.id, unit_id) +end + +local slot_name = "actions" + +if inline then + slot_name = "default" +end + +if delegation then + + if not delegation.trustee_id then + ui.image{ + static = "icons/16/table_go_crossed.png" + } + if delegation.issue_id then + slot.put(_"Delegation turned off for issue") + elseif delegation.area_id then + slot.put(_"Delegation turned off for area") + end + end + + local delegation_chain = Member:new_selector() + :add_field("delegation_chain.*") + :join("delegation_chain(" .. tostring(app.session.member.id) .. ", " .. tostring(unit_id or "NULL") .. ", " .. tostring(area_id or "NULL") .. ", " .. tostring(issue_id or "NULL") .. ")", "delegation_chain", "member.id = delegation_chain.member_id") + :add_order_by("index") + :exec() + + for i, record in ipairs(delegation_chain) do + local style + local overridden = (not issue or issue.state ~= 'voting') and record.overridden + if record.scope_in then + if not overridden then + ui.image{ + attr = { class = "delegation_arrow" }, + static = "delegation_arrow_24_vertical.png" + } + else + ui.image{ + attr = { class = "delegation_arrow delegation_arrow_overridden" }, + static = "delegation_arrow_24_vertical.png" + } + end + ui.tag{ + attr = { class = "delegation_scope" .. (overridden and " delegation_scope_overridden" or "") }, + content = function() + if record.scope_in == "unit" then + slot.put(config.single_object_mode and _"Global delegation" or _"Unit delegation") + elseif record.scope_in == "area" then + slot.put(_"Area delegation") + elseif record.scope_in == "issue" then + slot.put(_"Issue delegation") + end + end + } + end + ui.container{ + attr = { class = overridden and "delegation_overridden" or "" }, + content = function() + execute.view{ + module = "member", + view = "_show_thumb", + params = { member = record } + } + end + } + if (not issue or issue.state ~= 'voting') and record.participation and not record.overridden then + ui.container{ + attr = { class = "delegation_participation" }, + content = function() + slot.put(_"This member is participating, the rest of delegation chain is suspended while discussing") + end + } + end + slot.put("
") + end +end \ No newline at end of file diff -r 9d463368e0d0 -r 63d6549cc00b app/main/event/_list.lua --- a/app/main/event/_list.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/event/_list.lua Fri May 18 19:07:07 2012 +0200 @@ -65,6 +65,59 @@ elseif event.is_interested_by_delegation_to_member_id then class = class .. " interested_by_delegation" end + + ui.container{ attr = { class = "issue_policy_info" }, content = function() + if (app.session.member_id or config.public_access == "pseudonym") and event.member_id then + if app.session.member_id then + ui.link{ + content = function() + execute.view{ + module = "member_image", + view = "_show", + params = { + member = event.member, + image_type = "avatar", + show_dummy = true, + class = "micro_avatar", + popup_text = text + } + } + end, + module = "member", view = "show", id = event.member_id + } + slot.put(" ") + end + ui.link{ + text = event.member.name, + module = "member", view = "show", id = event.member_id + } + slot.put(" · ") + end + local event_name = event.event_name + local event_image + if event.event == "issue_state_changed" then + if event.state == "discussion" then + event_name = _"Discussion started" + event_image = "comments.png" + elseif event.state == "verification" then + event_name = _"Verification started" + event_image = "lock.png" + elseif event.state == "voting" then + event_name = _"Voting started" + event_image = "email_open.png" + else + event_name = event.state_name + end + if event_image then + ui.image{ static = "icons/16/" .. event_image } + slot.put(" ") + end + end + ui.tag{ attr = { class = "event_name" }, content = event_name } + slot.put(" · ") + ui.tag{ attr = { class = "time" }, content = format.time(event.occurrence) } + end } + ui.container{ attr = { class = class }, content = function() ui.container { attr = { class = "issue_info" }, content = function() @@ -147,57 +200,6 @@ ui.tag{ content = event.issue.area.unit.name } end } - ui.container{ attr = { class = "issue_policy_info" }, content = function() - if (app.session.member_id or config.public_access == "pseudonym") and event.member_id then - if app.session.member_id then - ui.link{ - content = function() - execute.view{ - module = "member_image", - view = "_show", - params = { - member = event.member, - image_type = "avatar", - show_dummy = true, - class = "micro_avatar", - popup_text = text - } - } - end, - module = "member", view = "show", id = event.member_id - } - slot.put(" ") - end - ui.link{ - text = event.member.name, - module = "member", view = "show", id = event.member_id - } - slot.put(" · ") - end - local event_name = event.event_name - local event_image - if event.event == "issue_state_changed" then - if event.state == "discussion" then - event_name = _"Discussion started" - event_image = "comments.png" - elseif event.state == "verification" then - event_name = _"Verification started" - event_image = "lock.png" - elseif event.state == "voting" then - event_name = _"Voting started" - event_image = "email_open.png" - else - event_name = event.state_name - end - if event_image then - ui.image{ static = "icons/16/" .. event_image } - slot.put(" ") - end - end - ui.tag{ attr = { class = "event_name" }, content = event_name } - slot.put(" · ") - ui.tag{ attr = { class = "time" }, content = format.time(event.occurrence) } - end } end } diff -r 9d463368e0d0 -r 63d6549cc00b app/main/index/_lang_chooser.lua --- a/app/main/index/_lang_chooser.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/index/_lang_chooser.lua Fri May 18 19:07:07 2012 +0200 @@ -1,31 +0,0 @@ -slot.select("title", function() - ui.container{ - attr = { class = "lang_chooser" }, - content = function() - for i, lang in ipairs{"en", "de", "eo"} do - ui.link{ - content = function() - ui.image{ - static = "lang/" .. lang .. ".png", - attr = { style = "margin-left: 0.5em;", alt = lang, title = lang } - } - end, - text = _('Select language "#{langcode}"', { langcode = lang }), - module = "index", - action = "set_lang", - params = { lang = lang }, - routing = { - default = { - mode = "redirect", - module = request.get_module(), - view = request.get_view(), - id = param.get_id_cgi(), - params = param.get_all_cgi() - } - } - } - end - end - } -end) - diff -r 9d463368e0d0 -r 63d6549cc00b app/main/index/index.lua --- a/app/main/index/index.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/index/index.lua Fri May 18 19:07:07 2012 +0200 @@ -1,7 +1,3 @@ -execute.view{ module = "index", view = "_lang_chooser" } - -slot.put_into("title", encode.html(config.app_title)) - if app.session.member_id then util.help("index.index", _"Home") @@ -74,7 +70,6 @@ issues_selector = closed_issues_selector } } - ui.tabs(tabs) else diff -r 9d463368e0d0 -r 63d6549cc00b app/main/initiative/_show.lua --- a/app/main/initiative/_show.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/initiative/_show.lua Fri May 18 19:07:07 2012 +0200 @@ -14,121 +14,125 @@ local initiatives_selector = initiative.issue:get_reference_selector("initiatives") -slot.select("initiatives_list", function() +slot.select("head", function() execute.view{ - module = "initiative", - view = "_list", + module = "issue", + view = "_show", params = { issue = initiative.issue, - initiatives_selector = initiatives_selector, - no_sort = true, highlight_initiative = initiative, limit = 3 + initiative_limit = 3 } } end) -slot.select("initiative_head", function() +ui.container{ attr = { class = "initiative_head" }, content = function() ui.container{ - attr = { class = "initiative_name" }, + attr = { class = "title" }, content = _("Initiative i#{id}: #{name}", { id = initiative.id, name = initiative.name }) } - if app.session.member_id or config.public_access == "pseudonym" or config.public_access == "full" then - ui.tag{ - attr = { class = "initiator_names" }, - content = function() - for i, initiator in ipairs(initiators) do - slot.put(" ") - if app.session.member_id then + ui.container{ attr = { class = "content" }, content = function() + if app.session.member_id or config.public_access == "pseudonym" or config.public_access == "full" then + ui.tag{ + attr = { class = "initiator_names" }, + content = function() + for i, initiator in ipairs(initiators) do + slot.put(" ") + if app.session.member_id then + ui.link{ + content = function () + execute.view{ + module = "member_image", + view = "_show", + params = { + member = initiator, + image_type = "avatar", + show_dummy = true, + class = "micro_avatar", + popup_text = text + } + } + end, + module = "member", view = "show", id = initiator.id + } + slot.put(" ") + end ui.link{ - content = function () - execute.view{ - module = "member_image", - view = "_show", - params = { - member = initiator, - image_type = "avatar", - show_dummy = true, - class = "micro_avatar", - popup_text = text - } - } - end, + text = initiator.name, module = "member", view = "show", id = initiator.id } - slot.put(" ") - end - ui.link{ - text = initiator.name, - module = "member", view = "show", id = initiator.id - } - if not initiator.accepted then - ui.tag{ attr = { title = _"Not accepted yet" }, content = "?" } + if not initiator.accepted then + ui.tag{ attr = { title = _"Not accepted yet" }, content = "?" } + end end end - end - } - end - - if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then - slot.put(" · ") - ui.link{ - attr = { class = "action" }, - content = function() - slot.put(_"Invite initiator") - end, - module = "initiative", - view = "add_initiator", - params = { initiative_id = initiative.id } - } - if #initiators > 1 then - slot.put(" · ") - ui.link{ - content = function() - slot.put(_"Remove initiator") - end, - module = "initiative", - view = "remove_initiator", - params = { initiative_id = initiative.id } } end - end - if initiator and initiator.accepted == false then + + if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then slot.put(" · ") ui.link{ - text = _"Cancel refuse of invitation", + attr = { class = "action" }, + content = function() + slot.put(_"Invite initiator") + end, module = "initiative", - action = "remove_initiator", - params = { - initiative_id = initiative.id, - member_id = app.session.member.id - }, - routing = { - ok = { - mode = "redirect", - module = "initiative", - view = "show", - id = initiative.id + view = "add_initiator", + params = { initiative_id = initiative.id } + } + if #initiators > 1 then + slot.put(" · ") + ui.link{ + content = function() + slot.put(_"Remove initiator") + end, + module = "initiative", + view = "remove_initiator", + params = { initiative_id = initiative.id } + } + end + end + if initiator and initiator.accepted == false then + slot.put(" · ") + ui.link{ + text = _"Cancel refuse of invitation", + module = "initiative", + action = "remove_initiator", + params = { + initiative_id = initiative.id, + member_id = app.session.member.id + }, + routing = { + ok = { + mode = "redirect", + module = "initiative", + view = "show", + id = initiative.id + } } } + end + end } + ui.container{ attr = { class = "content" }, content = function() + if app.session.member_id then + execute.view{ + module = "supporter", + view = "_show_box", + params = { + initiative = initiative + } } - end - if app.session.member_id then - execute.view{ - module = "supporter", - view = "_show_box", - params = { - initiative = initiative - } - } - end + end -end ) + end } + +end } util.help("initiative.show") -slot.select("initiative_head", function() +--slot.select("initiative_head", function() if initiative.issue.ranks_available and initiative.admitted then local class = initiative.winner and "admitted_info" or "not_admitted_info" @@ -199,7 +203,7 @@ content = _("This issue has been cancelled. It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) }) } end -end) +--end) if initiator and initiator.accepted == nil and not initiative.issue.half_frozen and not initiative.issue.closed then ui.container{ diff -r 9d463368e0d0 -r 63d6549cc00b app/main/initiative/_suggestions.lua --- a/app/main/initiative/_suggestions.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/initiative/_suggestions.lua Fri May 18 19:07:07 2012 +0200 @@ -1,31 +1,5 @@ local initiative = param.get("initiative", "table") -if app.session.member_id - and not initiative.issue.half_frozen - and not initiative.issue.closed - and not initiative.revoked - and app.session.member:has_voting_right_for_unit_id(initiative.issue.area.unit_id) -then - ui.link{ - content = function() - ui.image{ static = "icons/16/comment_add.png" } - slot.put(_"Add new suggestion") - end, - module = "suggestion", - view = "new", - params = { - initiative_id = initiative.id - } - } -end + -execute.view{ - module = "suggestion", - view = "_list", - params = { - initiative = initiative, - suggestions_selector = initiative:get_reference_selector("suggestions"), - tab_id = param.get("tab_id") - } -} diff -r 9d463368e0d0 -r 63d6549cc00b app/main/initiative/show.lua --- a/app/main/initiative/show.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/initiative/show.lua Fri May 18 19:07:07 2012 +0200 @@ -10,7 +10,7 @@ execute.view{ module = "issue", - view = "_show_head", + view = "_head", params = { issue = initiative.issue, initiative = initiative } } diff -r 9d463368e0d0 -r 63d6549cc00b app/main/initiative/show_tab.lua --- a/app/main/initiative/show_tab.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/initiative/show_tab.lua Fri May 18 19:07:07 2012 +0200 @@ -52,10 +52,12 @@ name = "suggestions", label = _"Suggestions" .. " (" .. tostring(suggestion_count) .. ")", icon = { static = "icons/16/comments.png" }, - module = "initiative", - view = "_suggestions", + module = "suggestion", + view = "_list", params = { - initiative = initiative + initiative = initiative, + suggestions_selector = initiative:get_reference_selector("suggestions"), + tab_id = param.get("tab_id") } } diff -r 9d463368e0d0 -r 63d6549cc00b app/main/interest/_show_box.lua --- a/app/main/interest/_show_box.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/interest/_show_box.lua Fri May 18 19:07:07 2012 +0200 @@ -5,46 +5,31 @@ local interest = Interest:by_pk(issue.id, app.session.member.id) local membership = Membership:by_pk(issue.area_id, app.session.member_id) -slot.select("interest", function() - if interest then +if interest then - ui.container{ - content = function() - ui.container{ - attr = { - class = "head head_active", - }, - content = function() - ui.image{ - static = "icons/16/eye.png" - } - slot.put(_"Your are interested") - - end - } + ui.tag{ content = _"Your are interested" } + slot.put(" ") - if issue.state ~= "finished" and issue.state ~= "cancelled" and issue.state ~= "voting" then - ui.link{ - image = { static = "icons/16/cross.png" }, - text = _"Withdraw interest", - module = "interest", - action = "update", - params = { issue_id = issue.id, delete = true }, - routing = { default = { mode = "redirect", module = initiative and "initiative" or "issue", view = "show", id = initiative and initiative.id or issue.id } } - } - end - end + if issue.state ~= "finished" and issue.state ~= "cancelled" and issue.state ~= "voting" then + slot.put("(") + ui.link{ + text = _"Withdraw", + module = "interest", + action = "update", + params = { issue_id = issue.id, delete = true }, + routing = { default = { mode = "redirect", module = initiative and "initiative" or "issue", view = "show", id = initiative and initiative.id or issue.id } } } - elseif app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then - if not issue.closed and not issue.fully_frozen then - ui.link{ - image = { static = "icons/16/user_add.png" }, - text = _"Add my interest", - module = "interest", - action = "update", - params = { issue_id = issue.id }, - routing = { default = { mode = "redirect", module = initiative and "initiative" or "issue", view = "show", id = initiative and initiative.id or issue.id } } - } - end + slot.put(") ") end -end) +elseif app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then + if not issue.closed and not issue.fully_frozen then + ui.link{ + text = _"Add my interest", + module = "interest", + action = "update", + params = { issue_id = issue.id }, + routing = { default = { mode = "redirect", module = initiative and "initiative" or "issue", view = "show", id = initiative and initiative.id or issue.id } } + } + slot.put(" ") + end +end diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/_details.lua --- a/app/main/issue/_details.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/issue/_details.lua Fri May 18 19:07:07 2012 +0200 @@ -14,10 +14,12 @@ label = _"Issue quorum", value = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) } - ui.field.text{ - label = _"Currently required", - value = math.ceil(issue.population * policy.issue_quorum_num / policy.issue_quorum_den) - } + if issue.population then + ui.field.text{ + label = _"Currently required", + value = math.ceil(issue.population * policy.issue_quorum_num / policy.issue_quorum_den) + } + end ui.field.timestamp{ label = _"Accepted at", name = "accepted" } ui.field.text{ label = _"Discussion time", value = issue.discussion_time } ui.field.timestamp{ label = _"Half frozen at", name = "half_frozen" } @@ -26,10 +28,12 @@ label = _"Initiative quorum", value = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) } - ui.field.text{ - label = _"Currently required", - value = math.ceil(issue.population * (issue.policy.initiative_quorum_num / issue.policy.initiative_quorum_den)), - } + if issue.population then + ui.field.text{ + label = _"Currently required", + value = math.ceil(issue.population * (issue.policy.initiative_quorum_num / issue.policy.initiative_quorum_den)), + } + end ui.field.timestamp{ label = _"Fully frozen at", name = "fully_frozen" } ui.field.text{ label = _"Voting time", value = issue.voting_time } ui.field.timestamp{ label = _"Closed", name = "closed" } diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/_filters.lua --- a/app/main/issue/_filters.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/issue/_filters.lua Fri May 18 19:07:07 2012 +0200 @@ -6,6 +6,115 @@ local filters = {} +local filter = { name = "filter" } + +if state ~= "closed" then + filter[#filter+1] = { + name = "any", + label = _"Any phase", + selector_modifier = function(selector) end + } +end + +if not state then + filter[#filter+1] = { + name = "open", + label = _"Open", + selector_modifier = function(selector) + selector:add_where("issue.closed ISNULL") + end + } +end + +if not state or state == "open" then + filter[#filter+1] = { + name = "new", + label = _"New", + selector_modifier = function(selector) + selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") + end + } + filter[#filter+1] = { + name = "accepted", + label = _"Discussion", + selector_modifier = function(selector) + selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") + end + } + filter[#filter+1] = { + name = "half_frozen", + label = _"Frozen", + selector_modifier = function(selector) + selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL") + end + } + filter[#filter+1] = { + name = "frozen", + label = _"Voting", + selector_modifier = function(selector) + selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") + filter_voting = true + end + } +end + +if not state then + filter[#filter+1] = { + name = "finished", + label = _"Finished", + selector_modifier = function(selector) + selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL") + end + } + filter[#filter+1] = { + name = "cancelled", + label = _"Cancelled", + selector_modifier = function(selector) + selector:add_where("issue.closed NOTNULL AND issue.fully_frozen ISNULL") + end + } +end + +if state == "closed" then + filter[#filter+1] = { + name = "any", + label = _"Any state", + selector_modifier = function(selector) end + } + + filter[#filter+1] = { + name = "finished", + label = _"Finished", + selector_modifier = function(selector) + selector:add_where("issue.state IN ('finished_with_winner', 'finished_without_winner')") + end + } + filter[#filter+1] = { + name = "finished_with_winner", + label = _"with winner", + selector_modifier = function(selector) + selector:add_where("issue.state = 'finished_with_winner'") + end + } + filter[#filter+1] = { + name = "finished_without_winner", + label = _"without winner", + selector_modifier = function(selector) + selector:add_where("issue.state = 'finished_without_winner'") + end + } + filter[#filter+1] = { + name = "cancelled", + label = _"Cancelled", + selector_modifier = function(selector) + selector:add_where("issue.state NOT IN ('finished_with_winner', 'finished_without_winner')") + end + } +end + +filters[#filters+1] = filter + + if member then local filter = { name = "filter_interest", @@ -133,114 +242,6 @@ end -local filter = { name = "filter" } - -if state ~= "closed" then - filter[#filter+1] = { - name = "any", - label = _"Any phase", - selector_modifier = function(selector) end - } -end - -if not state then - filter[#filter+1] = { - name = "open", - label = _"Open", - selector_modifier = function(selector) - selector:add_where("issue.closed ISNULL") - end - } -end - -if not state or state == "open" then - filter[#filter+1] = { - name = "new", - label = _"New", - selector_modifier = function(selector) - selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") - end - } - filter[#filter+1] = { - name = "accepted", - label = _"Discussion", - selector_modifier = function(selector) - selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") - end - } - filter[#filter+1] = { - name = "half_frozen", - label = _"Frozen", - selector_modifier = function(selector) - selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL") - end - } - filter[#filter+1] = { - name = "frozen", - label = _"Voting", - selector_modifier = function(selector) - selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") - filter_voting = true - end - } -end - -if not state then - filter[#filter+1] = { - name = "finished", - label = _"Finished", - selector_modifier = function(selector) - selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL") - end - } - filter[#filter+1] = { - name = "cancelled", - label = _"Cancelled", - selector_modifier = function(selector) - selector:add_where("issue.closed NOTNULL AND issue.fully_frozen ISNULL") - end - } -end - -if state == "closed" then - filter[#filter+1] = { - name = "any", - label = _"Any state", - selector_modifier = function(selector) end - } - - filter[#filter+1] = { - name = "finished", - label = _"Finished", - selector_modifier = function(selector) - selector:add_where("issue.state IN ('finished_with_winner', 'finished_without_winner')") - end - } - filter[#filter+1] = { - name = "finished_with_winner", - label = _"with winner", - selector_modifier = function(selector) - selector:add_where("issue.state = 'finished_with_winner'") - end - } - filter[#filter+1] = { - name = "finished_without_winner", - label = _"without winner", - selector_modifier = function(selector) - selector:add_where("issue.state = 'finished_without_winner'") - end - } - filter[#filter+1] = { - name = "cancelled", - label = _"Cancelled", - selector_modifier = function(selector) - selector:add_where("issue.state NOT IN ('finished_with_winner', 'finished_without_winner')") - end - } -end - -filters[#filters+1] = filter - --[[ if not param.get("no_sort", atom.boolean) then diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/_head.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/issue/_head.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,3 @@ +local issue = param.get("issue", "table") + +execute.view{ module = "area", view = "_head", params = { area = issue.area } } diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/_list.lua --- a/app/main/issue/_list.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/issue/_list.lua Fri May 18 19:07:07 2012 +0200 @@ -12,17 +12,6 @@ issues_selector:add_where("issue.closed NOTNULL") end -if app.session.member_id then - issues_selector - :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", member.id } ) - :add_field("(_interest.member_id NOTNULL)", "is_interested") - issues_selector - :left_join("delegating_interest_snapshot", "_delegating_interest", { "_delegating_interest.issue_id = issue.id AND _delegating_interest.member_id = ? AND _delegating_interest.event = issue.latest_snapshot_event", member.id } ) - :add_field("_delegating_interest.delegate_member_ids[1]", "is_interested_by_delegation_to_member_id") - :add_field("_delegating_interest.delegate_member_ids[array_upper(_delegating_interest.delegate_member_ids, 1)]", "is_interested_via_member_id") - :add_field("array_length(_delegating_interest.delegate_member_ids, 1)", "delegation_chain_length") -end - ui.add_partial_param_names{ "filter", "filter_open", @@ -42,159 +31,14 @@ content = function() local highlight_string = param.get("highlight_string", "string") local issues = issues or issues_selector:exec() + issues:load('policy') -- issues:load(initiatives) ui.container{ attr = { class = "issues" }, content = function() for i, issue in ipairs(issues) do - local class = "issue" - if issue.is_interested then - class = class .. " interested" - elseif issue.is_interested_by_delegation_to_member_id then - class = class .. " interested_by_delegation" - end - ui.container{ attr = { class = class }, content = function() - - ui.container{ attr = { class = "issue_info" }, content = function() - - if issue.is_interested then - ui.tag{ - tag = "div", attr = { class = "interest_by_delegation"}, - content = function() - local text = "You are interested in this issue" - ui.image{ attr = { alt = text, title = text }, static = "icons/16/eye.png" } - end - } - - elseif issue.is_interested_by_delegation_to_member_id then - ui.tag{ - tag = "div", attr = { class = "interest_by_delegation"}, - content = function() - local member = Member:by_id(issue.is_interested_by_delegation_to_member_id) - local text = _"delegated 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, - image_type = "avatar", - show_dummy = true, - class = "micro_avatar", - popup_text = member.name - } - } - if issue.is_interested_by_delegation_to_member_id ~= issue.is_interested_via_member_id then - if issue.delegation_chain_length > 2 then - local text = _"delegated to" - ui.image{ - attr = { class = "delegation_arrow", alt = text, title = text }, - static = "delegation_arrow_24_horizontal.png" - } - ui.tag{ content = "..." } - end - local text = _"delegated to" - ui.image{ - attr = { class = "delegation_arrow", alt = text, title = text }, - static = "delegation_arrow_24_horizontal.png" - } - local member = Member:by_id(issue.is_interested_via_member_id) - execute.view{ - module = "member_image", - view = "_show", - params = { - member = member, - image_type = "avatar", - show_dummy = true, - class = "micro_avatar", - popup_text = member.name - } - } - end - end - } - end - - ui.tag{ - tag = "div", - content = function() - ui.link{ - attr = { class = "issue_id" }, - text = _("Issue ##{id}", { id = tostring(issue.id) }), - module = "issue", - view = "show", - id = issue.id - } - - slot.put(" · ") - ui.tag{ content = issue.policy.name } - slot.put(" · ") - ui.tag{ content = issue.area.name } - slot.put(" · ") - ui.tag{ content = issue.area.unit.name } - - end - } - ui.tag{ - attr = { class = "issue_policy_info" }, - tag = "div", - content = function() - - ui.tag{ attr = { class = "event_name" }, content = issue.state_name } - - if issue.state_time_left then - slot.put(" · ") - if issue.state_time_left:sub(1,1) == "-" then - if issue.state == "new" then - ui.tag{ content = _("Discussion starts soon") } - elseif issue.state == "discussion" then - ui.tag{ content = _("Verification starts soon") } - elseif issue.state == "frozen" then - ui.tag{ content = _("Voting starts soon") } - elseif issue.state == "voting" then - ui.tag{ content = _("Counting starts soon") } - end - else - ui.tag{ content = _("#{time_left} left", { time_left = issue.state_time_left:gsub("days", _"days"):gsub("day", _"day") }) } - end - end - - end - } - - - if issue.old_state then - ui.field.text{ value = format.time(issue.sort) } - ui.field.text{ value = Issue:get_state_name_for_state(issue.old_state) .. " > " .. Issue:get_state_name_for_state(issue.new_state) } - else - end - end } - - ui.container{ attr = { class = "initiative_list" }, content = function() - - local initiatives_selector = issue:get_reference_selector("initiatives") - local highlight_string = param.get("highlight_string") - if highlight_string then - initiatives_selector:add_field( {'"highlight"("initiative"."name", ?)', highlight_string }, "name_highlighted") - end - execute.view{ - module = "initiative", - view = "_list", - params = { - issue = issue, - initiatives_selector = initiatives_selector, - highlight_string = highlight_string, - per_page = app.session.member_id and tonumber(app.session.member:get_setting_value("initiatives_preview_limit") or 3) or 3, - no_sort = true, - limit = app.session.member_id and tonumber(app.session.member:get_setting_value("initiatives_preview_limit") or 3) or 3, - for_member = for_member - } - } - end } - end } + execute.view{ module = "issue", view = "_show", params = { issue = issue, for_listing = true } } + end end } end diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/_list_initiatives.lua --- a/app/main/issue/_list_initiatives.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/issue/_list_initiatives.lua Fri May 18 19:07:07 2012 +0200 @@ -1,18 +1,2 @@ local issue = param.get("issue", "table") -ui.container{ - attr = { class = "box issue_initiative_list" }, - content = function() - execute.view{ - module = "initiative", - view = "_list", - params = { - initiatives_selector = issue:get_reference_selector("initiatives"), - issue = issue, - no_sort = true - } - } - end -} - -slot.put("
") diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/_pad.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/issue/_pad.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,8 @@ +local issue = param.get("issue", "table") + +ui.tag{ tag = "iframe", attr = { + width = "800", + height = "500", + src = issue.etherpad_url +} } + diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/_show.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/issue/_show.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,175 @@ +local issue = param.get("issue", "table") +local initiative_limit = param.get("initiative_limit", atom.integer) +local for_listing = param.get("for_listing", atom.boolean) + +local direct_voter +if app.session.member_id then + direct_voter = DirectVoter:by_pk(issue.id, app.session.member.id) +end + +local voteable = app.session.member_id and issue.state == 'voting' and + app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) + +local vote_link_text = direct_voter and _"Change vote" or "Vote now" + + +local class = "issue" +if issue.is_interested then + class = class .. " interested" +elseif issue.is_interested_by_delegation_to_member_id then + class = class .. " interested_by_delegation" +end + +ui.container{ attr = { class = class }, content = function() + + execute.view{ module = "delegation", view = "_info", params = { issue = issue } } + + if for_listing then + ui.container{ attr = { class = "context" }, content = function() + ui.tag{ content = issue.area.unit.name } + slot.put(" · ") + ui.tag{ content = issue.area.name } + end } + end + ui.container{ attr = { class = "title" }, content = function() + + ui.link{ + attr = { class = "issue_id" }, + text = _("#{policy_name} ##{issue_id}", { + policy_name = issue.policy.name, + issue_id = issue.id + }), + module = "issue", + view = "show", + id = issue.id + } + end } + + ui.tag{ + attr = { class = "content issue_policy_info" }, + tag = "div", + content = function() + + ui.tag{ attr = { class = "event_name" }, content = issue.state_name } + + if issue.state_time_left then + slot.put(" · ") + if issue.state_time_left:sub(1,1) == "-" then + if issue.state == "new" then + ui.tag{ content = _("Discussion starts soon") } + elseif issue.state == "discussion" then + ui.tag{ content = _("Verification starts soon") } + elseif issue.state == "frozen" then + ui.tag{ content = _("Voting starts soon") } + elseif issue.state == "voting" then + ui.tag{ content = _("Counting starts soon") } + end + else + ui.tag{ content = _("#{time_left} left", { time_left = issue.state_time_left:gsub("days", _"days"):gsub("day", _"day") }) } + end + end + + end + } + + ui.container{ + attr = { class = "content actions" }, content = function() + + if voteable then + ui.link{ + content = vote_link_text, + module = "vote", + view = "list", + params = { issue_id = issue.id } + } + slot.put(" · ") + end + + if app.session.member_id then + execute.view{ + module = "interest", + view = "_show_box", + params = { issue = issue, initiative = initiative } + } + slot.put(" · ") + end + + if config.issue_discussion_url_func then + local url = config.issue_discussion_url_func(issue) + ui.link{ + attr = { target = "_blank" }, + external = url, + content = _"Discussion on issue" + } + slot.put(" · ") + end + + if config.etherpad and app.session.member then + ui.link{ + attr = { target = "_blank" }, + external = issue.etherpad_url, + content = _"Issue pad" + } + slot.put(" · ") + end + + + if app.session.member_id and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then + if not issue.fully_frozen and not issue.closed then + ui.link{ + attr = { class = "action" }, + text = _"Create alternative initiative", + module = "initiative", + view = "new", + params = { issue_id = issue.id } + } + end + end + + end } + + if not for_listing then + + if voteable then + ui.container{ + attr = { class = "voting_active_info" }, + content = function() + slot.put(_"Voting for this issue is currently running!") + slot.put(" ") + if app.session.member_id then + ui.link{ + content = vote_link_text, + module = "vote", + view = "list", + params = { issue_id = issue.id } + } + end + end + } + end + + end + + ui.container{ attr = { class = "initiative_list" }, content = function() + + local initiatives_selector = issue:get_reference_selector("initiatives") + local highlight_string = param.get("highlight_string") + if highlight_string then + initiatives_selector:add_field( {'"highlight"("initiative"."name", ?)', highlight_string }, "name_highlighted") + end + execute.view{ + module = "initiative", + view = "_list", + params = { + issue = issue, + initiatives_selector = initiatives_selector, + highlight_string = highlight_string, + per_page = initiative_limit, + no_sort = true, + limit = initiative_limit, + for_member = for_member + } + } + end } +end } + diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/_show_head.lua --- a/app/main/issue/_show_head.lua Tue Apr 17 00:07:04 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,188 +0,0 @@ -local issue = param.get("issue", "table") -local initiative = param.get("initiative", "table") - -local direct_voter - -if app.session.member_id then - direct_voter = DirectVoter:by_pk(issue.id, app.session.member.id) -end - -if config.feature_rss_enabled then - util.html_rss_head{ title = _"Initiatives in this issue (last created first)", module = "initiative", view = "list_rss", params = { issue_id = issue.id } } - util.html_rss_head{ title = _"Initiatives in this issue (last updated first)", module = "initiative", view = "list_rss", params = { issue_id = issue.id, order = "last_updated" } } -end - -slot.select("title", function() - ui.link{ - content = _("Issue ##{id}", { id = issue.id }), - module = "issue", - view = "show", - id = issue.id - } - slot.put(" · ") - ui.link{ - content = issue.area.name, - module = "area", - view = "show", - id = issue.area.id - } - if not config.single_unit_id then - slot.put(" · ") - ui.link{ - content = issue.area.unit.name, - module = "unit", - view = "show", - id = issue.area.unit_id - } - end -end) - - -slot.select("title2", function() - ui.tag{ - tag = "div", - attr = { class = "issue_policy_info" }, - content = function() - - ui.link{ - text = issue.policy.name, - module = "policy", - view = "show", - id = issue.policy.id - } - - slot.put(" · ") - ui.tag{ content = issue.state_name } - - if issue.state_time_left then - slot.put(" · ") - if issue.state_time_left:sub(1,1) == "-" then - if issue.state == "new" then - ui.tag{ content = _("Discussion starts soon") } - elseif issue.state == "discussion" then - ui.tag{ content = _("Verification starts soon") } - elseif issue.state == "frozen" then - ui.tag{ content = _("Voting starts soon") } - elseif issue.state == "voting" then - ui.tag{ content = _("Counting starts soon") } - end - else - ui.tag{ content = _("#{time_left} left", { time_left = issue.state_time_left:gsub("days", _"days"):gsub("day", _"day") }) } - end - end - - end - } - - -end) - -slot.select("actions", function() - - if app.session.member_id then - - if issue.state == 'voting' and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then - local text - if not direct_voter then - text = _"Vote now" - else - text = _"Change vote" - end - ui.link{ - content = function() - ui.image{ static = "icons/16/email_open.png" } - slot.put(text) - end, - module = "vote", - view = "list", - params = { issue_id = issue.id } - } - end - - execute.view{ - module = "interest", - view = "_show_box", - params = { issue = issue, initiative = initiative } - } - - if not issue.closed then - execute.view{ - module = "delegation", - view = "_show_box", - params = { issue_id = issue.id, - initiative_id = initiative and initiative.id or nil} - } - end - - end - - if config.issue_discussion_url_func then - local url = config.issue_discussion_url_func(issue) - ui.link{ - attr = { target = "_blank" }, - external = url, - content = function() - ui.image{ static = "icons/16/comments.png" } - slot.put(_"Discussion on issue") - end, - } - end - - if config.etherpad and app.session.member then - local url = config.etherpad.base_url .. "p/" .. config.etherpad.group_id .. "$Issue" .. issue.id - ui.link{ - attr = { target = "_blank" }, - external = url, - content = function() - ui.image{ static = "icons/16/comments.png" } - slot.put(_"Issue pad") - end, - } - end - -end) - -if app.session.member_id and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then - slot.select("actions", function() - if not issue.fully_frozen and not issue.closed then - ui.link{ - image = { static = "icons/16/script_add.png" }, - attr = { class = "action" }, - text = _"Create alternative initiative", - module = "initiative", - view = "new", - params = { issue_id = issue.id } - } - end - end) -end - -local issue = param.get("issue", "table") - -if config.public_access_issue_head and not app.session.member_id then - config.public_access_issue_head(issue) -end - -if app.session.member_id and issue.state == 'voting' and not direct_voter - and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) -then - ui.container{ - attr = { class = "voting_active_info" }, - content = function() - slot.put(_"Voting for this issue is currently running!") - slot.put(" ") - if app.session.member_id then - ui.link{ - content = function() - slot.put(_"Vote now") - end, - module = "vote", - view = "list", - params = { issue_id = issue.id } - } - end - end - } - slot.put("
") -end - diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/show.lua --- a/app/main/issue/show.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/issue/show.lua Fri May 18 19:07:07 2012 +0200 @@ -5,27 +5,11 @@ end execute.view{ - module = "issue", - view = "_show_head", - params = { issue = issue } + module = "area", + view = "_head", + params = { area = issue.area } } ---[[ -if not issue.fully_frozen and not issue.closed then - slot.select("actions", function() - ui.link{ - content = function() - ui.image{ static = "icons/16/script_add.png" } - slot.put(_"Create alternative initiative") - end, - module = "initiative", - view = "new", - params = { issue_id = issue.id } - } - end) -end ---]] - util.help("issue.show") if issue.state == "cancelled" then @@ -36,6 +20,10 @@ } end +slot.select("head", function() + execute.view{ module = "issue", view = "_show", params = { issue = issue } } +end ) + execute.view{ module = "issue", diff -r 9d463368e0d0 -r 63d6549cc00b app/main/issue/show_tab.lua --- a/app/main/issue/show_tab.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/issue/show_tab.lua Fri May 18 19:07:07 2012 +0200 @@ -18,25 +18,11 @@ static_params = { issue_id = issue.id }, } -tabs[#tabs+1] = - { - name = "initiatives", - label = _"Initiatives", - icon = { static = "icons/16/script.png" }, - module = "issue", - view = "_list_initiatives", - params = { - issue = issue - } - } - - if app.session.member_id then tabs[#tabs+1] = { name = "interested_members", - label = _"Members" .. " (" .. tostring(interested_members_selector:count()) .. ")" , - icon = { static = "icons/16/eye.png" }, + label = _"Interested" .. " (" .. tostring(interested_members_selector:count()) .. ")" , module = "member", view = "_list", params = { @@ -49,7 +35,6 @@ { name = "delegations", label = _"Delegations" .. " (" .. tostring(delegations_selector:count()) .. ")" , - icon = { static = "icons/16/table_go.png" }, module = "delegation", view = "_list", params = { delegations_selector = delegations_selector } @@ -60,11 +45,21 @@ { name = "details", label = _"Details", - icon = { static = "icons/16/magnifier.png" }, module = "issue", view = "_details", params = { issue = issue } } + +if config.etherpad then + tabs[#tabs+1] = + { + name = "pad", + label = _"Pad", + module = "issue", + view = "_pad", + params = { issue = issue } + } +end ui.tabs(tabs) diff -r 9d463368e0d0 -r 63d6549cc00b app/main/member/_area_list.lua --- a/app/main/member/_area_list.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/member/_area_list.lua Fri May 18 19:07:07 2012 +0200 @@ -1,7 +1,33 @@ local member = param.get("member", "table") local for_member = param.get("for_member", atom.boolean) +local filter_unit = param.get_all_cgi()["filter_unit"] or "personal" -local units = member.units_with_voting_right +ui.container{ attr = { class = "ui_filter_head" }, content = function() + + ui.link{ + attr = { class = filter_unit == "personal" and "ui_tabs_link active" or nil }, + text = _"With voting right", + module = "index", view = "index", params = { filter_unit = "personal" } + } + + slot.put(" ") + + ui.link{ + attr = { class = filter_unit == "global" and "active" or nil }, + text = _"All units", + module = "index", view = "index", params = { filter_unit = "global" } + } +end } + +slot.put("
") + + +if filter_unit == "global" then + execute.view{ module = "unit", view = "_list" } + return +end + +local units = Unit:new_selector():exec() for i, unit in ipairs(units) do local trustee_member = Member:new_selector() @@ -18,7 +44,7 @@ local area_count = areas_selector:count() ui.container{ attr = { class = "member_area_list" }, content = function() - ui.container{ attr = { class = "unit_head" }, content = function() + ui.container{ attr = { class = "xunit_head" }, content = function() ui.link{ text = unit.name, module = "unit", view = "show", id = unit.id @@ -49,7 +75,7 @@ module = "area", view = "_list", params = { areas_selector = areas_selector, hide_membership = true } } - else + elseif member:has_voting_right_for_unit_id(unit.id) then if for_member then ui.container{ attr = { class = "voting_priv_info" }, content = _"This member has voting privileges for this unit, but you ist not member of any of its areas." } else @@ -77,3 +103,5 @@ end } end + + diff -r 9d463368e0d0 -r 63d6549cc00b app/main/member/_menu.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/member/_menu.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,104 @@ +ui.tag{ tag = "ul", content = function() + + ui.tag{ tag = "li", content = function() + + ui.link{ + text = _"Show profile", + module = "member", + view = "show", + id = app.session.member_id + } + + end } + + ui.tag{ tag = "li", content = function() + + ui.link{ + content = function() + slot.put(_"Edit profile") + end, + module = "member", + view = "edit" + } + + end } + + ui.tag{ tag = "li", content = function() + + ui.link{ + content = function() + slot.put(_"Upload avatar/photo") + end, + module = "member", + view = "edit_images" + } + + end } + + ui.tag{ tag = "li", content = function() + + ui.link{ + content = _"Contacts", + module = 'contact', + view = 'list' + } + + end } + + ui.tag{ tag = "li", content = function() + + ui.link{ + text = _"Settings", + module = "member", + view = "settings" + } + + end } + + ui.tag{ tag = "li", content = function() + + ui.link{ + text = _"Logout", + module = 'index', + action = 'logout', + routing = { + default = { + mode = "redirect", + module = "index", + view = "index" + } + } + } + end } + + ui.tag{ tag = "li", content = function() + ui.tag{ tag = "span", content = _"Select language" } + end } + + for i, lang in ipairs{"en", "de", "eo"} do + ui.tag{ tag = "li", content = function() + ui.link{ + content = function() + ui.image{ + static = "lang/" .. lang .. ".png", + } + ui.tag{ content = _('Select language "#{langcode}"', { langcode = lang }) } + end, + module = "index", + action = "set_lang", + params = { lang = lang }, + routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } + } + } + end } + end + +end } + diff -r 9d463368e0d0 -r 63d6549cc00b app/main/member/_profile.lua --- a/app/main/member/_profile.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/member/_profile.lua Fri May 18 19:07:07 2012 +0200 @@ -9,28 +9,6 @@ end end ---slot.select("actions", function() - - if app.session.member and app.session.member_id == member.id then - ui.link{ - content = function() - slot.put(_"Edit my profile") - end, - module = "member", - view = "edit" - } - slot.put(" ") - ui.link{ - content = function() - slot.put(_"Upload images") - end, - module = "member", - view = "edit_images" - } - slot.put("

") - end ---end) - ui.form{ attr = { class = "box member vertical" }, record = member, diff -r 9d463368e0d0 -r 63d6549cc00b app/main/member/_show.lua --- a/app/main/member/_show.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/member/_show.lua Fri May 18 19:07:07 2012 +0200 @@ -1,8 +1,246 @@ -execute.view{ +local show_as_homepage = param.get("show_as_homepage", atom.boolean) + +local member = param.get("member", "table") + +local tabs = { module = "member", view = "show_tab", - params = { - member = param.get("member", "table"), - show_as_homepage = param.get("show_as_homepage", atom.boolean) + static_params = { + member_id = member.id, + show_as_homepage = show_as_homepage } -} \ No newline at end of file +} + +if show_as_homepage and app.session.member_id == member.id then + + if app.session.member.notify_email_unconfirmed then + tabs[#tabs+1] = { + class = "yellow", + name = "email_unconfirmed", + label = _"Email unconfirmed", + module = "member", + view = "_email_unconfirmed", + params = {} + } + end + + if app.session.member.notify_level == nil then + tabs[#tabs+1] = { + class = "yellow", + name = "notify_level_not_set", + label = _"Notifications", + module = "member", + view = "_notify_level_not_set" + } + end + + local broken_delegations = Delegation:new_selector() + :join("issue", nil, "issue.id = delegation.issue_id AND issue.closed ISNULL") + :join("member", nil, "delegation.trustee_id = member.id") + :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 } + + if broken_delegations:count() > 0 then + tabs[#tabs+1] = { + class = "red", + name = "broken_delegations", + label = _"Delegation problems" .. " (" .. tostring(broken_delegations:count()) .. ")", + icon = { static = "icons/16/table_go.png" }, + module = "delegation", + view = "_list", + params = { delegations_selector = broken_delegations, outgoing = true }, + } + end + + local selector = Issue:new_selector() + :join("area", nil, "area.id = issue.area_id") + :join("privilege", nil, { "privilege.unit_id = area.unit_id AND privilege.member_id = ? AND privilege.voting_right", app.session.member_id }) + :left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) + :left_join("interest", nil, { "interest.issue_id = issue.id AND interest.member_id = ?", app.session.member.id }) + :left_join("membership", nil, { "membership.area_id = area.id AND membership.member_id = ? ", app.session.member.id }) + :add_where{ "direct_voter.member_id ISNULL" } + :add_where{ "interest.member_id NOTNULL OR membership.member_id NOTNULL" } + :add_where{ "issue.fully_frozen NOTNULL" } + :add_where{ "issue.closed ISNULL" } + :add_order_by{ "issue.fully_frozen + issue.voting_time ASC" } + + local count = selector:count() + if count > 0 then + tabs[#tabs+1] = { + class = "yellow", + name = "not_voted_issues", + label = _"Now in voting" .. " (" .. tostring(count) .. ")", + icon = { static = "icons/16/email_open.png" }, + module = "issue", + view = "_list", + params = { + issues_selector = selector, + no_filter = true + } + } + end + + local initiator_invites_selector = Initiative:new_selector() + :join("issue", "_issue_state", "_issue_state.id = initiative.issue_id") + :join("initiator", nil, { "initiator.initiative_id = initiative.id AND initiator.member_id = ? AND initiator.accepted ISNULL", app.session.member.id }) + :add_where("_issue_state.closed ISNULL AND _issue_state.half_frozen ISNULL") + + if initiator_invites_selector:count() > 0 then + tabs[#tabs+1] = { + class = "yellow", + name = "initiator_invites", + label = _"Initiator invites" .. " (" .. tostring(initiator_invites_selector:count()) .. ")", + icon = { static = "icons/16/user_add.png" }, + module = "index", + view = "_initiator_invites", + params = { + initiatives_selector = initiator_invites_selector + } + } + end + + local updated_drafts_selector = Initiative:new_selector() + :join("issue", "_issue_state", "_issue_state.id = initiative.issue_id AND _issue_state.closed ISNULL AND _issue_state.fully_frozen ISNULL") + :join("current_draft", "_current_draft", "_current_draft.initiative_id = initiative.id") + :join("supporter", "supporter", { "supporter.member_id = ? AND supporter.initiative_id = initiative.id AND supporter.draft_id < _current_draft.id", app.session.member_id }) + :add_where("initiative.revoked ISNULL") + + if updated_drafts_selector:count() > 0 then + tabs[#tabs+1] = { + class = "yellow", + name = "updated_drafts", + label = _"Updated drafts" .. " (" .. tostring(updated_drafts_selector:count()) .. ")", + icon = { static = "icons/16/script.png" }, + module = "index", + view = "_updated_drafts", + params = { + initiatives_selector = updated_drafts_selector + } + } + end +end + +if not show_as_homepage then + tabs[#tabs+1] = { + name = "profile", + label = _"Profile", + icon = { static = "icons/16/application_form.png" }, + module = "member", + view = "_profile", + params = { member = member }, + } +end + + +local areas_selector = member:get_reference_selector("areas") +tabs[#tabs+1] = { + name = "areas", + label = _"Units", + icon = { static = "icons/16/package.png" }, + module = "member", + view = "_area_list", + params = { areas_selector = areas_selector, member = member, for_member = not show_as_homepage }, +} + +if show_as_homepage then + tabs[#tabs+1] = { + name = "timeline", + label = _"Events", + module = "member", + view = "_event_list", + params = { } + } +else + tabs[#tabs+1] = { + name = "timeline", + label = _"Events", + module = "event", + view = "_list", + params = { for_member = member } + } +end + +tabs[#tabs+1] = { + name = "open", + label = _"Open issues", + module = "issue", + view = "_list", + link_params = { + filter_interest = not show_as_homepage and "issue" or nil, + }, + params = { + for_state = "open", + for_member = not show_as_homepage and member or nil, + issues_selector = Issue:new_selector() + :add_where("issue.closed ISNULL") + :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()") + } +} + +tabs[#tabs+1] = { + name = "closed", + label = _"Closed issues", + module = "issue", + view = "_list", + link_params = { + filter_interest = not show_as_homepage and "issue" or nil, + }, + params = { + for_state = "closed", + for_member = not show_as_homepage and member or nil, + issues_selector = Issue:new_selector() + :add_where("issue.closed NOTNULL") + :add_order_by("issue.closed DESC") + + } +} + +if show_as_homepage then + tabs[#tabs+1] = { + name = "members", + label = _"Members", + module = 'member', + view = '_list', + params = { members_selector = Member:new_selector() } + } +end + + + +if not show_as_homepage then + local outgoing_delegations_selector = member:get_reference_selector("outgoing_delegations") + :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id") + :add_where("_member_showtab_issue.closed ISNULL") + tabs[#tabs+1] = { + name = "outgoing_delegations", + label = _"Outgoing delegations" .. " (" .. tostring(outgoing_delegations_selector:count()) .. ")", + icon = { static = "icons/16/table_go.png" }, + module = "delegation", + view = "_list", + params = { delegations_selector = outgoing_delegations_selector, outgoing = true }, + } + + local incoming_delegations_selector = member:get_reference_selector("incoming_delegations") + :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id") + :add_where("_member_showtab_issue.closed ISNULL") + tabs[#tabs+1] = { + name = "incoming_delegations", + label = _"Incoming delegations" .. " (" .. tostring(incoming_delegations_selector:count()) .. ")", + icon = { static = "icons/16/table_go.png" }, + module = "delegation", + view = "_list", + params = { delegations_selector = incoming_delegations_selector, incoming = true }, + } + + local contacts_selector = member:get_reference_selector("saved_members"):add_where("public") + tabs[#tabs+1] = { + name = "contacts", + label = _"Contacts" .. " (" .. tostring(contacts_selector:count()) .. ")", + icon = { static = "icons/16/book_edit.png" }, + module = "member", + view = "_list", + params = { members_selector = contacts_selector }, + } +end + +ui.tabs(tabs) diff -r 9d463368e0d0 -r 63d6549cc00b app/main/member/menu.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/member/menu.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,11 @@ +if not app.session.member_id then + error("access denied") +end + +app.html_title.title = _("Member menu") + +execute.view{ + module = "member", + view = "_menu" +} + diff -r 9d463368e0d0 -r 63d6549cc00b app/main/member/show.lua --- a/app/main/member/show.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/member/show.lua Fri May 18 19:07:07 2012 +0200 @@ -23,7 +23,6 @@ slot.select("actions", function() ui.link{ content = function() - ui.image{ static = "icons/16/clock_edit.png" } slot.put(encode.html(_"Show member history")) end, module = "member", @@ -39,6 +38,7 @@ slot.put(" ") end if not (member.id == app.session.member.id) then + slot.put(" · ") --TODO performance local contact = Contact:by_pk(app.session.member.id, member.id) if contact then @@ -47,7 +47,6 @@ content = _"You have saved this member as contact." } ui.link{ - image = { static = "icons/16/book_delete.png" }, text = _"Remove from contacts", module = "contact", action = "remove_member", @@ -64,7 +63,6 @@ } elseif member.activated then ui.link{ - image = { static = "icons/16/book_add.png" }, text = _"Add to my contacts", module = "contact", action = "add_member", @@ -82,11 +80,13 @@ end end local ignored_member = IgnoredMember:by_pk(app.session.member.id, member.id) + slot.put(" · ") if ignored_member then ui.container{ attr = { class = "interest" }, content = _"You have ignored this member" } + slot.put(" · ") ui.link{ text = _"Stop ignoring member", module = "member", diff -r 9d463368e0d0 -r 63d6549cc00b app/main/member/show_tab.lua --- a/app/main/member/show_tab.lua Tue Apr 17 00:07:04 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,265 +0,0 @@ -local show_as_homepage = param.get("show_as_homepage", atom.boolean) - -local member - -if request.get_json_request_slots() then - member = Member:by_id(param.get("member_id")) -else - member = param.get("member", "table") -end - -local tabs = { - module = "member", - view = "show_tab", - static_params = { - member_id = member.id, - show_as_homepage = show_as_homepage - } -} - -if show_as_homepage and app.session.member_id == member.id then - - if app.session.member.notify_email_unconfirmed then - tabs[#tabs+1] = { - class = "yellow", - name = "email_unconfirmed", - label = _"Email unconfirmed", - module = "member", - view = "_email_unconfirmed", - params = {} - } - end - - if app.session.member.notify_level == nil then - tabs[#tabs+1] = { - class = "yellow", - name = "notify_level_not_set", - label = _"Notifications", - module = "member", - view = "_notify_level_not_set" - } - end - - --[[ - if config.motd_intern then - tabs[#tabs+1] = { - class = "yellow", - name = "motd", - label = _"Message of the day", - module = "index", - view = "_motd", - params = {} - } - end - --]] - - local broken_delegations = Delegation:new_selector() - :join("issue", nil, "issue.id = delegation.issue_id AND issue.closed ISNULL") - :join("member", nil, "delegation.trustee_id = member.id") - :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 } - - if broken_delegations:count() > 0 then - tabs[#tabs+1] = { - class = "red", - name = "broken_delegations", - label = _"Delegation problems" .. " (" .. tostring(broken_delegations:count()) .. ")", - icon = { static = "icons/16/table_go.png" }, - module = "delegation", - view = "_list", - params = { delegations_selector = broken_delegations, outgoing = true }, - } - end - - local selector = Area:new_selector() - :reset_fields() - :join("privilege", nil, { "privilege.unit_id = area.unit_id AND privilege.member_id = ? AND privilege.voting_right", app.session.member_id }) - :add_field("area.id", nil, { "grouped" }) - :add_field("area.name", nil, { "grouped" }) - :add_field("membership.member_id NOTNULL", "is_member", { "grouped" }) - :add_field("count(issue.id)", "issues_to_vote_count") - :add_field("count(interest.member_id)", "interested_issues_to_vote_count") - :add_field("count(interest.member_id NOTNULL OR interest.member_id NOTNULL)", "issues_to_vote_count_sum") - :join("issue", nil, "issue.area_id = area.id AND issue.fully_frozen NOTNULL AND issue.closed ISNULL") - :left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) - :add_where{ "direct_voter.member_id ISNULL" } - :left_join("interest", nil, { "interest.issue_id = issue.id AND interest.member_id = ?", app.session.member.id }) - :left_join("membership", nil, { "membership.area_id = area.id AND membership.member_id = ? ", app.session.member.id }) - - local not_voted_areas = {} - local issues_to_vote_count = 0 - for i, area in ipairs(selector:exec()) do - if area.is_member or area.interested_issues_to_vote_count > 0 then - not_voted_areas[#not_voted_areas+1] = area - end - if area.is_member then - issues_to_vote_count = issues_to_vote_count + area.issues_to_vote_count_sum - end - end - - if issues_to_vote_count > 0 then - tabs[#tabs+1] = { - class = "yellow", - name = "not_voted_issues", - label = _"Not voted issues" .. " (" .. tostring(issues_to_vote_count) .. ")", - icon = { static = "icons/16/email_open.png" }, - module = "index", - view = "_not_voted_issues", - params = { - areas = not_voted_areas - } - } - end - - local initiator_invites_selector = Initiative:new_selector() - :join("issue", "_issue_state", "_issue_state.id = initiative.issue_id") - :join("initiator", nil, { "initiator.initiative_id = initiative.id AND initiator.member_id = ? AND initiator.accepted ISNULL", app.session.member.id }) - :add_where("_issue_state.closed ISNULL AND _issue_state.half_frozen ISNULL") - - if initiator_invites_selector:count() > 0 then - tabs[#tabs+1] = { - class = "yellow", - name = "initiator_invites", - label = _"Initiator invites" .. " (" .. tostring(initiator_invites_selector:count()) .. ")", - icon = { static = "icons/16/user_add.png" }, - module = "index", - view = "_initiator_invites", - params = { - initiatives_selector = initiator_invites_selector - } - } - end - - local updated_drafts_selector = Initiative:new_selector() - :join("issue", "_issue_state", "_issue_state.id = initiative.issue_id AND _issue_state.closed ISNULL AND _issue_state.fully_frozen ISNULL") - :join("current_draft", "_current_draft", "_current_draft.initiative_id = initiative.id") - :join("supporter", "supporter", { "supporter.member_id = ? AND supporter.initiative_id = initiative.id AND supporter.draft_id < _current_draft.id", app.session.member_id }) - :add_where("initiative.revoked ISNULL") - - if updated_drafts_selector:count() > 0 then - tabs[#tabs+1] = { - class = "yellow", - name = "updated_drafts", - label = _"Updated drafts" .. " (" .. tostring(updated_drafts_selector:count()) .. ")", - icon = { static = "icons/16/script.png" }, - module = "index", - view = "_updated_drafts", - params = { - initiatives_selector = updated_drafts_selector - } - } - end -end - -if not show_as_homepage then - tabs[#tabs+1] = { - name = "profile", - label = _"Profile", - icon = { static = "icons/16/application_form.png" }, - module = "member", - view = "_profile", - params = { member = member }, - } -end - - -local areas_selector = member:get_reference_selector("areas") -tabs[#tabs+1] = { - name = "areas", - label = _"Areas", - icon = { static = "icons/16/package.png" }, - module = "member", - view = "_area_list", - params = { areas_selector = areas_selector, member = member, for_member = not show_as_homepage }, -} - -if show_as_homepage then - tabs[#tabs+1] = { - name = "timeline", - label = _"Events", - module = "member", - view = "_event_list", - params = { } - } -else - tabs[#tabs+1] = { - name = "timeline", - label = _"Events", - module = "event", - view = "_list", - params = { for_member = member } - } -end - -tabs[#tabs+1] = { - name = "open", - label = _"Open issues", - module = "issue", - view = "_list", - link_params = { - filter_interest = not show_as_homepage and "issue" or nil, - }, - params = { - for_state = "open", - for_member = not show_as_homepage and member or nil, - issues_selector = Issue:new_selector() - :add_where("issue.closed ISNULL") - :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()") - } -} - -tabs[#tabs+1] = { - name = "closed", - label = _"Closed issues", - module = "issue", - view = "_list", - link_params = { - filter_interest = not show_as_homepage and "issue" or nil, - }, - params = { - for_state = "closed", - for_member = not show_as_homepage and member or nil, - issues_selector = Issue:new_selector() - :add_where("issue.closed NOTNULL") - :add_order_by("issue.closed DESC") - - } -} - -if not show_as_homepage then - local outgoing_delegations_selector = member:get_reference_selector("outgoing_delegations") - :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id") - :add_where("_member_showtab_issue.closed ISNULL") - tabs[#tabs+1] = { - name = "outgoing_delegations", - label = _"Outgoing delegations" .. " (" .. tostring(outgoing_delegations_selector:count()) .. ")", - icon = { static = "icons/16/table_go.png" }, - module = "delegation", - view = "_list", - params = { delegations_selector = outgoing_delegations_selector, outgoing = true }, - } - - local incoming_delegations_selector = member:get_reference_selector("incoming_delegations") - :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id") - :add_where("_member_showtab_issue.closed ISNULL") - tabs[#tabs+1] = { - name = "incoming_delegations", - label = _"Incoming delegations" .. " (" .. tostring(incoming_delegations_selector:count()) .. ")", - icon = { static = "icons/16/table_go.png" }, - module = "delegation", - view = "_list", - params = { delegations_selector = incoming_delegations_selector, incoming = true }, - } - - local contacts_selector = member:get_reference_selector("saved_members"):add_where("public") - tabs[#tabs+1] = { - name = "contacts", - label = _"Contacts" .. " (" .. tostring(contacts_selector:count()) .. ")", - icon = { static = "icons/16/book_edit.png" }, - module = "member", - view = "_list", - params = { members_selector = contacts_selector }, - } -end - -ui.tabs(tabs) diff -r 9d463368e0d0 -r 63d6549cc00b app/main/member_image/_show.lua --- a/app/main/member_image/_show.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/member_image/_show.lua Fri May 18 19:07:07 2012 +0200 @@ -1,4 +1,6 @@ local member = param.get("member", "table") +local member_id = member and member.id or param.get("member_id", atom.integer) + local image_type = param.get("image_type") local show_dummy = param.get("show_dummy", atom.boolean) local class = param.get("class") @@ -10,6 +12,7 @@ class = "" end +--[[ local image = member:get_reference_selector("images") :add_where{ "image_type = ?", image_type } :optional_object_mode() @@ -28,16 +31,19 @@ external = encode.url{ static = (config.member_image_default_file[image_type] or 'icons/16/lightning.png')}, } else +--]] ui.image{ attr = { title = popup_text, class = "member_image member_image_" .. image_type .. class }, module = "member_image", view = "show", extension = "jpg", - id = member.id, + id = member_id, params = { image_type = image_type } } + --[[ end end end +--]] \ No newline at end of file diff -r 9d463368e0d0 -r 63d6549cc00b app/main/membership/_show_box.lua --- a/app/main/membership/_show_box.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/membership/_show_box.lua Fri May 18 19:07:07 2012 +0200 @@ -2,46 +2,43 @@ local membership = Membership:by_pk(area.id, app.session.member.id) -slot.select("interest", function() +if membership then - if membership then + ui.container{ + attr = { + class = "head head_active", + }, + content = function() + ui.image{ + static = "icons/16/user_green.png" + } + slot.put(_"You are member") + end + } - ui.container{ - attr = { - class = "head head_active", - }, - content = function() - ui.image{ - static = "icons/16/user_green.png" - } - slot.put(_"You are member") - end - } - - ui.link{ - image = { static = "icons/16/cross.png" }, - text = _"Withdraw membership", - module = "membership", - action = "update", - params = { area_id = area.id, delete = true }, - routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } - } - elseif app.session.member:has_voting_right_for_unit_id(area.unit_id) then - ui.link{ - image = { static = "icons/16/user_add.png" }, - text = _"Become a member", - module = "membership", - action = "update", - params = { area_id = area.id }, - routing = { - default = { - mode = "redirect", - module = "area", - view = "show", - id = area.id - } + ui.link{ + image = { static = "icons/16/cross.png" }, + text = _"Withdraw membership", + module = "membership", + action = "update", + params = { area_id = area.id, delete = true }, + routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } + } +elseif app.session.member:has_voting_right_for_unit_id(area.unit_id) then + ui.link{ + image = { static = "icons/16/user_add.png" }, + text = _"Become a member", + module = "membership", + action = "update", + params = { area_id = area.id }, + routing = { + default = { + mode = "redirect", + module = "area", + view = "show", + id = area.id } } - end + } +end -end) diff -r 9d463368e0d0 -r 63d6549cc00b app/main/supporter/_show_box.lua --- a/app/main/supporter/_show_box.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/supporter/_show_box.lua Fri May 18 19:07:07 2012 +0200 @@ -3,180 +3,181 @@ -- TODO performance local initiator = Initiator:by_pk(initiative.id, app.session.member.id) -ui.partial{ - module = "initiative", - view = "show_support", - id = initiative.id, - target = "initiative_" .. tostring(initiative.id) .. "_support", - content = function() - - ui.container{ - attr = { class = "actions" }, - content = function() - - local initiative = param.get("initiative", "table") - local supporter = Supporter:by_pk(initiative.id, app.session.member.id) +local initiative = param.get("initiative", "table") +local supporter = Supporter:by_pk(initiative.id, app.session.member.id) - local partial = { - routing = { - default = { - mode = "redirect", - module = "initiative", - view = "show_support", - id = initiative.id - } - } - } +local partial = { + routing = { + default = { + mode = "redirect", + module = "initiative", + view = "show_support", + id = initiative.id + } + } +} - local routing = { - default = { - mode = "redirect", - module = request.get_module(), - view = request.get_view(), - id = param.get_id_cgi(), - params = param.get_all_cgi() - } - } +local routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } +} - if not initiative.issue.fully_frozen and not initiative.issue.closed then - if supporter then - if not supporter:has_critical_opinion() then - ui.container{ attr = { class = "supporter" }, content = function() - ui.image{ - static = "icons/16/thumb_up_green.png" - } - slot.put(_"Your are supporter") - end } - else - ui.tag{ attr = { class = "potential_supporter" }, content = function() - ui.image{ - static = "icons/16/thumb_up.png" - } - slot.put(_"Your are potential supporter") - end } - end - ui.link{ - image = { static = "icons/16/cross.png" }, - text = _"Withdraw support", - module = "initiative", - action = "remove_support", - id = initiative.id, - routing = routing, - partial = partial - } - elseif not initiative.revoked and app.session.member:has_voting_right_for_unit_id(initiative.issue.area.unit_id) then - local params = param.get_all_cgi() - params.dyn = nil - ui.link{ - image = { static = "icons/16/thumb_up_green.png" }, - text = _"Support this initiative", - module = "initiative", - action = "add_support", - id = initiative.id, - routing = routing, - partial = partial - } - end - end +if not initiative.issue.fully_frozen and not initiative.issue.closed then + if supporter then + if not supporter:has_critical_opinion() then + ui.tag{ content = function() + ui.image{ + static = "icons/16/thumb_up_green.png" + } + slot.put(_"Your are supporter") + end } + else + ui.tag{ attr = { class = "potential_supporter" }, content = function() + ui.image{ + static = "icons/16/thumb_up.png" + } + slot.put(_"Your are potential supporter") + end } + end + slot.put(" (") + ui.link{ + text = _"Withdraw", + module = "initiative", + action = "remove_support", + id = initiative.id, + routing = routing, + partial = partial + } + slot.put(") ") + elseif not initiative.revoked and app.session.member:has_voting_right_for_unit_id(initiative.issue.area.unit_id) then + local params = param.get_all_cgi() + params.dyn = nil + ui.link{ + text = _"Support this initiative", + module = "initiative", + action = "add_support", + id = initiative.id, + routing = routing, + partial = partial + } + slot.put(" ") + end +end +if app.session.member_id + and not initiative.issue.half_frozen + and not initiative.issue.closed + and not initiative.revoked + and app.session.member:has_voting_right_for_unit_id(initiative.issue.area.unit_id) +then + ui.link{ + content = function() + slot.put(_"Add suggestion") + end, + module = "suggestion", + view = "new", + params = { + initiative_id = initiative.id + } + } + slot.put(" ") +end - if (initiative.discussion_url and #initiative.discussion_url > 0) then - if initiative.discussion_url:find("^https?://") then - if initiative.discussion_url and #initiative.discussion_url > 0 then - ui.link{ - attr = { - target = "_blank", - title = _"Discussion with initiators" - }, - image = { static = "icons/16/comments.png" }, - text = _"Discuss with initiators", - external = initiative.discussion_url - } - end - else - slot.put(encode.html(initiative.discussion_url)) - end - end - if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then - ui.link{ - image = { static = "icons/16/comments.png" }, - text = _"change discussion URL", - module = "initiative", - view = "edit", - id = initiative.id - } - end - if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then - ui.link{ - content = function() - ui.image{ static = "icons/16/script_add.png" } - slot.put(_"Edit draft") - end, - module = "draft", - view = "new", - params = { initiative_id = initiative.id } - } - end +if (initiative.discussion_url and #initiative.discussion_url > 0) then + if initiative.discussion_url:find("^https?://") then + if initiative.discussion_url and #initiative.discussion_url > 0 then + ui.link{ + attr = { + target = "_blank", + title = _"Discussion with initiators" + }, + text = _"Discuss with initiators", + external = initiative.discussion_url + } + slot.put(" ") + end + else + slot.put(encode.html(initiative.discussion_url)) + end +end +if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then + ui.link{ + image = { static = "icons/16/comments.png" }, + text = _"change discussion URL", + module = "initiative", + view = "edit", + id = initiative.id + } + slot.put(" ") +end +if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then + ui.link{ + content = function() + ui.image{ static = "icons/16/script_add.png" } + slot.put(_"Edit draft") + end, + module = "draft", + view = "new", + params = { initiative_id = initiative.id } + } + slot.put(" ") +end - if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then - ui.link{ - content = function() - ui.image{ static = "icons/16/script_delete.png" } - slot.put(_"Revoke initiative") - end, - module = "initiative", - view = "revoke", - id = initiative.id - } - end - - if not initiative.issue.closed then - local ignored_initiative = IgnoredInitiative:by_pk(app.session.member.id, initiative.id) - if ignored_initiative then - ui.container{ - attr = { class = "interest" }, - content = _"You have ignored this initiative" - } - ui.link{ - text = _"Stop ignoring initiative", - module = "initiative", - action = "update_ignore", - id = initiative.id, - params = { delete = true }, - routing = { - default = { - mode = "redirect", - module = request.get_module(), - view = request.get_view(), - id = param.get_id_cgi(), - params = param.get_all_cgi() - } - } - } - else - ui.link{ - attr = { class = "interest" }, - text = _"Ignore initiative", - module = "initiative", - action = "update_ignore", - id = initiative.id, - routing = { - default = { - mode = "redirect", - module = request.get_module(), - view = request.get_view(), - id = param.get_id_cgi(), - params = param.get_all_cgi() - } - } - } - end - end - - end +if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then + ui.link{ + content = function() + ui.image{ static = "icons/16/script_delete.png" } + slot.put(_"Revoke initiative") + end, + module = "initiative", + view = "revoke", + id = initiative.id + } + slot.put(" ") +end + +if not initiative.issue.closed then + local ignored_initiative = IgnoredInitiative:by_pk(app.session.member.id, initiative.id) + if ignored_initiative then + ui.tag{ + content = _"You have ignored this initiative" } - - - slot.put("
") + ui.link{ + text = _"Stop ignoring initiative", + module = "initiative", + action = "update_ignore", + id = initiative.id, + params = { delete = true }, + routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } + } + } + else + ui.link{ + text = _"Ignore initiative", + module = "initiative", + action = "update_ignore", + id = initiative.id, + routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } + } + } end -} +end diff -r 9d463368e0d0 -r 63d6549cc00b app/main/unit/_head.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/unit/_head.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,31 @@ +local unit = param.get("unit", "table") + +slot.select("head", function() + + ui.container{ attr = { class = "unit_head" }, content = function() + + execute.view{ module = "delegation", view = "_info", params = { unit = unit } } + + ui.container{ attr = { class = "title" }, content = function() + if not config.single_unit_id then + ui.link{ + module = "unit", view = "show", id = unit.id, + attr = { class = "unit_name" }, content = unit.name + } + else + ui.link{ + module = "unit", view = "show", id = unit.id, + attr = { class = "unit_name" }, content = config.app_title + } + end + end } + + ui.container{ attr = { class = "content" }, content = function() + + ui.tag{ content = "1234 Stimmberechtigte" } + + end } + + end } + +end ) \ No newline at end of file diff -r 9d463368e0d0 -r 63d6549cc00b app/main/unit/show.lua --- a/app/main/unit/show.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/app/main/unit/show.lua Fri May 18 19:07:07 2012 +0200 @@ -2,11 +2,7 @@ local unit = Unit:by_id(unit_id) -if not config.single_unit_id then - slot.put_into("title", unit.name) -else - slot.put_into("title", encode.html(config.app_title)) -end +execute.view{ module = "unit", view = "_head", params = { unit = unit } } if config.single_unit_id and not app.session.member_id and config.motd_public then local help_text = config.motd_public @@ -20,15 +16,6 @@ util.help("unit.show", _"Unit") -if app.session.member_id then - execute.view{ - module = "delegation", - view = "_show_box", - params = { unit_id = unit_id } - } -end - - local areas_selector = Area:build_selector{ active = true, unit_id = unit_id } areas_selector:add_order_by("member_weight DESC") @@ -101,8 +88,8 @@ if app.session.member_id then tabs[#tabs+1] = { - name = "members", - label = _"Members", + name = "eligible_voters", + label = _"Eligible voters", module = "member", view = "_list", params = { members_selector = members_selector } diff -r 9d463368e0d0 -r 63d6549cc00b config/default.lua --- a/config/default.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/config/default.lua Fri May 18 19:07:07 2012 +0200 @@ -1,7 +1,20 @@ +-- forward compatibility for webmcp 1.2 +if not os.pfilter then + os.pfilter = extos.pfilter +end +if not os.listdir then + os.listdir = extos.listdir +end +if not os.crypt then + os.crypt = extos.crypt +end + config.app_name = "LiquidFeedback" config.app_version = "2.beta4" -config.app_title = config.app_name .. " (" .. request.get_config_name() .. " environment)" +config.instance_name = request.get_config_name() + +config.app_title = config.app_name .. " " .. config.instance_name config.app_logo = nil @@ -75,13 +88,13 @@ -- functions and to disable garbage collection during the request, to -- increase speed: -- --- require 'webmcp_accelerator' --- collectgarbage("stop") +require 'webmcp_accelerator' +collectgarbage("stop") -- open and set default database handle db = assert(mondelefant.connect{ engine='postgresql', - dbname='liquid_feedback_p' + dbname='liquid_feedback' }) at_exit(function() db:close() diff -r 9d463368e0d0 -r 63d6549cc00b config/development.lua --- a/config/development.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/config/development.lua Fri May 18 19:07:07 2012 +0200 @@ -44,8 +44,8 @@ --) config.etherpad = { - base_url = "http://localhost:9001/", - api_base = "http://localhost:9001/", + base_url = "http://10.8.33.34:9001/", + api_base = "http://10.8.33.34:9001/", api_key = "g5XAVrRb5EgPuEqIdVrRNt2Juipx3PoH", group_id = "g.7WDKN3StkEyuWkyN", cookie_path = "/" diff -r 9d463368e0d0 -r 63d6549cc00b config/example.lua --- a/config/example.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/config/example.lua Fri May 18 19:07:07 2012 +0200 @@ -4,6 +4,8 @@ config.app_name = "LiquidFeedback" config.app_version = "2.beta1" +config.instance_name = request.get_config_name() + config.app_title = config.app_name .. " (" .. request.get_config_name() .. " environment)" config.app_logo = nil diff -r 9d463368e0d0 -r 63d6549cc00b model/area.lua --- a/model/area.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/model/area.lua Fri May 18 19:07:07 2012 +0200 @@ -58,6 +58,59 @@ ref = 'allowed_policies' } +Area:add_reference{ + mode = "11", + to = mondelefant.class_prototype, + this_key = "id", + that_key = "area_id", + ref = "delegation_info", + back_ref = "area", + selector_generator = function(list, options) + assert(options.member_id, "member_id mandatory for delegation_info") + local ids = { sep = ", " } + for i, object in ipairs(list) do + local id = object.id + if id ~= nil then + ids[#ids+1] = {"?", id} + end + end + local sub_selector = Area:get_db_conn():new_selector() + if #ids == 0 then + return sub_selector:empty_list_mode() + end + sub_selector:from("area") + sub_selector:add_field("area.id", "area_id") + sub_selector:add_field{ '(delegation_info(?, null, area.id, null)).*', options.member_id } + sub_selector:add_where{ 'area.id IN ($)', ids } + + local selector = Area:get_db_conn():new_selector() + selector:add_from(sub_selector, "delegation_info") + selector:left_join("member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id") + selector:left_join("member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id") + selector:add_field("delegation_info.*") + selector:add_field("first_trustee.name", "first_trustee_name") + selector:add_field("other_trustee.name", "other_trustee_name") + return selector + end +} + +function Area.list:load_delegation_info_once_for_member_id(member_id) + if self._delegation_info_loaded_for_member_id ~= member_id then + self:load("delegation_info", { member_id = member_id }) + for i, area in ipairs(self) do + area._delegation_info_loaded_for_member_id = member_id + end + self._delegation_info_loaded_for_member_id = member_id + end +end + +function Area.object:load_delegation_info_once_for_member_id(member_id) + if self._delegation_info_loaded_for_member_id ~= member_id then + self:load("delegation_info", { member_id = member_id }) + self._delegation_info_loaded_for_member_id = member_id + end +end + function Area.object_get:default_policy() return Policy:new_selector() :join("allowed_policy", nil, "allowed_policy.policy_id = policy.id") diff -r 9d463368e0d0 -r 63d6549cc00b model/delegation_info.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/model/delegation_info.lua Fri May 18 19:07:07 2012 +0200 @@ -0,0 +1,1 @@ +DelegationInfo = mondelefant.new_class() diff -r 9d463368e0d0 -r 63d6549cc00b model/issue.lua --- a/model/issue.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/model/issue.lua Fri May 18 19:07:07 2012 +0200 @@ -108,6 +108,58 @@ ref = 'direct_voters' } +Issue:add_reference{ + mode = "11", + to = mondelefant.class_prototype, + this_key = "id", + that_key = "issue_id", + ref = "delegation_info", + back_ref = "issue", + selector_generator = function(list, options) + assert(options.member_id, "member_id mandatory for delegation_info") + local ids = { sep = ", " } + for i, object in ipairs(list) do + local id = object.id + if id ~= nil then + ids[#ids+1] = {"?", id} + end + end + local sub_selector = Issue:get_db_conn():new_selector() + if #ids == 0 then + return sub_selector:empty_list_mode() + end + sub_selector:from("issue") + sub_selector:add_field("issue.id", "issue_id") + sub_selector:add_field{ '(delegation_info(?, null, null, issue.id)).*', options.member_id } + sub_selector:add_where{ 'issue.id IN ($)', ids } + + local selector = Issue:get_db_conn():new_selector() + selector:add_from(sub_selector, "delegation_info") + selector:left_join("member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id") + selector:left_join("member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id") + selector:add_field("delegation_info.*") + selector:add_field("first_trustee.name", "first_trustee_name") + selector:add_field("other_trustee.name", "other_trustee_name") + return selector + end +} + +function Issue.list:load_delegation_info_once_for_member_id(member_id) + if self._delegation_info_loaded_for_member_id ~= member_id then + self:load("delegation_info", { member_id = member_id }) + for i, issue in ipairs(self) do + issue._delegation_info_loaded_for_member_id = member_id + end + self._delegation_info_loaded_for_member_id = member_id + end +end + +function Issue.object:load_delegation_info_once_for_member_id(member_id) + if self._delegation_info_loaded_for_member_id ~= member_id then + self:load("delegation_info", { member_id = member_id }) + self._delegation_info_loaded_for_member_id = member_id + end +end function Issue:get_state_name_for_state(value) @@ -238,4 +290,8 @@ state_names[#state_names+1] = Issue:get_state_name_for_state(state) end return table.concat(state_names, ", ") +end + +function Issue.object_get:etherpad_url() + return config.etherpad.base_url .. "p/" .. config.etherpad.group_id .. "$Issue" .. self.id end \ No newline at end of file diff -r 9d463368e0d0 -r 63d6549cc00b model/member.lua --- a/model/member.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/model/member.lua Fri May 18 19:07:07 2012 +0200 @@ -493,3 +493,12 @@ :for_share() :exec()) and true or false end + +function Member.object:get_delegatee_member(unit_id, area_id, issue_id) + local selector = Member:new_selector() + if unit_id then + selector:join("delegation", nil, { "delegation.trustee_id = member.id AND delegation.scope = 'unit' AND delegation.unit_id = ? AND delegation.truster_id = ?", unit_id, self.id }) + end + selector:optional_object_mode() + return selector:exec() +end \ No newline at end of file diff -r 9d463368e0d0 -r 63d6549cc00b model/unit.lua --- a/model/unit.lua Tue Apr 17 00:07:04 2012 +0200 +++ b/model/unit.lua Fri May 18 19:07:07 2012 +0200 @@ -21,6 +21,61 @@ ref = 'members' } +Unit:add_reference{ + mode = "11", + to = mondelefant.class_prototype, + this_key = "id", + that_key = "unit_id", + ref = "delegation_info", + back_ref = "unit", + selector_generator = function(list, options) + assert(options.member_id, "member_id mandatory for delegation_info") + local ids = { sep = ", " } + for i, object in ipairs(list) do + local id = object.id + if id ~= nil then + ids[#ids+1] = {"?", id} + end + end + local sub_selector = Unit:get_db_conn():new_selector() + if #ids == 0 then + return sub_selector:empty_list_mode() + end + sub_selector:from("unit") + sub_selector:add_field("unit.id", "unit_id") + sub_selector:add_field{ '(delegation_info(?, unit.id, null, null)).*', options.member_id } + sub_selector:add_where{ 'unit.id IN ($)', ids } + + local selector = Unit:get_db_conn():new_selector() + selector:add_from(sub_selector, "delegation_info") + selector:left_join("member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id") + selector:left_join("member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id") + selector:add_field("delegation_info.*") + selector:add_field("first_trustee.name", "first_trustee_name") + selector:add_field("other_trustee.name", "other_trustee_name") + return selector + end +} + +function Unit.list:load_delegation_info_once_for_member_id(member_id) + if self._delegation_info_loaded_for_member_id ~= member_id then + self:load("delegation_info", { member_id = member_id }) + for i, unit in ipairs(self) do + unit._delegation_info_loaded_for_member_id = member_id + end + self._delegation_info_loaded_for_member_id = member_id + end +end + +function Unit.object:load_delegation_info_once_for_member_id(member_id) + if self._delegation_info_loaded_for_member_id ~= member_id then + self:load("delegation_info", { member_id = member_id }) + self._delegation_info_loaded_for_member_id = member_id + end +end + + + function recursive_add_child_units(units, parent_unit) parent_unit.childs = {} for i, unit in ipairs(units) do diff -r 9d463368e0d0 -r 63d6549cc00b static/style.css --- a/static/style.css Tue Apr 17 00:07:04 2012 +0200 +++ b/static/style.css Fri May 18 19:07:07 2012 +0200 @@ -179,6 +179,7 @@ font-weight: bold; } +.topbar .instance_name, .topbar a { color: #eee; line-height: 30px; @@ -194,12 +195,13 @@ line-height: 200%; } -.navigation img { +.topbar img { margin-right: 0.5em; vertical-align: middle; } -.navigation a { +.topbar a, +.topbar .member_menu span { padding: 0 0.5em; float: left; display: block; @@ -210,79 +212,159 @@ display: inline; } -.topbar .member_info { +.topbar .navigation_right { float: right; padding-right: 1%; } +.member_menu { + float: right; +} + +#member_menu { + position: absolute; + right: 20px; + top: 19px; +} + +#member_menu { + display: none; +} + +.member_menu:hover #member_menu { + display: block; +} + +#member_menu ul { + list-style: none; +} + +#member_menu li span { + background-color: #333; + line-height: 200%; + display: block; + width: 15em; + color: #fff; +} + + + +#member_menu li a { + background-color: #333; + line-height: 200%; + display: block; + width: 15em; +} + +#member_menu a:hover { + background-color: #eee; + color: #000; +} + + /************************************************************************* * Title of current page including path and actions */ -.title, -.title2, -.actions { - background-color: #f2f2f2; - margin-left: 1%; - margin-right: 1%; - border-left: 1px solid #bbb; - border-right: 1px solid #bbb; +.slot_title { + font-size: 120%; + font-weight: bold; + margin-left: 10px; + margin-right: 10px; + margin-top: 1ex; +} + +.slot_actions { + margin-left: 10px; + margin-top: 0.5ex; + margin-bottom: 1ex; +} + +.page_head { + background-color: #fff; + margin: 0px 10px 0 10px; + border: 1px solid #aaa; + border-radius: 0 0 8px 8px; + box-shadow: #777 0px 5px 5px -5px; } -.actions { - border-bottom: 1px solid #bbb; + +.page_head .area_head, +.page_head .issue { + border-top: 1px solid #000; } -.initiative_head .actions { - border: none; - box-shadow: none; - -moz-box-shadow: none; - -webkit-box-shadow: none; +.page_head .unit_head .title, +.page_head .area_head .title, +.issue .context, +.issue .title, +.initiative_head .title { + margin: 8px; +} + +.page_head .unit_head .content, +.page_head .area_head .content, +.issue .content, +.initiative_head .content { + margin: 0px 8px 8px 8px; +} + +.issue .content.actions { + margin-bottom: 2.5ex; } -.slot_initiatives_list { - margin-top: 1ex; - margin-left: 1%; - margin-right: 1%; - background-color: #fcfcfc; - border-radius: 8px; - clear: left; - border: 1px solid #aaa; - padding-top: 1ex; - padding-bottom: 1ex; + +.page_head .unit_head .title, +.page_head .area_head .title, +.issue .title, +.initiative_head .title { + font-weight: bold; + font-size: 120%; } -.title { - box-shadow: inset #888 0px 5px 6px -5px; - -moz-box-shadow: inset #888 0px 5px 6px -5px;; - -webkit-box-shadow: inset #888 0px 5px 6px -5px;; +.page_head .unit_head .title .extra, +.page_head .area_head .title .extra, +.issue .title .extra { + margin-left: 0.7em; + font-size: 75%; +} + + +.initiative_head { + margin-top: 10px; } -.title { - color: #000; - padding: 1.5ex 1ex 0 1ex; + +.delegation_info { + float: right; + text-decoration: none; + padding: 5px; + border-radius: 0px 5px 0px 5px; } -.title div { - font-size: 125%; - line-height: 110%; +.delegation_arrow { + vertical-align: middle; } -.title a { - color: #000; +.delegation_info .link { + text-decoration: underline; + color: #aaa; +} + +.delegation_info:hover { + background-color: #ddd; } -.title .member_image { - margin-right: 0.7em; - vertical-align: middle; - border-radius: 7px; +.delegation_info .micro_avatar { + border: 2px solid #fff; } -.slot_title2 { - padding: 1ex 1ex 0 1ex; +.delegation_info .micro_avatar.highlighted { + border: 2px solid #fa0; } + .member_list .member_image_avatar { float: left; margin-right: 0.5em; @@ -294,66 +376,6 @@ vertical-align: middle; } -.actions { - font-size: 75%; - line-height: 220%; - padding-top: 2ex; - padding-bottom: 1ex; -} - -.actions { - border-radius: 0 0 8px 8px; -} - -.actions .interest, -.actions .delegation, -.actions a { - margin-left: 1ex; -} - -.actions a { - margin-top: 1px; - margin-bottom: 1px; -} - -.actions .interest a, -.actions .delegation a { - margin: 0; -} - -.initiative_head .actions { - background-color: #fff; - margin: 0px; -} - -.actions a { - padding-right: 0.3em; -} - -.slot_initiative_head { - margin-left: 1%; - margin-right: 1%; - margin-top: 2ex; -} - -.initiative_name { - font-weight: bold; - font-size: 125%; -} -.actions a { - float: left; -} - -.actions a:hover { - background-color: #d7d7d7; -} - -.actions img { - padding-left: 0.2em; - padding-right: 0.2em; - vertical-align: middle; -} - .logo { float: right; margin-right: 1%; @@ -365,153 +387,6 @@ } /************************************************************************* - * vote info / delegation - */ - -.interest, -.slot_support, -.delegation { - float: left; - position: relative; - z-index: 1; -} - -.interest img, -.slot_support img, -.delegation img { - padding-left: 0.2em; - padding-right: 0.2em; -} -.actions .supporter, -.actions .potential_supporter, -.vote_info .head { - float: left; -} - -.actions .supporter, -.actions .potential_supporter, -.actions .interest .head { - padding-right: 0.3em; -} - -.delegation .head_active, -.interest .head_active, -.actions .supporter, -.actions .potential_supporter { - border-radius: 5px; - border: 1px solid #5f6675; -} - -.delegation .head_active, -.interest .head_active { - background-color: #cdf; -} - -.actions .supporter { - background-color: #cdf; -} - -.actions .potential_supporter { - background-color: #cdf; -} - -.slot_support .head_initiator { - background-color: #f2f2f2; - border-radius: 5px; -} - -.delegation .change_delegation { - margin-bottom: 2ex; -} - -.delegation .change_delegation a { - display: inline; - float: none; - padding: 1ex; -} - -.delegation .delegation_participation { - margin-left: 20.5em; - margin-top: 3ex; - font-style: italic; - font-size: 80%; -} - -.slot_actions .change_delegation { - float: left; -} - -.vote_info .close { - position: absolute; - top: 0; - right: 0; - padding: 1ex; - display: block; -} - -.vote_info .content { - font-size: 133%; - line-height: 100%; - top: 2.8ex; - display: none; - position: absolute; - z-index: 10; - background-color: #cdf; - border-radius: 0 5px 5px 5px; - padding: 1em; - width: 35em; - border: 1px solid #5f6675; - border-top: none; -} - -.delegation_arrow { - vertical-align: middle; -} - -.vote_info .delegation_arrow { - margin-top: 1ex; - margin-bottom: 1ex; -} - -.vote_info .delegation_arrow_overridden { - opacity: 0.4; -} - -.vote_info .delegation_scope_overridden { - color: #777; -} - -.vote_info .delegation_scope { - display: inline; -} - -.vote_info .delegation_info { -} - -.vote_info a { - padding-right: 0; -} - -.vote_info .member_thumb { - clear: left; - background: #fff; -} - -.delegation_overridden .member_thumb { - opacity: 0.4; -} - -.delegation .revoke { - margin: 0.5ex; - float: right; -} - -.delegation .revoke img { - vertical-align: middle; -} - - -/************************************************************************* * Main content */ @@ -1000,26 +875,26 @@ } .issues .issue { + margin-top: 10px; background-color: #fcfcfc; overflow: hidden; - margin-bottom: 2ex; border: 1px solid #aaa; border-radius: 8px; } -.issues .issue.interested, -.issues .issue.interest_by_delegation { +.issue.interested, +.issue.interest_by_delegation { border: 1px solid #b2cdff; } -.issues .issue .issue_info { +.issue .issue_info { padding: 1ex 1ex 0.3ex 1ex; line-height: 140%; margin-bottom: 1ex; } -.issues .issue.interested .issue_info, -.issues .issue.interested_by_delegation .issue_info { +.issue.interested .issue_info, +.issue.interested_by_delegation .issue_info { background-color: #dfeaff; background-image: linear-gradient(top, #dfeaff 0%, #fcfcfc 66%); background-image: -o-linear-gradient(top, #dfeaff 0%, #fcfcfc 66%); @@ -1029,11 +904,11 @@ } .event_list .event .issue_id, -.issues .issue .issue_info .issue_id { +.issue .issue_info .issue_id { font-size: 125%; } -.issues .issue .suggestion { +.issue .suggestion { margin-left: 1ex; margin-bottom: 1ex; font-weight: bold; @@ -1051,11 +926,11 @@ vertical-align: middle; } -.issues .issue .interest_by_delegation { +.issue .interest_by_delegation { float: right; } -.issues .issue .initiative_list a { +.issue .initiative_list a.highlighted { font-weight: bold; } @@ -1111,7 +986,7 @@ margin-bottom: 1ex; } -.issues tr tr { +.issue tr tr { border: none; background: none; } @@ -1311,10 +1186,10 @@ .public_access_issue_head { background-color: #fffbce; padding: 1ex; - margin-top: 2ex; + margin-top: 1ex; margin-bottom: 2ex; - border-radius: 8px; - border: 1px solid #ffe900; + border-top: 1px solid #ffe900; + border-bottom: 1px solid #ffe900; } .suggestion_fulfilled { @@ -1492,7 +1367,7 @@ cursor: pointer; } -#voting .grabber { +#voting .movable { vertical-align: middle; cursor: move; } @@ -1547,10 +1422,13 @@ /* shadows */ -.box, -.slot_initiative_head { +.initiative_head, +.box { border: 1px solid #aaa; border-radius: 8px; +} + +.box { padding: 1ex; } @@ -1560,8 +1438,6 @@ } .slot_initiatives_list, -.actions, -.issues .issue, .ui_tabs_links a, .draft_content, .help, @@ -1570,11 +1446,11 @@ .ui_filter a.active, .vote_info .content, .member_area_list, -.box, -.slot_initiative_head { +.box { box-shadow: #777 0px 5px 5px -5px; -mox-box-shadow: #777 0px 5px 5px -5px; -webkit-box-shadow: #777 0px 5px 5px -5px; + clear: both; } .member_area_list .box {