| rev | 
   line source | 
| 
bsw@1045
 | 
     1 local issue = param.get("issue", "table")
 | 
| 
bsw@1045
 | 
     2 local initiative = param.get("initiative", "table")
 | 
| 
bsw@1045
 | 
     3 
 | 
| 
bsw@1045
 | 
     4 local view_module
 | 
| 
bsw@1045
 | 
     5 local view_id
 | 
| 
bsw@1045
 | 
     6 
 | 
| 
bsw@1045
 | 
     7 if initiative then
 | 
| 
bsw@1045
 | 
     8   issue = initiative.issue
 | 
| 
bsw@1045
 | 
     9   view_module = "initiative"
 | 
| 
bsw@1045
 | 
    10   view_id = initiative.id
 | 
| 
bsw@1045
 | 
    11 else
 | 
| 
bsw@1045
 | 
    12   view_module = "issue"
 | 
| 
bsw@1045
 | 
    13   view_id = issue.id
 | 
| 
bsw@1045
 | 
    14 end
 | 
| 
bsw@1045
 | 
    15 
 | 
| 
bsw/jbe@1309
 | 
    16 local current_occured = false
 | 
| 
bsw/jbe@1309
 | 
    17 local failed = false
 | 
| 
bsw/jbe@1309
 | 
    18 
 | 
| 
bsw/jbe@1309
 | 
    19 ui.tag{ tag = "table", content = function()
 | 
| 
bsw@1045
 | 
    20 
 | 
| 
bsw/jbe@1309
 | 
    21 local function quorum_text(policy, quorum)
 | 
| 
bsw/jbe@1309
 | 
    22   local num
 | 
| 
bsw/jbe@1309
 | 
    23   local den
 | 
| 
bsw@1481
 | 
    24 
 | 
| 
bsw/jbe@1309
 | 
    25   if quorum == 1 then
 | 
| 
bsw/jbe@1309
 | 
    26     return math.max(policy.issue_quorum or 0, issue.issue_quorum or 0)
 | 
| 
bsw/jbe@1309
 | 
    27   elseif quorum == 2 then
 | 
| 
bsw/jbe@1309
 | 
    28     num = policy.initiative_quorum_num
 | 
| 
bsw/jbe@1309
 | 
    29     den = policy.initiative_quorum_den
 | 
| 
bsw/jbe@1309
 | 
    30   end
 | 
| 
bsw@1481
 | 
    31 
 | 
| 
bsw@1481
 | 
    32   local quorums = {}
 | 
| 
bsw@1481
 | 
    33 
 | 
| 
bsw@1481
 | 
    34   if num and num > 0 and den == 100 or den == 10 then
 | 
| 
bsw@1481
 | 
    35     table.insert(quorums, _("#{percentage}%", { percentage = num * 100 / den }))
 | 
| 
bsw@1481
 | 
    36   elseif num and num > 0 and den and den > 0 then
 | 
| 
bsw@1481
 | 
    37     table.insert(quorums, num .. "/" .. den)
 | 
| 
bsw/jbe@1309
 | 
    38   end
 | 
| 
bsw@1481
 | 
    39 
 | 
| 
bsw@1481
 | 
    40   if policy.initiative_quorum then
 | 
| 
bsw@1481
 | 
    41     table.insert(quorums, policy.initiative_quorum)
 | 
| 
bsw/jbe@1309
 | 
    42   end
 | 
| 
bsw@1481
 | 
    43 
 | 
| 
bsw@1481
 | 
    44   return table.concat(quorums, " / ")
 | 
| 
bsw/jbe@1309
 | 
    45 end
 | 
| 
bsw@1045
 | 
    46 
 | 
| 
bsw/jbe@1309
 | 
    47 local phases = { "admission", "discussion", "verification", "voting" }
 | 
| 
bsw/jbe@1309
 | 
    48 
 | 
| 
bsw/jbe@1309
 | 
    49 for i, state in ipairs(phases) do
 | 
| 
bsw/jbe@1309
 | 
    50   local current = state == issue.state
 | 
| 
bsw/jbe@1309
 | 
    51   
 | 
| 
bsw/jbe@1309
 | 
    52   if current then
 | 
| 
bsw/jbe@1309
 | 
    53     current_occured = true
 | 
| 
bsw/jbe@1309
 | 
    54   end
 | 
| 
bsw@1045
 | 
    55   
 | 
| 
bsw/jbe@1309
 | 
    56   local phase_success = (
 | 
| 
bsw/jbe@1309
 | 
    57     (state == "admission" and issue.accepted)
 | 
| 
bsw/jbe@1309
 | 
    58       or (state == "discussion" and issue.half_frozen)
 | 
| 
bsw/jbe@1309
 | 
    59       or (state == "verification" and issue.fully_frozen and issue.state ~= "canceled_no_initiative_admitted")
 | 
| 
bsw/jbe@1309
 | 
    60       or (state == "voting" and issue.closed and issue.state ~= "canceled_no_initiative_admitted" and issue.state ~= "canceled_by_admin")
 | 
| 
bsw/jbe@1309
 | 
    61   )
 | 
| 
bsw/jbe@1309
 | 
    62   
 | 
| 
bsw/jbe@1309
 | 
    63   if not failed then
 | 
| 
bsw/jbe@1309
 | 
    64     ui.container{ tag = "div", attr = { id = "phase-" .. state, class = current and "phase-current" or nil }, content = function()
 | 
| 
bsw@1045
 | 
    65     
 | 
| 
bsw/jbe@1309
 | 
    66       local state_names = {
 | 
| 
bsw/jbe@1309
 | 
    67         admission = _"Admission",
 | 
| 
bsw/jbe@1309
 | 
    68         discussion = _"Discussion",
 | 
| 
bsw/jbe@1309
 | 
    69         verification = _"Verification",
 | 
| 
bsw/jbe@1309
 | 
    70         voting = _"Voting"
 | 
| 
bsw/jbe@1309
 | 
    71       }
 | 
| 
bsw@1045
 | 
    72       
 | 
| 
bsw/jbe@1309
 | 
    73       local state_name = state_names[state] or state
 | 
| 
bsw/jbe@1309
 | 
    74       
 | 
| 
bsw/jbe@1309
 | 
    75       local quorum
 | 
| 
bsw/jbe@1309
 | 
    76       if state == "admission" then
 | 
| 
bsw/jbe@1309
 | 
    77         quorum = quorum_text(issue.policy, 1)
 | 
| 
bsw/jbe@1309
 | 
    78       elseif state == "verification" then
 | 
| 
bsw/jbe@1309
 | 
    79         quorum = quorum_text(issue.policy, 2)
 | 
| 
bsw/jbe@1309
 | 
    80       end
 | 
| 
bsw/jbe@1309
 | 
    81       
 | 
| 
bsw/jbe@1309
 | 
    82       local time_text
 | 
| 
bsw/jbe@1309
 | 
    83       if current then
 | 
| 
bsw/jbe@1309
 | 
    84         local time_left
 | 
| 
bsw/jbe@1309
 | 
    85         if issue.state_time_left:sub(1,1) ~= "-" then
 | 
| 
bsw/jbe@1309
 | 
    86           time_text = format.interval_text(issue.state_time_left, { mode = "time_left" })
 | 
| 
bsw/jbe@1309
 | 
    87         else
 | 
| 
bsw/jbe@1309
 | 
    88           time_text = "phase ends soon"
 | 
| 
bsw/jbe@1309
 | 
    89         end
 | 
| 
bsw/jbe@1309
 | 
    90       elseif current_occured then
 | 
| 
bsw/jbe@1309
 | 
    91         local phase_duration = issue[state .. "_time_text"]
 | 
| 
bsw/jbe@1309
 | 
    92         time_text = _("#{duration}", { duration = format.interval_text(phase_duration) } )
 | 
| 
bsw/jbe@1309
 | 
    93       else
 | 
| 
bsw/jbe@1309
 | 
    94         local text = "failed"
 | 
| 
bsw/jbe@1309
 | 
    95         if quorum then
 | 
| 
bsw/jbe@1309
 | 
    96           text = _("failed #{quorum}", { quorum = quorum })
 | 
| 
bsw/jbe@1309
 | 
    97         end
 | 
| 
bsw/jbe@1309
 | 
    98         if phase_success then
 | 
| 
bsw/jbe@1309
 | 
    99           if quorum == 0 then
 | 
| 
bsw/jbe@1309
 | 
   100             text = _"without quorum"
 | 
| 
bsw/jbe@1309
 | 
   101           elseif quorum then
 | 
| 
bsw/jbe@1309
 | 
   102             text = _("reached #{quorum}", { quorum = quorum })
 | 
| 
bsw/jbe@1309
 | 
   103           else
 | 
| 
bsw/jbe@1309
 | 
   104             text = _"finished"
 | 
| 
bsw/jbe@1309
 | 
   105           end
 | 
| 
bsw/jbe@1309
 | 
   106         elseif issue.state == "canceled_revoked_before_accepted" or
 | 
| 
bsw/jbe@1309
 | 
   107             issue.state == "canceled_after_revocation_during_discussion" or
 | 
| 
bsw/jbe@1309
 | 
   108             issue.state == "canceled_after_revocation_during_verification"
 | 
| 
bsw/jbe@1309
 | 
   109         then
 | 
| 
bsw/jbe@1309
 | 
   110           text = _"revoked"
 | 
| 
bsw/jbe@1309
 | 
   111         elseif issue.state == "canceled_by_admin" then
 | 
| 
bsw/jbe@1309
 | 
   112           text = _"canceled"
 | 
| 
bsw/jbe@1309
 | 
   113         end
 | 
| 
bsw/jbe@1309
 | 
   114         time_text = text
 | 
| 
bsw/jbe@1309
 | 
   115       end
 | 
| 
bsw@1045
 | 
   116 
 | 
| 
bsw/jbe@1309
 | 
   117       if not config.voting_only or state == "voting" then
 | 
| 
bsw/jbe@1309
 | 
   118         if current then
 | 
| 
bsw/jbe@1309
 | 
   119           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "play_arrow" }
 | 
| 
bsw/jbe@1309
 | 
   120         elseif not current_occured and not phase_success then
 | 
| 
bsw/jbe@1309
 | 
   121           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "clear" }
 | 
| 
bsw/jbe@1309
 | 
   122         elseif current_occured and issue.accepted then
 | 
| 
bsw/jbe@1309
 | 
   123           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "schedule" }
 | 
| 
bsw/jbe@1309
 | 
   124         elseif current_occured then
 | 
| 
bsw/jbe@1309
 | 
   125           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "lock" }
 | 
| 
bsw/jbe@1309
 | 
   126         else
 | 
| 
bsw/jbe@1309
 | 
   127           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "check" }
 | 
| 
bsw@1045
 | 
   128         end
 | 
| 
bsw@1045
 | 
   129 
 | 
| 
bsw/jbe@1309
 | 
   130         if not config.voting_only then
 | 
| 
bsw/jbe@1309
 | 
   131           slot.put(" ")
 | 
| 
bsw@1045
 | 
   132         end
 | 
| 
bsw@1045
 | 
   133 
 | 
| 
bsw/jbe@1309
 | 
   134         ui.tag{ attr = { class = "mdl-data-table__cell--non-numeric" }, content = function()
 | 
| 
bsw/jbe@1309
 | 
   135           if not config.voting_only then
 | 
| 
bsw/jbe@1309
 | 
   136             ui.tag{ content = i .. "." }
 | 
| 
bsw@1045
 | 
   137           end
 | 
| 
bsw@1045
 | 
   138           slot.put(" ")
 | 
| 
bsw/jbe@1309
 | 
   139           ui.tag{ content = state_name  }
 | 
| 
bsw/jbe@1309
 | 
   140         end}
 | 
| 
bsw/jbe@1309
 | 
   141         ui.tag{ content = " (" .. time_text .. ")"}
 | 
| 
bsw/jbe@1309
 | 
   142       
 | 
| 
bsw/jbe@1309
 | 
   143         slot.put(" ")
 | 
| 
bsw/jbe@1309
 | 
   144           
 | 
| 
bsw/jbe@1309
 | 
   145         if not current then
 | 
| 
bsw/jbe@1309
 | 
   146           ui.tag{ tag = "i", attr = { onclick = "document.getElementById('phase-info-" .. i .. "').classList.toggle('hidden');", class = "material-icons material-icons-small clickable" }, content = "info_outline" }
 | 
| 
bsw/jbe@1309
 | 
   147         end
 | 
| 
bsw/jbe@1309
 | 
   148       end
 | 
| 
bsw/jbe@1309
 | 
   149       
 | 
| 
bsw/jbe@1309
 | 
   150     end }
 | 
| 
bsw/jbe@1309
 | 
   151     
 | 
| 
bsw/jbe@1309
 | 
   152     local help_texts = {
 | 
| 
bsw/jbe@1309
 | 
   153       admission = _("As soon as one initiative of this issue reaches the 1st quorum of #{quorum} support, the issue will proceed to discussion phase.", { quorum = quorum_text(issue.policy, 1) }),
 | 
| 
bsw/jbe@1309
 | 
   154       discussion = _"During the discussion phase, the issue is debated on while the initiators improve the proposals and reasons in their initiatives. Supporters of initiatives can write and rate suggestions for improvement.",
 | 
| 
bsw/jbe@1309
 | 
   155       verification = _("During the verification phase, existing initiatives cannot be changed anymore. Initiatives need to pass the 2nd quorum of #{quorum} at end of verification phase to become admitted for voting.", { quorum = quorum_text(issue.policy, 2) }),
 | 
| 
bsw/jbe@1309
 | 
   156       voting = _"During the voting phase, votes for all admitted initiatives in this issue can be cast. The final result will be calculated as soon as this phase ends."
 | 
| 
bsw/jbe@1309
 | 
   157     }
 | 
| 
bsw/jbe@1309
 | 
   158     
 | 
| 
bsw/jbe@1309
 | 
   159     local class = "phase-info"
 | 
| 
bsw/jbe@1309
 | 
   160     if not current then
 | 
| 
bsw/jbe@1309
 | 
   161       class = class .. " hidden"
 | 
| 
bsw/jbe@1309
 | 
   162     end
 | 
| 
bsw@1060
 | 
   163 
 | 
| 
bsw/jbe@1309
 | 
   164     if not config.voting_only then
 | 
| 
bsw/jbe@1309
 | 
   165       ui.container { attr = { id = "phase-info-" .. i, class = class }, content = help_texts[state] }
 | 
| 
bsw@1045
 | 
   166     end
 | 
| 
bsw@1045
 | 
   167     
 | 
| 
bsw/jbe@1309
 | 
   168   end
 | 
| 
bsw/jbe@1309
 | 
   169   
 | 
| 
bsw/jbe@1309
 | 
   170   if not phase_success and not current and not current_occured then
 | 
| 
bsw/jbe@1309
 | 
   171     failed = true
 | 
| 
bsw@1045
 | 
   172   end
 | 
| 
bsw/jbe@1309
 | 
   173 end
 | 
| 
bsw/jbe@1309
 | 
   174 
 | 
| 
bsw/jbe@1309
 | 
   175 end }
 | 
| 
bsw/jbe@1309
 | 
   176 
 | 
| 
bsw/jbe@1309
 | 
   177 if issue.closed then
 | 
| 
bsw/jbe@1309
 | 
   178   ui.tag{ content = issue.state_name }
 | 
| 
bsw/jbe@1309
 | 
   179 end
 |