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@1145: local direct_supporter
bsw@1145: 
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@1061:                   
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@1061:                 ui.link{
bsw@1061:                   attr = { class = "suggestion-details" },
bsw@1061:                   content = _"Details",
bsw@1061:                   module = "suggestion", view = "show", id = suggestion.id
bsw@1061:                 }
bsw@1061: 
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@1125:         text = _"No suggestions"
bsw@1045:       else
bsw@1125:         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: }