liquid_feedback_frontend
view app/main/initiative/show.lua @ 1092:5b65ea5c24f5
Fixed free timings in poll mode
| author | bsw | 
|---|---|
| date | Fri Oct 17 13:03:31 2014 +0200 (2014-10-17) | 
| parents | 7188f8a45b3d | 
| children | 71eb36b43e76 | 
 line source
     1 local initiative = Initiative:by_id ( param.get_id() )
     2 local member = app.session.member
     4 if not initiative then
     5   execute.view { module = "index", view = "404" }
     6   request.set_status("404 Not Found")
     7   return
     8 end
    10 local issue_info
    12 if member then
    13   initiative:load_everything_for_member_id(member.id)
    14   initiative.issue:load_everything_for_member_id(member.id)
    15   issue_info = initiative.issue.member_info
    16 end
    18 execute.view {
    19   module = "issue", view = "_head", 
    20   params = {
    21     issue = initiative.issue,
    22     initiative = initiative,
    23     member = app.session.member
    24   }
    25 }
    27 if app.session.member_id then
    28   direct_supporter = initiative.issue.member_info.own_participation and initiative.member_info.supported
    29 end
    31 ui.script { script = [[
    32   function showTab(tabId) {
    33     $('.tab').hide();
    34     $('.main').hide();
    35     $('.main, .slot_extra .section').hide();
    36     $('.' + tabId).show();
    37     if (tabId == "main") $('.slot_extra .section').show();
    38   };
    39   showTab('main');
    40 ]]}
    42 execute.view{ module = "issue", view = "_sidebar_state", params = {
    43   initiative = initiative
    44 } }
    46 execute.view { 
    47   module = "issue", view = "_sidebar_issue", 
    48   params = {
    49     issue = initiative.issue,
    50     highlight_initiative_id = initiative.id
    51   }
    52 }
    54 execute.view {
    55   module = "issue", view = "_sidebar_whatcanido",
    56   params = { initiative = initiative }
    57 }
    59 execute.view { 
    60   module = "issue", view = "_sidebar_members", params = {
    61     issue = initiative.issue, initiative = initiative
    62   }
    63 }
    65 ui.section( function ()
    66   execute.view{
    67     module = "initiative", view = "_head", params = {
    68       initiative = initiative
    69     }
    70   }
    72   if direct_supporter and not initiative.issue.closed then
    73     local supporter = app.session.member:get_reference_selector("supporters")
    74       :add_where{ "initiative_id = ?", initiative.id }
    75       :optional_object_mode()
    76       :exec()
    78     if supporter then
    80       local old_draft_id = supporter.draft_id
    81       local new_draft_id = initiative.current_draft.id
    83       if old_draft_id ~= new_draft_id then
    84         ui.sectionRow( "draft_updated_info", function ()
    85           ui.container{ 
    86             attr = { class = "info" },
    87             content = _"The draft of this initiative has been updated!"
    88           }
    89           slot.put(" ")
    90           ui.link{
    91             content = _"show differences",
    92             module = "draft",
    93             view = "diff",
    94             params = {
    95               old_draft_id = old_draft_id,
    96               new_draft_id = new_draft_id
    97             }
    98           }
    99           if not initiative.revoked then
   100             slot.put(" | ")
   101             ui.link{
   102               text   = _"refresh my support",
   103               module = "initiative",
   104               action = "add_support",
   105               id     = initiative.id,
   106               params = { draft_id = initiative.current_draft.id },
   107               routing = {
   108                 default = {
   109                   mode = "redirect",
   110                   module = "initiative",
   111                   view = "show",
   112                   id = initiative.id
   113                 }
   114               }
   115             }
   116             slot.put(" | ")
   117           end
   119           ui.link{
   120             text   = _"remove my support",
   121             module = "initiative",
   122             action = "remove_support",
   123             id     = initiative.id,
   124             routing = {
   125               default = {
   126                 mode = "redirect",
   127                 module = "initiative",
   128                 view = "show",
   129                 id = initiative.id
   130               }
   131             }
   132           }
   134         end )
   135       end
   136     end
   137   end
   140   ui.sectionRow( function ()
   141     ui.container {
   142       attr = { class = "draft" },
   143       content = function ()
   144         slot.put ( initiative.current_draft:get_content ( "html" ) )
   145       end
   146     }
   147   end )
   149 end)
   151 ui.link { attr = { name = "suggestions" }, text = "" }
   154 ui.container {
   155   attr = { class = "section suggestions" },
   156   content = function ()
   158     if # ( initiative.suggestions ) > 0 then
   160       ui.sectionHead( function ()
   161         ui.heading { 
   162           level = 1, 
   163           content = _("Suggestions for improvement (#{count})", { count = # ( initiative.suggestions ) } ) 
   164         }
   165         ui.container { content = _"written and rated by the supportes of this initiative to improve the proposal and its reasons" }
   166       end )
   168       for i, suggestion in ipairs(initiative.suggestions) do
   170         local opinion = Opinion:by_pk(app.session.member_id, suggestion.id)
   172         local class = "sectionRow suggestion"
   173         if suggestion.id == param.get("suggestion_id", atom.number) then
   174           class = class .. " highlighted"
   175         end
   176         if member and not initiative.issue.fully_frozen and not initiative.issue.closed and initiative.member_info.supported then
   177           class = class .. " rateable"
   178         end
   181         ui.tag { tag = "div", attr = { class = class, id = "s" .. suggestion.id }, content = function ()
   183           if opinion then
   185             ui.container { attr = { class = "opinion"}, content = function()
   186               local class = ""
   187               local text = ""
   189               if opinion.degree == 2 then
   190                 class = "must"
   191                 text = _"must"
   192               elseif opinion.degree == 1 then
   193                 class = "should"
   194                 text = _"should"
   195               elseif opinion.degree == 0 then
   196                 class = "neutral"
   197                 text = _"neutral"
   198               elseif opinion.degree == -1 then
   199                 class = "shouldnot"
   200                 text = _"should not"
   201               elseif opinion.degree == -2 then
   202                 class = "mustnot"
   203                 text = _"must not"
   204               end
   206               ui.tag { 
   207                 attr = { class = class }, 
   208                 content = text 
   209               }
   211               slot.put ( " " )
   213               if 
   214                 (opinion.degree > 0 and not opinion.fulfilled)
   215                 or (opinion.degree < 0 and opinion.fulfilled)
   216               then
   217                 ui.tag{ content = _"but" }
   218               else
   219                 ui.tag{ content = _"and" }
   220               end
   222               slot.put ( " " )
   224               local class = ""
   225               local text = ""
   227               if opinion.fulfilled then
   228                 class = "implemented"
   229                 text = _"is implemented"
   230               else
   231                 class = "notimplemented"
   232                 text = _"is not implemented"
   233               end
   235               ui.tag { 
   236                 attr = { class = class }, 
   237                 content = text
   238               }
   240               if 
   241                 (opinion.degree > 0 and not opinion.fulfilled)
   242                 or (opinion.degree < 0 and opinion.fulfilled)
   243               then
   244                 if math.abs(opinion.degree) > 1 then
   245                   slot.put(" !!")
   246                 else
   247                   slot.put(" !")
   248                 end
   249               else
   250                 slot.put(" ✓")
   251               end
   253             end }
   255           end
   258           ui.link { attr = { name = "s" .. suggestion.id }, text = "" }
   259           ui.heading { level = 2, 
   260             attr = { class = "suggestionHead" },
   261             content = format.string(suggestion.name, {
   262             truncate_at = 160, truncate_suffix = true
   263           }) }
   266             local plus2  = (suggestion.plus2_unfulfilled_count or 0)
   267                             + (suggestion.plus2_fulfilled_count or 0)
   268             local plus1  = (suggestion.plus1_unfulfilled_count  or 0)
   269                             + (suggestion.plus1_fulfilled_count or 0)
   270             local minus1 = (suggestion.minus1_unfulfilled_count  or 0)
   271                             + (suggestion.minus1_fulfilled_count or 0)
   272             local minus2 = (suggestion.minus2_unfulfilled_count  or 0)
   273                             + (suggestion.minus2_fulfilled_count or 0)
   275             local with_opinion = plus2 + plus1 + minus1 + minus2
   277             local neutral = (suggestion.initiative.supporter_count or 0)
   278                             - with_opinion
   280             local neutral2 = with_opinion 
   281                               - (suggestion.plus2_fulfilled_count or 0)
   282                               - (suggestion.plus1_fulfilled_count or 0)
   283                               - (suggestion.minus1_fulfilled_count or 0)
   284                               - (suggestion.minus2_fulfilled_count or 0)
   286             ui.container { 
   287             attr = { class = "suggestionInfo" },
   288             content = function ()
   290               if with_opinion > 0 then
   291                 ui.container { attr = { class = "suggestion-rating" }, content = function ()
   292                   ui.tag { content = _"collective rating:" }
   293                   slot.put(" ")
   294                   ui.bargraph{
   295                     max_value = suggestion.initiative.supporter_count,
   296                     width = 100,
   297                     bars = {
   298                       { color = "#0a0", value = plus2 },
   299                       { color = "#8a8", value = plus1 },
   300                       { color = "#eee", value = neutral },
   301                       { color = "#a88", value = minus1 },
   302                       { color = "#a00", value = minus2 },
   303                     }
   304                   }
   305                   slot.put(" | ")
   306                   ui.tag { content = _"implemented:" }
   307                   slot.put ( " " )
   308                   ui.bargraph{
   309                     max_value = with_opinion,
   310                     width = 100,
   311                     bars = {
   312                       { color = "#0a0", value = suggestion.plus2_fulfilled_count },
   313                       { color = "#8a8", value = suggestion.plus1_fulfilled_count },
   314                       { color = "#eee", value = neutral2 },
   315                       { color = "#a88", value = suggestion.minus1_fulfilled_count },
   316                       { color = "#a00", value = suggestion.minus2_fulfilled_count },
   317                     }
   318                   }
   319                 end }
   320               end
   322               if app.session:has_access("authors_pseudonymous") then
   323                 util.micro_avatar ( suggestion.author )
   324               else
   325                 slot.put("<br />")
   326               end
   328               ui.container {
   329                 attr = { class = "suggestion-text" },
   330                 content = function ()
   331                   slot.put ( suggestion:get_content( "html" ) )
   334               if direct_supporter then
   336                 ui.container {
   337                   attr = { class = "rating" },
   338                   content = function ()
   340                     if not opinion then
   341                       opinion = {}
   342                     end
   343                     ui.form { 
   344                       module = "opinion", action = "update", params = {
   345                         suggestion_id = suggestion.id
   346                       },
   347                       routing = { default = {
   348                         mode = "redirect", 
   349                         module = "initiative", view = "show", id = suggestion.initiative_id,
   350                         params = { suggestion_id = suggestion.id },
   351                         anchor = "s" .. suggestion.id -- TODO webmcp
   352                       } },
   353                       content = function ()
   356                         ui.heading { level = 3, content = _"Should the initiator implement this suggestion?" }
   357                         ui.container { content = function ()
   359                           local active = opinion.degree == 2
   360                           ui.tag { tag = "input", attr = {
   361                             type = "radio", name = "degree", value = 2, 
   362                             id = "s" .. suggestion.id .. "_degree2",
   363                             checked = active and "checked" or nil
   364                           } }
   365                           ui.tag { 
   366                             tag = "label", 
   367                             attr = {
   368                               ["for"] = "s" .. suggestion.id .. "_degree2",
   369                               class = active and "active-plus2" or nil,
   370                             },
   371                             content = _"must"
   372                           }
   374                           local active = opinion.degree == 1
   375                           ui.tag { tag = "input", attr = {
   376                             type = "radio", name = "degree", value = 1,
   377                             id = "s" .. suggestion.id .. "_degree1",
   378                             checked = active and "checked" or nil
   379                           } }
   380                           ui.tag { 
   381                             tag = "label", 
   382                             attr = {
   383                               ["for"] = "s" .. suggestion.id .. "_degree1",
   384                               class = active and "active-plus1" or nil,
   385                             },
   386                             content = _"should"
   387                           }
   389                           local active = not opinion.member_id
   390                           ui.tag { tag = "input", attr = {
   391                             type = "radio", name = "degree", value = 0,
   392                             id = "s" .. suggestion.id .. "_degree0",
   393                             checked = active and "checked" or nil
   394                           } }
   395                           ui.tag { 
   396                             tag = "label", 
   397                             attr = {
   398                               ["for"] = "s" .. suggestion.id .. "_degree0",
   399                               class = active and "active-neutral" or nil,
   400                             },
   401                             content = _"neutral"
   402                           }
   404                           local active = opinion.degree == -1
   405                           ui.tag { tag = "input", attr = {
   406                             type = "radio", name = "degree", value = -1,
   407                             id = "s" .. suggestion.id .. "_degree-1",
   408                             checked = active and "checked" or nil
   409                           } }
   410                           ui.tag { 
   411                             tag = "label", 
   412                             attr = {
   413                               ["for"] = "s" .. suggestion.id .. "_degree-1",
   414                               class = active and "active-minus1" or nil,
   415                             },
   416                             content = _"should not"
   417                           }
   419                           local active = opinion.degree == -2
   420                           ui.tag { tag = "input", attr = {
   421                             type = "radio", name = "degree", value = -2,
   422                             id = "s" .. suggestion.id .. "_degree-2",
   423                             checked = active and "checked" or nil
   424                           } }
   425                           ui.tag { 
   426                             tag = "label", 
   427                             attr = {
   428                               ["for"] = "s" .. suggestion.id .. "_degree-2",
   429                               class = active and "active-minus2" or nil,
   430                             },
   431                             content = _"must not"
   432                           }
   433                         end }
   435                         slot.put("<br />")
   437                         ui.heading { level = 3, content = _"Did the initiator implement this suggestion?" }
   438                         ui.container { content = function ()
   439                           local active = opinion.fulfilled == false
   440                           ui.tag { tag = "input", attr = {
   441                             type = "radio", name = "fulfilled", value = "false",
   442                             id = "s" .. suggestion.id .. "_notfulfilled",
   443                             checked = active and "checked" or nil
   444                           } }
   445                           ui.tag { 
   446                             tag = "label", 
   447                             attr = {
   448                               ["for"] = "s" .. suggestion.id .. "_notfulfilled",
   449                               class = active and "active-notfulfilled" or nil,
   450                             },
   451                             content = _"No (not yet)"
   452                           }
   454                           local active = opinion.fulfilled
   455                           ui.tag { tag = "input", attr = {
   456                             type = "radio", name = "fulfilled", value = "true",
   457                             id = "s" .. suggestion.id .. "_fulfilled",
   458                             checked = active and "checked" or nil
   459                           } }
   460                           ui.tag { 
   461                             tag = "label", 
   462                             attr = {
   463                               ["for"] = "s" .. suggestion.id .. "_fulfilled",
   464                               class = active and "active-fulfilled" or nil,
   465                             },
   466                             content = _"Yes, it's implemented"
   467                           }
   468                         end }
   469                         slot.put("<br />")
   471                         ui.tag{
   472                           tag = "input",
   473                           attr = {
   474                             type = "submit",
   475                             class = "btn btn-default",
   476                             value = _"publish my rating"
   477                           },
   478                           content = ""
   479                         }
   481                       end 
   482                     }
   484                   end -- if not issue,fully_frozen or closed
   485                 }
   486               end 
   488                 local text = _"Read more"
   490                 if direct_supporter then
   491                   text = _"Show more and rate this"
   492                 end
   494                 ui.link{
   495                   attr = { class = "suggestion-details" },
   496                   content = _"Details",
   497                   module = "suggestion", view = "show", id = suggestion.id
   498                 }
   500                 ui.link { 
   501                   attr = { 
   502                     class = "suggestion-more",
   503                     onclick = "$('#s" .. suggestion.id .. "').removeClass('folded').addClass('unfolded'); return false;"
   504                   },
   505                   text = text
   506                 }
   508                 ui.link { 
   509                   attr = { 
   510                     class = "suggestion-less",
   511                     onclick = "$('#s" .. suggestion.id .. "').addClass('folded').removeClass('unfolded'); return false;"
   512                   },
   513                   text = _"Show less"
   514                 }
   515                 end
   516               }
   518               ui.script{ script = [[
   519                 var textEl = $('#s]] .. suggestion.id .. [[ .suggestion-text');
   520                 var height = textEl.height();
   521                 if (height > 150) $('#s]] .. suggestion.id .. [[').addClass('folded');
   522               ]] }
   524             end
   525           } -- ui.paragraph
   529         end } -- ui.tag "li"
   531       end -- for i, suggestion
   533     else -- if #initiative.suggestions > 0
   535       local text
   536       if initiative.issue.closed then
   537         text = "No suggestions"
   538       else
   539         text = "No suggestions (yet)"
   540       end
   541       ui.sectionHead( function()
   542         ui.heading { level = 1, content = text }
   543       end)
   545     end -- if #initiative.suggestions > 0
   547   end
   548 }
