| 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/jbe@1309
 | 
    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/jbe@1309
 | 
    31   
 | 
| 
bsw/jbe@1309
 | 
    32   if num == nil or den == nil then
 | 
| 
bsw/jbe@1309
 | 
    33     return 0
 | 
| 
bsw/jbe@1309
 | 
    34   end
 | 
| 
bsw/jbe@1309
 | 
    35   
 | 
| 
bsw/jbe@1309
 | 
    36   if den == 100 or den == 10 then
 | 
| 
bsw/jbe@1309
 | 
    37     return _("#{percentage}%", { percentage = num * 100 / den })
 | 
| 
bsw/jbe@1309
 | 
    38   else
 | 
| 
bsw/jbe@1309
 | 
    39     return num .. "/" .. den
 | 
| 
bsw/jbe@1309
 | 
    40   end
 | 
| 
bsw/jbe@1309
 | 
    41   
 | 
| 
bsw/jbe@1309
 | 
    42 end
 | 
| 
bsw@1045
 | 
    43 
 | 
| 
bsw/jbe@1309
 | 
    44 local phases = { "admission", "discussion", "verification", "voting" }
 | 
| 
bsw/jbe@1309
 | 
    45 
 | 
| 
bsw/jbe@1309
 | 
    46 for i, state in ipairs(phases) do
 | 
| 
bsw/jbe@1309
 | 
    47   local current = state == issue.state
 | 
| 
bsw/jbe@1309
 | 
    48   
 | 
| 
bsw/jbe@1309
 | 
    49   if current then
 | 
| 
bsw/jbe@1309
 | 
    50     current_occured = true
 | 
| 
bsw/jbe@1309
 | 
    51   end
 | 
| 
bsw@1045
 | 
    52   
 | 
| 
bsw/jbe@1309
 | 
    53   local phase_success = (
 | 
| 
bsw/jbe@1309
 | 
    54     (state == "admission" and issue.accepted)
 | 
| 
bsw/jbe@1309
 | 
    55       or (state == "discussion" and issue.half_frozen)
 | 
| 
bsw/jbe@1309
 | 
    56       or (state == "verification" and issue.fully_frozen and issue.state ~= "canceled_no_initiative_admitted")
 | 
| 
bsw/jbe@1309
 | 
    57       or (state == "voting" and issue.closed and issue.state ~= "canceled_no_initiative_admitted" and issue.state ~= "canceled_by_admin")
 | 
| 
bsw/jbe@1309
 | 
    58   )
 | 
| 
bsw/jbe@1309
 | 
    59   
 | 
| 
bsw/jbe@1309
 | 
    60   if not failed then
 | 
| 
bsw/jbe@1309
 | 
    61     ui.container{ tag = "div", attr = { id = "phase-" .. state, class = current and "phase-current" or nil }, content = function()
 | 
| 
bsw@1045
 | 
    62     
 | 
| 
bsw/jbe@1309
 | 
    63       local state_names = {
 | 
| 
bsw/jbe@1309
 | 
    64         admission = _"Admission",
 | 
| 
bsw/jbe@1309
 | 
    65         discussion = _"Discussion",
 | 
| 
bsw/jbe@1309
 | 
    66         verification = _"Verification",
 | 
| 
bsw/jbe@1309
 | 
    67         voting = _"Voting"
 | 
| 
bsw/jbe@1309
 | 
    68       }
 | 
| 
bsw@1045
 | 
    69       
 | 
| 
bsw/jbe@1309
 | 
    70       local state_name = state_names[state] or state
 | 
| 
bsw/jbe@1309
 | 
    71       
 | 
| 
bsw/jbe@1309
 | 
    72       local quorum
 | 
| 
bsw/jbe@1309
 | 
    73       if state == "admission" then
 | 
| 
bsw/jbe@1309
 | 
    74         quorum = quorum_text(issue.policy, 1)
 | 
| 
bsw/jbe@1309
 | 
    75       elseif state == "verification" then
 | 
| 
bsw/jbe@1309
 | 
    76         quorum = quorum_text(issue.policy, 2)
 | 
| 
bsw/jbe@1309
 | 
    77       end
 | 
| 
bsw/jbe@1309
 | 
    78       
 | 
| 
bsw/jbe@1309
 | 
    79       local time_text
 | 
| 
bsw/jbe@1309
 | 
    80       if current then
 | 
| 
bsw/jbe@1309
 | 
    81         local time_left
 | 
| 
bsw/jbe@1309
 | 
    82         if issue.state_time_left:sub(1,1) ~= "-" then
 | 
| 
bsw/jbe@1309
 | 
    83           time_text = format.interval_text(issue.state_time_left, { mode = "time_left" })
 | 
| 
bsw/jbe@1309
 | 
    84         else
 | 
| 
bsw/jbe@1309
 | 
    85           time_text = "phase ends soon"
 | 
| 
bsw/jbe@1309
 | 
    86         end
 | 
| 
bsw/jbe@1309
 | 
    87       elseif current_occured then
 | 
| 
bsw/jbe@1309
 | 
    88         local phase_duration = issue[state .. "_time_text"]
 | 
| 
bsw/jbe@1309
 | 
    89         time_text = _("#{duration}", { duration = format.interval_text(phase_duration) } )
 | 
| 
bsw/jbe@1309
 | 
    90       else
 | 
| 
bsw/jbe@1309
 | 
    91         local text = "failed"
 | 
| 
bsw/jbe@1309
 | 
    92         if quorum then
 | 
| 
bsw/jbe@1309
 | 
    93           text = _("failed #{quorum}", { quorum = quorum })
 | 
| 
bsw/jbe@1309
 | 
    94         end
 | 
| 
bsw/jbe@1309
 | 
    95         if phase_success then
 | 
| 
bsw/jbe@1309
 | 
    96           if quorum == 0 then
 | 
| 
bsw/jbe@1309
 | 
    97             text = _"without quorum"
 | 
| 
bsw/jbe@1309
 | 
    98           elseif quorum then
 | 
| 
bsw/jbe@1309
 | 
    99             text = _("reached #{quorum}", { quorum = quorum })
 | 
| 
bsw/jbe@1309
 | 
   100           else
 | 
| 
bsw/jbe@1309
 | 
   101             text = _"finished"
 | 
| 
bsw/jbe@1309
 | 
   102           end
 | 
| 
bsw/jbe@1309
 | 
   103         elseif issue.state == "canceled_revoked_before_accepted" or
 | 
| 
bsw/jbe@1309
 | 
   104             issue.state == "canceled_after_revocation_during_discussion" or
 | 
| 
bsw/jbe@1309
 | 
   105             issue.state == "canceled_after_revocation_during_verification"
 | 
| 
bsw/jbe@1309
 | 
   106         then
 | 
| 
bsw/jbe@1309
 | 
   107           text = _"revoked"
 | 
| 
bsw/jbe@1309
 | 
   108         elseif issue.state == "canceled_by_admin" then
 | 
| 
bsw/jbe@1309
 | 
   109           text = _"canceled"
 | 
| 
bsw/jbe@1309
 | 
   110         end
 | 
| 
bsw/jbe@1309
 | 
   111         time_text = text
 | 
| 
bsw/jbe@1309
 | 
   112       end
 | 
| 
bsw@1045
 | 
   113 
 | 
| 
bsw/jbe@1309
 | 
   114       if not config.voting_only or state == "voting" then
 | 
| 
bsw/jbe@1309
 | 
   115         if current then
 | 
| 
bsw/jbe@1309
 | 
   116           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "play_arrow" }
 | 
| 
bsw/jbe@1309
 | 
   117         elseif not current_occured and not phase_success then
 | 
| 
bsw/jbe@1309
 | 
   118           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "clear" }
 | 
| 
bsw/jbe@1309
 | 
   119         elseif current_occured and issue.accepted then
 | 
| 
bsw/jbe@1309
 | 
   120           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "schedule" }
 | 
| 
bsw/jbe@1309
 | 
   121         elseif current_occured then
 | 
| 
bsw/jbe@1309
 | 
   122           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "lock" }
 | 
| 
bsw/jbe@1309
 | 
   123         else
 | 
| 
bsw/jbe@1309
 | 
   124           ui.tag{ tag = "i", attr = { class = "material-icons" }, content = "check" }
 | 
| 
bsw@1045
 | 
   125         end
 | 
| 
bsw@1045
 | 
   126 
 | 
| 
bsw/jbe@1309
 | 
   127         if not config.voting_only then
 | 
| 
bsw/jbe@1309
 | 
   128           slot.put(" ")
 | 
| 
bsw@1045
 | 
   129         end
 | 
| 
bsw@1045
 | 
   130 
 | 
| 
bsw/jbe@1309
 | 
   131         ui.tag{ attr = { class = "mdl-data-table__cell--non-numeric" }, content = function()
 | 
| 
bsw/jbe@1309
 | 
   132           if not config.voting_only then
 | 
| 
bsw/jbe@1309
 | 
   133             ui.tag{ content = i .. "." }
 | 
| 
bsw@1045
 | 
   134           end
 | 
| 
bsw@1045
 | 
   135           slot.put(" ")
 | 
| 
bsw/jbe@1309
 | 
   136           ui.tag{ content = state_name  }
 | 
| 
bsw/jbe@1309
 | 
   137         end}
 | 
| 
bsw/jbe@1309
 | 
   138         ui.tag{ content = " (" .. time_text .. ")"}
 | 
| 
bsw/jbe@1309
 | 
   139       
 | 
| 
bsw/jbe@1309
 | 
   140         slot.put(" ")
 | 
| 
bsw/jbe@1309
 | 
   141           
 | 
| 
bsw/jbe@1309
 | 
   142         if not current then
 | 
| 
bsw/jbe@1309
 | 
   143           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
 | 
   144         end
 | 
| 
bsw/jbe@1309
 | 
   145       end
 | 
| 
bsw/jbe@1309
 | 
   146       
 | 
| 
bsw/jbe@1309
 | 
   147     end }
 | 
| 
bsw/jbe@1309
 | 
   148     
 | 
| 
bsw/jbe@1309
 | 
   149     local help_texts = {
 | 
| 
bsw/jbe@1309
 | 
   150       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
 | 
   151       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
 | 
   152       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
 | 
   153       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
 | 
   154     }
 | 
| 
bsw/jbe@1309
 | 
   155     
 | 
| 
bsw/jbe@1309
 | 
   156     local class = "phase-info"
 | 
| 
bsw/jbe@1309
 | 
   157     if not current then
 | 
| 
bsw/jbe@1309
 | 
   158       class = class .. " hidden"
 | 
| 
bsw/jbe@1309
 | 
   159     end
 | 
| 
bsw@1060
 | 
   160 
 | 
| 
bsw/jbe@1309
 | 
   161     if not config.voting_only then
 | 
| 
bsw/jbe@1309
 | 
   162       ui.container { attr = { id = "phase-info-" .. i, class = class }, content = help_texts[state] }
 | 
| 
bsw@1045
 | 
   163     end
 | 
| 
bsw@1045
 | 
   164     
 | 
| 
bsw/jbe@1309
 | 
   165   end
 | 
| 
bsw/jbe@1309
 | 
   166   
 | 
| 
bsw/jbe@1309
 | 
   167   if not phase_success and not current and not current_occured then
 | 
| 
bsw/jbe@1309
 | 
   168     failed = true
 | 
| 
bsw@1045
 | 
   169   end
 | 
| 
bsw/jbe@1309
 | 
   170 end
 | 
| 
bsw/jbe@1309
 | 
   171 
 | 
| 
bsw/jbe@1309
 | 
   172 end }
 | 
| 
bsw/jbe@1309
 | 
   173 
 | 
| 
bsw/jbe@1309
 | 
   174 if issue.closed then
 | 
| 
bsw/jbe@1309
 | 
   175   ui.tag{ content = issue.state_name }
 | 
| 
bsw/jbe@1309
 | 
   176 end
 |