bsw@1045: local initiative = Initiative:by_id ( param.get_id() )
bsw@1045: local member = app.session.member
bsw@1045:
bsw@1045: if not initiative then
bsw@1045: execute.view { module = "index", view = "404" }
bsw@1045: request.set_status("404 Not Found")
bsw@1045: return
bsw@1045: end
bsw@1045:
bsw@1045: local issue_info
bsw@1045:
bsw@1045: if member then
bsw@1045: initiative:load_everything_for_member_id(member.id)
bsw@1045: initiative.issue:load_everything_for_member_id(member.id)
bsw@1045: issue_info = initiative.issue.member_info
bsw@1045: end
bsw@1045:
bsw@1045: execute.view {
bsw@1045: module = "issue", view = "_head",
bsw@1045: params = {
bsw@1045: issue = initiative.issue,
bsw@1045: initiative = initiative,
bsw@1045: member = app.session.member
bsw@1045: }
bsw@1045: }
bsw@1045:
bsw@1045: if app.session.member_id then
bsw@1045: direct_supporter = initiative.issue.member_info.own_participation and initiative.member_info.supported
bsw@1045: end
bsw@718:
bsw@1045: ui.script { script = [[
bsw@1045: function showTab(tabId) {
bsw@1045: $('.tab').hide();
bsw@1045: $('.main').hide();
bsw@1045: $('.main, .slot_extra .section').hide();
bsw@1045: $('.' + tabId).show();
bsw@1045: if (tabId == "main") $('.slot_extra .section').show();
bsw@1045: };
bsw@1045: showTab('main');
bsw@1045: ]]}
bsw@1045:
bsw@1045: execute.view{ module = "issue", view = "_sidebar_state", params = {
bsw@1045: initiative = initiative
bsw@1045: } }
bsw@1045:
bsw@1045: execute.view {
bsw@1045: module = "issue", view = "_sidebar_issue",
bsw@1045: params = {
bsw@1045: issue = initiative.issue,
bsw@1045: highlight_initiative_id = initiative.id
bsw@1045: }
bsw@1045: }
bsw@1045:
bsw@1045: execute.view {
bsw@1045: module = "issue", view = "_sidebar_whatcanido",
bsw@1045: params = { initiative = initiative }
bsw@1045: }
bsw@1045:
bsw@1045: execute.view {
bsw@1045: module = "issue", view = "_sidebar_members", params = {
bsw@1045: issue = initiative.issue, initiative = initiative
bsw@718: }
bsw@718: }
bsw@1045:
bsw@1045: ui.section( function ()
bsw@1045: execute.view{
bsw@1045: module = "initiative", view = "_head", params = {
bsw@1045: initiative = initiative
bsw@1045: }
bsw@1045: }
bsw@1045:
bsw@1045: if direct_supporter and not initiative.issue.closed then
bsw@1045: local supporter = app.session.member:get_reference_selector("supporters")
bsw@1045: :add_where{ "initiative_id = ?", initiative.id }
bsw@1045: :optional_object_mode()
bsw@1045: :exec()
bsw@1045:
bsw@1045: if supporter then
bsw@1045:
bsw@1045: local old_draft_id = supporter.draft_id
bsw@1045: local new_draft_id = initiative.current_draft.id
bsw@1045:
bsw@1045: if old_draft_id ~= new_draft_id then
bsw@1045: ui.sectionRow( "draft_updated_info", function ()
bsw@1045: ui.container{
bsw@1045: attr = { class = "info" },
bsw@1045: content = _"The draft of this initiative has been updated!"
bsw@1045: }
bsw@1045: slot.put(" ")
bsw@1045: ui.link{
bsw@1045: content = _"show differences",
bsw@1045: module = "draft",
bsw@1045: view = "diff",
bsw@1045: params = {
bsw@1045: old_draft_id = old_draft_id,
bsw@1045: new_draft_id = new_draft_id
bsw@1045: }
bsw@1045: }
bsw@1045: if not initiative.revoked then
bsw@1045: slot.put(" | ")
bsw@1045: ui.link{
bsw@1045: text = _"refresh my support",
bsw@1045: module = "initiative",
bsw@1045: action = "add_support",
bsw@1045: id = initiative.id,
bsw@1045: params = { draft_id = initiative.current_draft.id },
bsw@1045: routing = {
bsw@1045: default = {
bsw@1045: mode = "redirect",
bsw@1045: module = "initiative",
bsw@1045: view = "show",
bsw@1045: id = initiative.id
bsw@1045: }
bsw@1045: }
bsw@1045: }
bsw@1045: slot.put(" | ")
bsw@1045: end
bsw@1045:
bsw@1045: ui.link{
bsw@1045: text = _"remove my support",
bsw@1045: module = "initiative",
bsw@1045: action = "remove_support",
bsw@1045: id = initiative.id,
bsw@1045: routing = {
bsw@1045: default = {
bsw@1045: mode = "redirect",
bsw@1045: module = "initiative",
bsw@1045: view = "show",
bsw@1045: id = initiative.id
bsw@1045: }
bsw@1045: }
bsw@1045: }
bsw@1045:
bsw@1045: end )
bsw@1045: end
bsw@1045: end
bsw@1045: end
bsw@1045:
bsw@1045:
bsw@1045: ui.sectionRow( function ()
bsw@1045: ui.container {
bsw@1045: attr = { class = "draft" },
bsw@1045: content = function ()
bsw@1045: slot.put ( initiative.current_draft:get_content ( "html" ) )
bsw@1045: end
bsw@1045: }
bsw@1045: end )
bsw@1045:
bsw@1045: end)
bsw@1045:
bsw@1045: ui.link { attr = { name = "suggestions" }, text = "" }
bsw@1045:
bsw@1045:
bsw@1045: ui.container {
bsw@1045: attr = { class = "section suggestions" },
bsw@1045: content = function ()
bsw@1045:
bsw@1045: if # ( initiative.suggestions ) > 0 then
bsw@1045:
bsw@1045: ui.sectionHead( function ()
bsw@1045: ui.heading {
bsw@1045: level = 1,
bsw@1045: content = _("Suggestions for improvement (#{count})", { count = # ( initiative.suggestions ) } )
bsw@1045: }
bsw@1045: ui.container { content = _"written and rated by the supportes of this initiative to improve the proposal and its reasons" }
bsw@1045: end )
bsw@1045:
bsw@1045: for i, suggestion in ipairs(initiative.suggestions) do
bsw@1045:
bsw@1045: local opinion = Opinion:by_pk(app.session.member_id, suggestion.id)
bsw@1045:
bsw@1045: local class = "sectionRow suggestion"
bsw@1045: if suggestion.id == param.get("suggestion_id", atom.number) then
bsw@1045: class = class .. " highlighted"
bsw@1045: end
bsw@1045: if member and not initiative.issue.fully_frozen and not initiative.issue.closed and initiative.member_info.supported then
bsw@1045: class = class .. " rateable"
bsw@1045: end
bsw@1045:
bsw@1045:
bsw@1045: ui.tag { tag = "div", attr = { class = class, id = "s" .. suggestion.id }, content = function ()
bsw@1045:
bsw@1045: if opinion then
bsw@1045:
bsw@1045: ui.container { attr = { class = "opinion"}, content = function()
bsw@1045: local class = ""
bsw@1045: local text = ""
bsw@1045:
bsw@1045: if opinion.degree == 2 then
bsw@1045: class = "must"
bsw@1045: text = _"must"
bsw@1045: elseif opinion.degree == 1 then
bsw@1045: class = "should"
bsw@1045: text = _"should"
bsw@1045: elseif opinion.degree == 0 then
bsw@1045: class = "neutral"
bsw@1045: text = _"neutral"
bsw@1045: elseif opinion.degree == -1 then
bsw@1045: class = "shouldnot"
bsw@1045: text = _"should not"
bsw@1045: elseif opinion.degree == -2 then
bsw@1045: class = "mustnot"
bsw@1045: text = _"must not"
bsw@1045: end
bsw@1045:
bsw@1045: ui.tag {
bsw@1045: attr = { class = class },
bsw@1045: content = text
bsw@1045: }
bsw@1045:
bsw@1045: slot.put ( " " )
bsw@1045:
bsw@1045: if
bsw@1045: (opinion.degree > 0 and not opinion.fulfilled)
bsw@1045: or (opinion.degree < 0 and opinion.fulfilled)
bsw@1045: then
bsw@1045: ui.tag{ content = _"but" }
bsw@1045: else
bsw@1045: ui.tag{ content = _"and" }
bsw@1045: end
bsw@1045:
bsw@1045: slot.put ( " " )
bsw@1045:
bsw@1045: local class = ""
bsw@1045: local text = ""
bsw@1045:
bsw@1045: if opinion.fulfilled then
bsw@1045: class = "implemented"
bsw@1045: text = _"is implemented"
bsw@1045: else
bsw@1045: class = "notimplemented"
bsw@1045: text = _"is not implemented"
bsw@1045: end
bsw@1045:
bsw@1045: ui.tag {
bsw@1045: attr = { class = class },
bsw@1045: content = text
bsw@1045: }
bsw@1045:
bsw@1045: if
bsw@1045: (opinion.degree > 0 and not opinion.fulfilled)
bsw@1045: or (opinion.degree < 0 and opinion.fulfilled)
bsw@1045: then
bsw@1045: if math.abs(opinion.degree) > 1 then
bsw@1045: slot.put(" !!")
bsw@1045: else
bsw@1045: slot.put(" !")
bsw@1045: end
bsw@1045: else
bsw@1045: slot.put(" ✓")
bsw@1045: end
bsw@1045:
bsw@1045: end }
bsw@1045:
bsw@1045: end
bsw@1045:
bsw@1045:
bsw@1045: ui.link { attr = { name = "s" .. suggestion.id }, text = "" }
bsw@1045: ui.heading { level = 2,
bsw@1045: attr = { class = "suggestionHead" },
bsw@1045: content = format.string(suggestion.name, {
bsw@1045: truncate_at = 160, truncate_suffix = true
bsw@1045: }) }
bsw@1045:
bsw@1045:
bsw@1045: local plus2 = (suggestion.plus2_unfulfilled_count or 0)
bsw@1045: + (suggestion.plus2_fulfilled_count or 0)
bsw@1045: local plus1 = (suggestion.plus1_unfulfilled_count or 0)
bsw@1045: + (suggestion.plus1_fulfilled_count or 0)
bsw@1045: local minus1 = (suggestion.minus1_unfulfilled_count or 0)
bsw@1045: + (suggestion.minus1_fulfilled_count or 0)
bsw@1045: local minus2 = (suggestion.minus2_unfulfilled_count or 0)
bsw@1045: + (suggestion.minus2_fulfilled_count or 0)
bsw@1045:
bsw@1045: local with_opinion = plus2 + plus1 + minus1 + minus2
bsw@1045:
bsw@1045: local neutral = (suggestion.initiative.supporter_count or 0)
bsw@1045: - with_opinion
bsw@1045:
bsw@1045: local neutral2 = with_opinion
bsw@1045: - (suggestion.plus2_fulfilled_count or 0)
bsw@1045: - (suggestion.plus1_fulfilled_count or 0)
bsw@1045: - (suggestion.minus1_fulfilled_count or 0)
bsw@1045: - (suggestion.minus2_fulfilled_count or 0)
bsw@1045:
bsw@1045: ui.container {
bsw@1045: attr = { class = "suggestionInfo" },
bsw@1045: content = function ()
bsw@1045:
bsw@1045: if with_opinion > 0 then
bsw@1045: ui.container { attr = { class = "suggestion-rating" }, content = function ()
bsw@1045: ui.tag { content = _"collective rating:" }
bsw@1045: slot.put(" ")
bsw@1045: ui.bargraph{
bsw@1045: max_value = suggestion.initiative.supporter_count,
bsw@1045: width = 100,
bsw@1045: bars = {
bsw@1045: { color = "#0a0", value = plus2 },
bsw@1045: { color = "#8a8", value = plus1 },
bsw@1045: { color = "#eee", value = neutral },
bsw@1045: { color = "#a88", value = minus1 },
bsw@1045: { color = "#a00", value = minus2 },
bsw@1045: }
bsw@1045: }
bsw@1045: slot.put(" | ")
bsw@1045: ui.tag { content = _"implemented:" }
bsw@1045: slot.put ( " " )
bsw@1045: ui.bargraph{
bsw@1045: max_value = with_opinion,
bsw@1045: width = 100,
bsw@1045: bars = {
bsw@1045: { color = "#0a0", value = suggestion.plus2_fulfilled_count },
bsw@1045: { color = "#8a8", value = suggestion.plus1_fulfilled_count },
bsw@1045: { color = "#eee", value = neutral2 },
bsw@1045: { color = "#a88", value = suggestion.minus1_fulfilled_count },
bsw@1045: { color = "#a00", value = suggestion.minus2_fulfilled_count },
bsw@1045: }
bsw@1045: }
bsw@1045: end }
bsw@1045: end
bsw@1045:
bsw@1045: if app.session:has_access("authors_pseudonymous") then
bsw@1045: util.micro_avatar ( suggestion.author )
bsw@1045: else
bsw@1045: slot.put("
")
bsw@1045: end
bsw@1045:
bsw@1045: ui.container {
bsw@1045: attr = { class = "suggestion-text" },
bsw@1045: content = function ()
bsw@1045: slot.put ( suggestion:get_content( "html" ) )
bsw@1045:
bsw@1045: if direct_supporter then
bsw@1045:
bsw@1045: ui.container {
bsw@1045: attr = { class = "rating" },
bsw@1045: content = function ()
bsw@1045:
bsw@1045: if not opinion then
bsw@1045: opinion = {}
bsw@1045: end
bsw@1045: ui.form {
bsw@1045: module = "opinion", action = "update", params = {
bsw@1045: suggestion_id = suggestion.id
bsw@1045: },
bsw@1045: routing = { default = {
bsw@1045: mode = "redirect",
bsw@1045: module = "initiative", view = "show", id = suggestion.initiative_id,
bsw@1045: params = { suggestion_id = suggestion.id },
bsw@1045: anchor = "s" .. suggestion.id -- TODO webmcp
bsw@1045: } },
bsw@1045: content = function ()
bsw@1045:
bsw@1045:
bsw@1045: ui.heading { level = 3, content = _"Should the initiator implement this suggestion?" }
bsw@1045: ui.container { content = function ()
bsw@1045:
bsw@1045: local active = opinion.degree == 2
bsw@1045: ui.tag { tag = "input", attr = {
bsw@1045: type = "radio", name = "degree", value = 2,
bsw@1045: id = "s" .. suggestion.id .. "_degree2",
bsw@1045: checked = active and "checked" or nil
bsw@1045: } }
bsw@1045: ui.tag {
bsw@1045: tag = "label",
bsw@1045: attr = {
bsw@1045: ["for"] = "s" .. suggestion.id .. "_degree2",
bsw@1045: class = active and "active-plus2" or nil,
bsw@1045: },
bsw@1045: content = _"must"
bsw@1045: }
bsw@1045:
bsw@1045: local active = opinion.degree == 1
bsw@1045: ui.tag { tag = "input", attr = {
bsw@1045: type = "radio", name = "degree", value = 1,
bsw@1045: id = "s" .. suggestion.id .. "_degree1",
bsw@1045: checked = active and "checked" or nil
bsw@1045: } }
bsw@1045: ui.tag {
bsw@1045: tag = "label",
bsw@1045: attr = {
bsw@1045: ["for"] = "s" .. suggestion.id .. "_degree1",
bsw@1045: class = active and "active-plus1" or nil,
bsw@1045: },
bsw@1045: content = _"should"
bsw@1045: }
bsw@1045:
bsw@1045: local active = not opinion.member_id
bsw@1045: ui.tag { tag = "input", attr = {
bsw@1045: type = "radio", name = "degree", value = 0,
bsw@1045: id = "s" .. suggestion.id .. "_degree0",
bsw@1045: checked = active and "checked" or nil
bsw@1045: } }
bsw@1045: ui.tag {
bsw@1045: tag = "label",
bsw@1045: attr = {
bsw@1045: ["for"] = "s" .. suggestion.id .. "_degree0",
bsw@1045: class = active and "active-neutral" or nil,
bsw@1045: },
bsw@1045: content = _"neutral"
bsw@1045: }
bsw@1045:
bsw@1045: local active = opinion.degree == -1
bsw@1045: ui.tag { tag = "input", attr = {
bsw@1045: type = "radio", name = "degree", value = -1,
bsw@1045: id = "s" .. suggestion.id .. "_degree-1",
bsw@1045: checked = active and "checked" or nil
bsw@1045: } }
bsw@1045: ui.tag {
bsw@1045: tag = "label",
bsw@1045: attr = {
bsw@1045: ["for"] = "s" .. suggestion.id .. "_degree-1",
bsw@1045: class = active and "active-minus1" or nil,
bsw@1045: },
bsw@1045: content = _"should not"
bsw@1045: }
bsw@1045:
bsw@1045: local active = opinion.degree == -2
bsw@1045: ui.tag { tag = "input", attr = {
bsw@1045: type = "radio", name = "degree", value = -2,
bsw@1045: id = "s" .. suggestion.id .. "_degree-2",
bsw@1045: checked = active and "checked" or nil
bsw@1045: } }
bsw@1045: ui.tag {
bsw@1045: tag = "label",
bsw@1045: attr = {
bsw@1045: ["for"] = "s" .. suggestion.id .. "_degree-2",
bsw@1045: class = active and "active-minus2" or nil,
bsw@1045: },
bsw@1045: content = _"must not"
bsw@1045: }
bsw@1045: end }
bsw@1045:
bsw@1045: slot.put("
")
bsw@1045:
bsw@1045: ui.heading { level = 3, content = _"Did the initiator implement this suggestion?" }
bsw@1045: ui.container { content = function ()
bsw@1045: local active = opinion.fulfilled == false
bsw@1045: ui.tag { tag = "input", attr = {
bsw@1045: type = "radio", name = "fulfilled", value = "false",
bsw@1045: id = "s" .. suggestion.id .. "_notfulfilled",
bsw@1045: checked = active and "checked" or nil
bsw@1045: } }
bsw@1045: ui.tag {
bsw@1045: tag = "label",
bsw@1045: attr = {
bsw@1045: ["for"] = "s" .. suggestion.id .. "_notfulfilled",
bsw@1045: class = active and "active-notfulfilled" or nil,
bsw@1045: },
bsw@1045: content = _"No (not yet)"
bsw@1045: }
bsw@1045:
bsw@1045: local active = opinion.fulfilled
bsw@1045: ui.tag { tag = "input", attr = {
bsw@1045: type = "radio", name = "fulfilled", value = "true",
bsw@1045: id = "s" .. suggestion.id .. "_fulfilled",
bsw@1045: checked = active and "checked" or nil
bsw@1045: } }
bsw@1045: ui.tag {
bsw@1045: tag = "label",
bsw@1045: attr = {
bsw@1045: ["for"] = "s" .. suggestion.id .. "_fulfilled",
bsw@1045: class = active and "active-fulfilled" or nil,
bsw@1045: },
bsw@1045: content = _"Yes, it's implemented"
bsw@1045: }
bsw@1045: end }
bsw@1045: slot.put("
")
bsw@1045:
bsw@1045: ui.tag{
bsw@1045: tag = "input",
bsw@1045: attr = {
bsw@1045: type = "submit",
bsw@1045: class = "btn btn-default",
bsw@1045: value = _"publish my rating"
bsw@1045: },
bsw@1045: content = ""
bsw@1045: }
bsw@1045:
bsw@1045: end
bsw@1045: }
bsw@1045:
bsw@1045: end -- if not issue,fully_frozen or closed
bsw@1045: }
bsw@1045: end
bsw@1045:
bsw@1045: local text = _"Read more"
bsw@1045:
bsw@1045: if direct_supporter then
bsw@1045: text = _"Show more and rate this"
bsw@1045: end
bsw@1045:
bsw@1045: ui.link {
bsw@1045: attr = {
bsw@1045: class = "suggestion-more",
bsw@1045: onclick = "$('#s" .. suggestion.id .. "').removeClass('folded').addClass('unfolded'); return false;"
bsw@1045: },
bsw@1045: text = text
bsw@1045: }
bsw@1045:
bsw@1045: ui.link {
bsw@1045: attr = {
bsw@1045: class = "suggestion-less",
bsw@1045: onclick = "$('#s" .. suggestion.id .. "').addClass('folded').removeClass('unfolded'); return false;"
bsw@1045: },
bsw@1045: text = _"Show less"
bsw@1045: }
bsw@1045: end
bsw@1045: }
bsw@1045:
bsw@1045: ui.script{ script = [[
bsw@1045: var textEl = $('#s]] .. suggestion.id .. [[ .suggestion-text');
bsw@1045: var height = textEl.height();
bsw@1045: if (height > 150) $('#s]] .. suggestion.id .. [[').addClass('folded');
bsw@1045: ]] }
bsw@1045:
bsw@1045: end
bsw@1045: } -- ui.paragraph
bsw@1045:
bsw@1045:
bsw@1045:
bsw@1045: end } -- ui.tag "li"
bsw@1045:
bsw@1045: end -- for i, suggestion
bsw@1045:
bsw@1045: else -- if #initiative.suggestions > 0
bsw@1045:
bsw@1045: local text
bsw@1045: if initiative.issue.closed then
bsw@1045: text = "No suggestions"
bsw@1045: else
bsw@1045: text = "No suggestions (yet)"
bsw@1045: end
bsw@1045: ui.sectionHead( function()
bsw@1045: ui.heading { level = 1, content = text }
bsw@1045: end)
bsw@1045:
bsw@1045: end -- if #initiative.suggestions > 0
bsw@1045:
bsw@1045: end
bsw@1045: }